import theater.*;


/**
 * Die Klasse stellt eine Repraesentation des virtuellen Spielers dar.
 *
 * @author Dietrich Boles (Universitaet Oldenburg)
 * @version 1.0 (07.10.2009)
 *
 */
public class Spieler extends Actor {
    private boolean active; // interner Flag, ob der Spieler gerade agiert

    // Default-Konstruktor (muss implementiert werden!)
    public Spieler() {
        super(); // nicht loeschen!
        setVisible(false);
        active = false;
    }

    // Copy-Konstruktor (muss implementiert werden!)
    public Spieler(Spieler actor) {
        super(actor); // nicht loeschen!
        setVisible(false);
        active = actor.active;
    }

    @Description("<html>Liefert die aktuelle Größe des Spielfeldes.</html>")
    public int getSize() {
        Performance.getPerformance().lock();

        try {
            return ((Spielfeld) getStage()).getSize();
        } finally {
            Performance.getPerformance().unlock();
        }
    }

    @Description("<html>Platziert eine Dame auf das angegebene Feld " +
    "(erster Parameter = Reihe, zweiter Parameter = Spalte)." +
    "<br>Fehler, wenn ungültige Koordinaten übergeben oder die Regeln des Damenproblems verletzt werden.</html>")
    public void setQueen(int row, int col) {
        Performance.getPerformance().lock();

        try {
            checkCoord(row, col);
            checkRules(row, col);

            Spielfeld feld = (Spielfeld) getStage();
            active = true;
            feld.add(new Dame(), col, row);
            active = false;
            feld.setDame(row, col);
        } finally {
            Performance.getPerformance().unlock();
        }
    }

    @Description("<html>Überprüft, ob sich auf dem angegebenen Feld " +
    "(erster Parameter = Reihe, zweiter Parameter = Spalte) eine Dame befindet." +
    "<br>Fehler, wenn ungültige Koordinaten übergeben werden.</html>")
    public boolean isQueen(int row, int col) {
        Performance.getPerformance().lock();

        try {
            checkCoord(row, col);

            Spielfeld feld = (Spielfeld) getStage();

            return feld.isDame(row, col);
        } finally {
            Performance.getPerformance().unlock();
        }
    }

    @Description("<html>Entfernt eine Dame vom angegebenen Feld " +
    "(erster Parameter = Reihe, zweiter Parameter = Spalte)." +
    "<br>Fehler, wenn ungültige Koordinaten übergeben werden.</html>")
    public void removeQueen(int row, int col) {
        Performance.getPerformance().lock();

        try {
            checkCoord(row, col);

            if (!isQueen(row, col)) {
                throw new RuntimeException("Keine Dame vorhanden: (" + row +
                    "/" + col + ")");
            }

            Spielfeld feld = (Spielfeld) getStage();
            active = true;
            feld.remove(feld.getComponentsAt(col, row, Dame.class).get(0));
            active = false;
            feld.removeDame(row, col);
        } finally {
            Performance.getPerformance().unlock();
        }
    }

    @Invisible
    boolean isActive() {
        return active;
    }

    @Invisible
    private void checkCoord(int row, int col) throws RuntimeException {
        Spielfeld feld = (Spielfeld) getStage();

        if ((row < 0) || (col < 0) || (row >= feld.getSize()) ||
                (col >= feld.getSize())) {
            throw new RuntimeException("Ungültige Koordinaten: (" + row + "/" +
                col + ")");
        }
    }

    @Invisible
    private void checkRules(int row, int col) throws RuntimeException {
        Spielfeld feld = (Spielfeld) getStage();

        if (!feld.checkSetDame(row, col)) {
            throw new RuntimeException(
                "Verletzung der Regeln des Damenproblems: (" + row + "/" + col +
                ")");
        }
    }
}
