package at.ac.tuwien.dbai.alternation.gui.example;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

import at.ac.tuwien.dbai.alternation.examples.Horn;
import at.ac.tuwien.dbai.alternation.examples.TicTacToe;
import at.ac.tuwien.dbai.alternation.gui.DefaultFormat;
import at.ac.tuwien.dbai.alternation.gui.MainFrame;
import at.ac.tuwien.dbai.alternation.runtime.ComputationTree;

public class TicTacToeTest {
    /**
     * The format-class for the GUI
     *
     */
    private static class TicTacToeFormat extends
            DefaultFormat<TicTacToe.Inputtape, TicTacToe.Worktape> {
        private String byteSymbol(byte number) {
            if (number == 1) {
                return "x";
            }
            if (number == 2) {
                return "o";
            }
            if (number == 0) {
                return "_";
            }
            return "e";
        }



        public String getShortInformation(TicTacToe.Worktape worktape, String
                                          state) {
            return state;
        }


        public String getLongInformation(TicTacToe.Worktape tape, String state) {
            StringBuffer buffer = new StringBuffer();

            if (state.equals("crossPlayer")) {
                buffer.append("cross players Turn: \n");
            } else {
                if (state.equals("noughtPlayer")) {
                    buffer.append("nought players Turn: \n");
                } else {
                    if (state.equals("start")) {
                        buffer.append("Initial configuration: \n");
                    } else {
                        throw new RuntimeException(
                                "Not a valid TicTacToe state.");
                    }
                }

            }

            for (int i = 0; i < 3; i++) {
                buffer.append(byteSymbol(tape.paper[i]) + ", ");
            }
            buffer.append("\n");
            for (int i = 3; i < 6; i++) {
                buffer.append(byteSymbol(tape.paper[i]) + ", ");
            }
            buffer.append("\n");
            for (int i = 6; i < 8; i++) {
                buffer.append(byteSymbol(tape.paper[i]) + ", ");
            }
            buffer.append(byteSymbol(tape.paper[8]) + ";\n");

            return buffer.toString();
        }

        @Override
        public void paintWorktape(TicTacToe.Worktape worktape, String state,
                Graphics g, Dimension size) {

            int lengthOfLines = size.height - 10;
            int spaceBetweenLines = (size.height - 10) / 3;

            g.drawLine(size.width / 2 - spaceBetweenLines / 2, 5, size.width
                    / 2 - spaceBetweenLines / 2, 5 + lengthOfLines);
            g.drawLine(size.width / 2 + spaceBetweenLines / 2, 5, size.width
                    / 2 + spaceBetweenLines / 2, 5 + lengthOfLines);

            g.drawLine((int) (size.width / 2 - 1.5 * spaceBetweenLines),
                    5 + spaceBetweenLines,
                    (int) (size.width / 2 + 1.5 * spaceBetweenLines),
                    5 + spaceBetweenLines);
            g.drawLine((int) (size.width / 2 - 1.5 * spaceBetweenLines),
                    5 + 2 * spaceBetweenLines,
                    (int) (size.width / 2 + 1.5 * spaceBetweenLines),
                    5 + 2 * spaceBetweenLines);

            if (state.equals("crossPlayer") || state.equals("noughtPlayer")
                    || state.equals("start")) {
                drawPlayerMark(
                        (int) (size.width / 2 - 1.5 * spaceBetweenLines + 5),
                        10, spaceBetweenLines, byteSymbol(worktape.paper[0]), g);
                drawPlayerMark(
                        (int) (size.width / 2 - spaceBetweenLines / 2 + 5), 10,
                        spaceBetweenLines, byteSymbol(worktape.paper[1]), g);
                drawPlayerMark(
                        (int) (size.width / 2 + 0.5 * spaceBetweenLines + 5),
                        10, spaceBetweenLines, byteSymbol(worktape.paper[2]), g);
                drawPlayerMark(
                        (int) (size.width / 2 - 1.5 * spaceBetweenLines + 5),
                        10 + spaceBetweenLines, spaceBetweenLines,
                        byteSymbol(worktape.paper[3]), g);
                drawPlayerMark(
                        (int) (size.width / 2 - spaceBetweenLines / 2 + 5),
                        10 + spaceBetweenLines, spaceBetweenLines,
                        byteSymbol(worktape.paper[4]), g);
                drawPlayerMark(
                        (int) (size.width / 2 + 0.5 * spaceBetweenLines + 5),
                        10 + spaceBetweenLines, spaceBetweenLines,
                        byteSymbol(worktape.paper[5]), g);
                drawPlayerMark(
                        (int) (size.width / 2 - 1.5 * spaceBetweenLines + 5),
                        10 + 2 * spaceBetweenLines, spaceBetweenLines,
                        byteSymbol(worktape.paper[6]), g);
                drawPlayerMark(
                        (int) (size.width / 2 - spaceBetweenLines / 2 + 5),
                        10 + 2 * spaceBetweenLines, spaceBetweenLines,
                        byteSymbol(worktape.paper[7]), g);
                drawPlayerMark(
                        (int) (size.width / 2 + 0.5 * spaceBetweenLines + 5),
                        10 + 2 * spaceBetweenLines, spaceBetweenLines,
                        byteSymbol(worktape.paper[8]), g);
            } else {
                throw new RuntimeException("Not a valid TicTacToe state.");
            }
        }

        /**
         * Draws the mark of a player at a specific position.
         * <code>player</code> is the parameter to identifie the player, who's
         * mark should be drawn. <code>player</code> could have the following
         * items:
         * <ul>
         * <li>x</li>
         * <li>o</li>
         * </ul>
         * If <code>player</code> doesn't match to any item of the list, nothing
         * will be drawn.
         *
         * @param x
         *            the x-coordinate for the mark
         * @param y
         *            the y-coordinate for the mark
         * @param spaceBetweenLines
         *            the width of a cell
         * @param player
         *            the player
         * @param g
         *            the <code>Graphics</code> object, where the mark is drawn
         *            to
         */
        private void drawPlayerMark(int x, int y, int spaceBetweenLines,
                String player, Graphics g) {
            if (player.equals("x")) {
                g.setColor(Color.RED);
                g.drawLine(x, y, x + spaceBetweenLines - 10, y
                        + spaceBetweenLines - 10);
                g.drawLine(x, y + spaceBetweenLines - 10, x + spaceBetweenLines
                        - 10, y);
            } else if (player.equals("o")) {
                g.setColor(Color.BLUE);
                g.drawRoundRect(x, y, spaceBetweenLines - 10,
                        spaceBetweenLines - 10, 100, 100);
            }
        }

    }

    public static void main(String[] args) {
        // create an instance
        byte[] game = new byte[] { 0, 0, 0, 0, 1, 0, 0, 2, 0 };

        // execute the Alter-Java program
        TicTacToe atm = new TicTacToe();
        atm.compute(game, true);
        // get the computation tree
        ComputationTree<TicTacToe.Worktape> cT = atm.getComputationTree();

        // start the GUI
        new MainFrame<TicTacToe.Inputtape, TicTacToe.Worktape>(cT,
                new TicTacToeFormat());
    }
}