import theater.*;

import java.awt.Color;


public class Piece extends Actor {
    static Turn lastTurn = null;
    boolean isA;
    Space space = null;
    Space toSpace;
    int origWidth;
    int origHeight;
    boolean scaled;
    Board board;
    Game game;
    Rules rules;
    ProgramThread programThread = null;

    Piece(boolean isA) {
        this.isA = isA;
        scaled = false;
        programThread = null;
    }

    Piece(Piece figur) {
        this.isA = figur.isA;
        scaled = false;
        programThread = null;
    }

    public void addedToStage(Stage stage) {
        board = (Board) getStage();
        game = board.getGame();
        rules = game.getRegeln();
    }

    protected Object clone() {
        return null;
    }

    public boolean isA() {
        return this.isA;
    }

    public void setSpace(Space space) {
        this.space = space;
    }

    public Space getSpace() {
        return this.space;
    }

    public void run() {
        board = (Board) getStage();
        game = board.getGame();
        rules = game.getRegeln();

        if (board.end) {
            return;
        }

        if (board.gameState == Board.PLAYER_CHOICE) {
            return;
        }

        if ((board.gameState == Board.WAIT) && (programThread == null)) {
            return;
        }

        Player currentPlayer = game.getAktuellerSpieler();
        Player otherPlayer = game.getOtherPlayer();

        if (!currentPlayer.isHuman() && !otherPlayer.isHuman()) {
            return; // wird durch Board gehandhabt
        }

        if (currentPlayer.isHuman()) {
            actHuman();
        } else {
            actProgram();
        }
    }

    public void actHuman() {
        ((Board) getStage()).setHuman(true);
    }

    public void actProgram() {
        if (this.getClass() != Brain.class) {
            return;
        }

        Player currentPlayer = game.getAktuellerSpieler();

        if (board.gameState == Board.GAME) {
            programThread = new ProgramThread(currentPlayer, lastTurn);
            programThread.start();
            board.pThread = programThread;
            board.gameState = Board.WAIT;

            return;
        } else if ((board.gameState == Board.WAIT) && programThread.finished) {
            lastTurn = programThread.newTurn;
            programThread = null;
            board.pThread = null;
            board.gameState = Board.GAME;

            // lastTurn = currentPlayer.naechsterSpielzug(lastTurn);
            // System.out.println(currentPlayer.getName() + " Turn: " +
            // lastTurn);
            board.fuehreSpielzugAus(lastTurn);
            checkEnd(currentPlayer);
        }
    }

    void checkEnd(Player currentPlayer) {
        if (rules.spielEnde(currentPlayer, game.getOtherPlayer())) {
            int ergebnis = rules.getErgebnis();
            int grund = rules.getEndeGrund();
            String winner;
            String matter;
            Color color;
            Info info;

            if (ergebnis == Rules.SIEGER_A) {
                winner = "Winner is Player BLUE";
                color = Color.BLUE;

                for (Piece p : board.getPieces(true)) {
                    p.setJubel();
                }

                for (Piece p : board.getPieces(false)) {
                    p.setSad();
                }
            } else if (ergebnis == Rules.SIEGER_B) {
                winner = "Winner is Player RED";
                color = Color.RED;

                for (Piece p : board.getPieces(false)) {
                    p.setJubel();
                }

                for (Piece p : board.getPieces(true)) {
                    p.setSad();
                }
            } else { // Unentschieden
                winner = "Game ended in a tie";
                color = Color.BLACK;

                for (Piece p : board.getPieces(true)) {
                    p.setNormal();
                }

                for (Piece p : board.getPieces(false)) {
                    p.setNormal();
                }
            }

            if (grund == Rules.KEIN_ZUG_MOEGLICH) {
                matter = "Matter: No possible turn";
            } else if (grund == Rules.BRAIN_GESCHLAGEN) {
                matter = "Matter: Brain captured";
            } else {
                matter = "Matter: Only brains left";
            }

            info = new Info(winner, matter, color);
            board.add(info, board.getNumberOfColumns() / 2,
                board.getNumberOfRows() / 2);
            board.end = true;
        } else {
            game.changePlayer();
            currentPlayer = this.game.getAktuellerSpieler();

            for (Piece p : board.getPieces(currentPlayer.isSpielerA())) {
                if (currentPlayer.isHuman()) {
                    p.setNormalFinger();
                } else {
                    p.setDenken();
                }
            }

            for (Piece p : board.getPieces(this.game.getOtherPlayer()
                                                    .isSpielerA())) {
                p.setNormal();
            }
        }
    }

    boolean in(Space[] spaces, Space space) {
        for (Space s : spaces) {
            if (s == space) {
                return true;
            }
        }

        return false;
    }

    String getColor() {
        if (isA) {
            return "blue";
        } else {
            return "red";
        }
    }

    String getKuerzel() {
        return null;
    }

    void setNormal() {
        setImage(getKuerzel() + "-" + getColor() + ".gif");
    }

    void setSad() {
        setImage(getKuerzel() + "-" + getColor() + "-sad.gif");
    }

    void setNormalFinger() {
        setImage(getKuerzel() + "-" + getColor() + "-finger.gif");
    }

    void setSadFinger() {
        setImage(getKuerzel() + "-" + getColor() + "-sad-finger.gif");
    }

    void setJubel() {
        setImage(getKuerzel() + "-" + getColor() + "-jubel.gif");
    }

    void setDenken() {
        setImage(getKuerzel() + "-" + getColor() + "-denken.gif");
    }

    void scale() {
        origWidth = getImage().getWidth();
        origHeight = getImage().getHeight();
        this.getImage().scale((int) (origWidth * 1.2), (int) (origHeight * 1.2));
    }

    void reScale() {
        this.getImage().scale((int) (origWidth), (int) (origHeight));
    }

    void setScaled(boolean s) {
        scaled = s;
    }

    boolean isScaled() {
        return scaled;
    }
}


class ProgramThread extends Thread {
    Player currentPlayer;
    Turn lastTurn;
    Turn newTurn;
    boolean finished;

    ProgramThread(Player c, Turn l) {
        this.currentPlayer = c;
        this.lastTurn = l;
        this.newTurn = null;
        finished = false;
    }

    public void run() {
        newTurn = currentPlayer.naechsterSpielzug(lastTurn);
        finished = true;
    }
}
