/******************************************************************************
 ** $Id: Kategorie.java 1647 2019-01-12 12:34:18Z wmh $
 ** Diese Datei ist Bestandteil der Java-Quelltexte des Würfelspiels JaFuffy.
 ******************************************************************************
 ** Copyright (C) Wolfgang Hauck <wolfgang.hauck@3kelvin.de>
 ******************************************************************************
 ** This program is free software: you can redistribute it and/or modify
 ** it under the terms of the GNU General Public License as published by
 ** the Free Software Foundation, either version 3 of the License, or
 ** (at your option) any later version.
 **
 ** This program is distributed in the hope that it will be useful,
 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 ** GNU General Public License for more details.
 **
 ** You should have received a copy of the GNU General Public License
 ** along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************
 ** Die aktuellste Version von JaFuffy findet sich im Internet unter
 ** <http://jafuffy.3kelvin.de>.
 **
 ** Kommentare, Fehler oder Erweiterungswünsche bitte per E-Mail senden an
 ** <jafuffy@3kelvin.de>.
 ******************************************************************************/
package jafuffy.logik;

/** Zeilenarten der Tabelle (Einträge, Kategorien). */
public enum Kategorie {

    /** Augenzahl Eins wird gezählt. */
    EINS("1er", "Nur Einser zählen", Art.OBEN),
    /** Augenzahl Zwei wird gezählt. */
    ZWEI("2er", "Nur Zweier zählen", Art.OBEN),
    /** Augenzahl Drei wird gezählt. */
    DREI("3er", "Nur Dreier zählen", Art.OBEN),
    /** Augenzahl Vier wird gezählt. */
    VIER("4er", "Nur Vierer zählen", Art.OBEN),
    /** Augenzahl Fünf wird gezählt. */
    FUENF("5er", "Nur Fünfer zählen", Art.OBEN),
    /** Augenzahl Sechs wird gezählt. */
    SECHS("6er", "Nur Sechser zählen", Art.OBEN),
    /** Die Gesamtpunktzahl der oberen Einträge, bei denen je eine Augenzahl zum Ergebnis beiträgt. */
    GESAMT("Gesamt", "Summe der oberen Einträge"),
    /** Bonus, falls Gesamtpunktzahl der oberen Einträge 63 überschreitet. */
    BONUS("Bonus ab 63", "Ab 63 Punkten oben zusätzlich 35 Bonuspunkte"),
    /** Gesamtpunktzahl der oberen Einträge einschließlich Bonus. */
    OSUMME("Obere Summe", "Summe der oberen Einträge plus Bonuspunkte"),
    /** Dreierpasch. */
    DREIERPASCH("Dreierpasch", "Alle Augen zählen", Art.UNTEN),
    /** Viererpasch. */
    VIERERPASCH("Viererpasch", "Alle Augen zählen", Art.UNTEN),
    /** Full-House. */
    FULLHOUSE("Full-House", "25 Punkte", Art.UNTEN),
    /** Kleine Straße. */
    KLEINESTRASSE("Kleine Straße", "30 Punkte", Art.UNTEN),
    /** Große Straße. */
    GROSSESTRASSE("Große Straße", "40 Punkte", Art.UNTEN),
    /** JaFuffy (fünf mal gleiche Augenzahl). */
    JAFUFFY("JaFuffy", "50 Punkte", Art.UNTEN),
    /** Chance (Summe aller Augen). */
    CHANCE("Chance", "Alle Augen zählen", Art.UNTEN),
    /** Summe der unteren Einträge. */
    USUMME("Untere Summe", "Summe der unteren Einträge"),
    /** Endsumme. */
    ESUMME("Endsumme", "Obere und untere Summe zusammen");

    /** Art des Tabelleneintrages. */
    private enum Art {
        /** Der Eintrag ist nicht setzbar und enthält abgeleitete Ergebnisse. */
        DERIVAT,
        /** Der Eintrag ist setzbar und befindet sich im oberen Tabellenteil. */
        OBEN,
        /** Der Eintrag ist setzbar und befindet sich im unteren Tabellenteil. */
        UNTEN;
    }

    /** Alle Einträge, für die ein Wurf gesetzt werden kann. */
    public static final Kategorie[] ALLE = {
        EINS,
        ZWEI,
        DREI,
        VIER,
        FUENF,
        SECHS,
        DREIERPASCH,
        VIERERPASCH,
        FULLHOUSE,
        KLEINESTRASSE,
        GROSSESTRASSE,
        JAFUFFY,
        CHANCE };
    /** Die Anzahl aller Tabelleneinträge. */
    public static final int ANZAHL = values().length;
    /** Alle oberen Einträge. */
    public static final Kategorie[] OBEN = { EINS, ZWEI, DREI, VIER, FUENF, SECHS };
    /** Alle unteren Einträge. */
    public static final Kategorie[] UNTEN = {
        DREIERPASCH,
        VIERERPASCH,
        FULLHOUSE,
        KLEINESTRASSE,
        GROSSESTRASSE,
        JAFUFFY,
        CHANCE };

    /**
     * Wandelt Nummerierung in Wert um.
     *
     * @param nummer
     *            Nummer des Aufzählungswertes.
     * @return Aufzählungswert.
     */
    public static Kategorie kategorie(int nummer) {
        return values()[nummer];
    }

    /**
     * Wandelt Augenzahl in Aufzählungswert um.
     *
     * @param augen
     *            Augenzahl.
     * @return Aufzählungswert.
     */
    public static Kategorie oben(int augen) {
        return kategorie(augen - 1);
    }

    /** Art des Tabelleneintrages. */
    private final Art art;
    /** Tabelleneintragsbeschreibung. */
    private final String beschreibung;
    /** Tabelleneintragsbezeichung. */
    private final String bezeichnung;

    /**
     * Erstellt Aufzählungswert.
     *
     * @param bezeichnung
     *            Tabelleneintragsbezeichung.
     * @param beschreibung
     *            Tabelleneintragsbeschreibung.
     */
    private Kategorie(String bezeichnung, String beschreibung) {
        this(bezeichnung, beschreibung, Art.DERIVAT);
    }

    /**
     * Erstellt Aufzählungswert.
     *
     * @param bezeichnung
     *            Tabelleneintragsbezeichung.
     * @param beschreibung
     *            Tabelleneintragsbeschreibung.
     * @param art
     *            Art des Aufzählungswertes.
     */
    private Kategorie(String bezeichnung, String beschreibung, Art art) {
        this.bezeichnung = bezeichnung;
        this.beschreibung = beschreibung;
        this.art = art;
    }

    /** Gibt an, ob Kategorie erwürfelt und gesetzt werden kann. */
    public boolean alle() {
        return oben() || unten();
    }

    /** Liefert für die Kategorie die Beschreibung als Hilfetext. */
    public String beschreibung() {
        return beschreibung;
    }

    /** Liefert die Bezeichnung der Kategorie zur Darstellung in der Tabelle. */
    public String bezeichnung() {
        return bezeichnung;
    }

    /** Gibt an, ob die Kategorie als erwürfelter Eintrag im oberen Tabellenteil liegt. */
    public boolean oben() {
        return art == Art.OBEN;
    }

    /** Gibt an, ob die Kategorie als erwürfelter Eintrag im unteren Tabellenteil liegt. */
    public boolean unten() {
        return art == Art.UNTEN;
    }

}
