package org.ggp.base.apps.kiosk.games;

import java.awt.Color;
import java.awt.Graphics;
import java.util.List;

import org.ggp.base.apps.kiosk.GameCanvas;
import org.ggp.base.util.gdl.grammar.GdlConstant;
import org.ggp.base.util.gdl.grammar.GdlFunction;
import org.ggp.base.util.gdl.grammar.GdlSentence;
import org.ggp.base.util.statemachine.Move;
import org.ggp.base.util.statemachine.exceptions.MoveDefinitionException;


/**
 * A reference implementation of Tic-Tac-Toe based purely on GameCanvas,
 * not using any of the standard templates. Comes to just under 150 lines.
 *
 * @author Sam Schreiber
 */
public class TicTacToeCanvas_Reference extends GameCanvas {
    public static final long serialVersionUID = 0x1;

    @Override
    public String getGameName() {
        return "Tic-Tac-Toe (Old Version)";
    }

    @Override
    protected String getGameKey() {
        return "ticTacToe";
    }

    private Graphics mostRecentG;
    @Override
    protected void paintGame(Graphics g) {
        int width = g.getClipBounds().width;
        int height = g.getClipBounds().height;

        mostRecentG = g;

        g.setColor(this.getBackground());
        g.fillRect(0, 0, width, height);

        g.setColor(Color.BLACK);
        g.fillRect(width/3-2, 0, 4, height);
        g.fillRect(2*width/3-2, 0, 4, height);
        g.fillRect(0, height/3-2, width, 4);
        g.fillRect(0, 2*height/3-2, width, 4);

        if(gameState == null)
            return;

        for(GdlSentence stateFact : gameState.getContents()) {
            if(stateFact.getBody().size() > 1)
                continue;

            GdlSentence theRealSentence = stateFact.getBody().get(0).toSentence();
            if(theRealSentence.getName().toString().equals("cell")) {
                int xCell = Integer.parseInt(theRealSentence.getBody().get(0).toString());
                int yCell = Integer.parseInt(theRealSentence.getBody().get(1).toString());
                char mark = theRealSentence.getBody().get(2).toString().charAt(0);

                int xSpot = (xCell-1)*width/3 + 2;
                int ySpot = (yCell-1)*height/3 + 2;

                g.setColor(Color.BLACK);
                final int BORDER_SIZE = 35;
                if(mark == 'b') {
                    ;
                } else if(mark == 'x') {
                    g.drawLine(xSpot+BORDER_SIZE, ySpot+BORDER_SIZE, xSpot + width/3 - BORDER_SIZE, ySpot + height/3 - BORDER_SIZE);
                    g.drawLine(xSpot+BORDER_SIZE, ySpot + height/3 - BORDER_SIZE, xSpot + width/3 - BORDER_SIZE, ySpot+BORDER_SIZE);
                } else if(mark == 'o') {
                    g.drawOval(xSpot+BORDER_SIZE, ySpot+BORDER_SIZE, width/3 - 2*BORDER_SIZE, height/3 - 2*BORDER_SIZE);
                }
            }
        }

        try {
            List<Move> legalMoves = stateMachine.getLegalMoves(gameState, myRole);

            for(Move legalMove : legalMoves) {
                if(legalMove.getContents() instanceof GdlConstant)
                    continue;

                GdlFunction moveContents = (GdlFunction) legalMove.getContents();
                int xCell = Integer.parseInt(moveContents.getBody().get(0).toString());
                int yCell = Integer.parseInt(moveContents.getBody().get(1).toString());

                int xSpot = (xCell-1)*width/3 + 2;
                int ySpot = (yCell-1)*height/3 + 2;

                final int BORDER_SIZE = 60;
                g.setColor(Color.GREEN);
                if(myRole.toString().equals("xplayer")) {
                    g.drawLine(xSpot+BORDER_SIZE, ySpot+BORDER_SIZE, xSpot + width/3 - BORDER_SIZE, ySpot + height/3 - BORDER_SIZE);
                    g.drawLine(xSpot+BORDER_SIZE, ySpot + height/3 - BORDER_SIZE, xSpot + width/3 - BORDER_SIZE, ySpot+BORDER_SIZE);
                } else {
                    g.drawOval(xSpot+BORDER_SIZE, ySpot+BORDER_SIZE, width/3 - 2*BORDER_SIZE, height/3 - 2*BORDER_SIZE);
                }

                if(xSelectedCell == xCell && ySelectedCell == yCell) {
                    g.drawRect(xSpot+BORDER_SIZE/2, ySpot+BORDER_SIZE/2, width/3-BORDER_SIZE, height/3-BORDER_SIZE);
                }
            }
        } catch (MoveDefinitionException e) {
            ;
        }
    }

    @Override
    protected void handleDragEvent(int dx, int dy) {
        ;
    }

    private int xSelectedCell, ySelectedCell;
    @Override
    protected void handleClickEvent(int x, int y) {
        int width = mostRecentG.getClipBounds().width;
        int height = mostRecentG.getClipBounds().height;

        try {
            List<Move> legalMoves = stateMachine.getLegalMoves(gameState, myRole);

            int xCell = 1+3*x/width;
            int yCell = 1+3*y/height;

            String moveString = "( mark " + xCell + " " + yCell + " )";
            for(Move legalMove : legalMoves) {
                if(legalMove.toString().equals(moveString)) {
                    submitWorkingMove(legalMove);

                    xSelectedCell = xCell;
                    ySelectedCell = yCell;

                    repaint();
                }
            }
        } catch(Exception e) {
            ;
        }
    }

    @Override
    public void clearMoveSelection() {
        xSelectedCell = ySelectedCell = 0;
        submitWorkingMove(null);

        repaint();
    }
}