/******************************************************************************
 ** $Id: Punkte.java 739 2015-05-23 16:13:32Z wmh $
 ** Diese Datei ist Bestandteil der Java-Quelltexte des Würfelspiels JaFuffy.
 ** Lauffähig ab Java 6.
 ******************************************************************************
 ** 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 2 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, write to the Free Software
 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 ******************************************************************************
 ** 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;

import java.util.ArrayList;

import javax.swing.event.TableModelEvent;
import javax.swing.table.AbstractTableModel;

/**
 * Zettelmodell (Turnierstand und Daten aller Spieler für Tabelle), enthält Punktestand und
 * Auswertungsinformationen.
 */
@SuppressWarnings("serial")
public
class Punkte extends AbstractTableModel {

    /** Meldungsklasse für Spieler zum Mitteilen von Änderungen */
    class Meldung {
        private final int spalte;

        /** Konstruktor */
        Meldung(int spalte) {
            this.spalte = spalte;
        }

        /** Mitteilung über die Veränderung der Spaltendaten */
        void mitteilen() {
            fireTableChanged(new TableModelEvent(Punkte.this, 0, getRowCount() - 1, spalte));
        }

    }

    // alle Mitspieler
    private final ArrayList<Spieler> spieler;
    // verwendete Auswertungsregeln
    private final Auswertung auswertung;
    // Zelle auswählbar?
    private boolean auswaehlbar = true;

    /**
     * Konstruktor.
     *
     * @param spieler
     *            alle Mitspieler
     * @param auswertung
     *            verwendete Auswertungsregeln
     */
    Punkte(ArrayList<Spieler> spieler, Auswertung auswertung) {
        this.spieler = spieler;
        this.auswertung = auswertung;
        for (Spieler s : spieler) {
            s.beobachten(new Meldung(spieler.indexOf(s)));
        }
    }

    /** Zeilenanzahl. */
    @Override
    public int getRowCount() {
        return Tabzeile.ANZAHL;
    }

    /** Spaltenanzahl. */
    @Override
    public int getColumnCount() {
        return spieler.size();
    }

    @Override
    public String getColumnName(int col) {
        return spieler.get(col).toString();
    }

    /**
     * Eingetragener Wert (Punktzahl).
     *
     * @param row
     *            Zeile des Eintrags
     * @param col
     *            Nummer des Spielers
     */
    @Override
    public Object getValueAt(int row, int col) {
        return spieler.get(col).punkte(Tabzeile.eintrag(row));
    }

    /**
     * Kann der Spieler in der (noch freien) Zelle Punkte setzen?
     *
     * @param row
     *            Zeile des Eintrags
     * @param col
     *            Nummer des Spielers
     */
    @Override
    public boolean isCellEditable(int row, int col) {
        Spieler s = spieler.get(col);
        return s.gewuerfelt() && s.setzbar(Tabzeile.eintrag(row)) && auswaehlbar;
    }

    /**
     * Rückmeldung der verwendeten Auswertung.
     *
     * @return Auswertungsobjekt
     */
    public Auswertung auswertung() {
        return auswertung;
    }

    /**
     * Zellen (nicht) auswaehlbar machen.
     *
     * @param auswaehlbar
     */
    public void auswaehlbar(boolean auswaehlbar) {
        this.auswaehlbar = auswaehlbar;
    }

    /**
     * Meldet zurück, ob Spieler gerade aktiv ("dran") ist und für die Punktzahlbestimmung einer
     * Spalte maßgebend ist.
     *
     * @param col
     *            Feldindex (entspricht Spaltenindex)
     * @return Spielerstatus, sprich ob Spieler gerade aktiv ist.
     */
    public boolean aktiv(int col) {
        Spieler s = spieler.get(col);
        return (s.rest() > 0 || s.gewuerfelt());
    }

    /**
     * Aktive Spalte aktualisieren.
     */
    public void aktiv() {
        for (int col = 0; col < getColumnCount(); col++) {
            if (aktiv(col)) {
                spieler.get(col).reaktivieren();
            }
        }
    }

    /**
     * Gibt an, ob der Ausgang für einen Spielzug noch offen ist und der aktive Spieler weiter
     * würfeln darf.
     *
     * @param col
     *            Feldindex (entspricht Spaltenindex)
     * @return Ist der Spielzug noch nicht abgeschlossen und daher der Ausgang noch offen?
     */
    public boolean offen(int col) {
        return spieler.get(col).rest() > 0;
    }

    /**
     * Gibt an, ob ein Spieler einen Spielzug angefangen hat.
     *
     * @param col
     *            Feldindex (entspricht Spaltenindex)
     * @return Ist der Spielzug noch nicht abgeschlossen und daher der Ausgang noch offen?
     */
    public boolean angefangen(int col) {
        return aktiv(col) && spieler.get(col).rest() < 3;
    }

    /**
     * Gibt an, ob ein Eintrag noch setzbar ist.
     *
     * @param row
     *            Tabellenzeile
     * @param col
     *            Tabellenspalte
     * @return Setzbarkeit
     */
    public boolean setzbar(int row, int col) {
        return spieler.get(col).setzbar(Tabzeile.eintrag(row));
    }

}
