package szakdolgozat.client.ui;

import java.util.Date;

import szakdolgozat.client.UI;
import szakdolgozat.client.game.Game;
import szakdolgozat.client.servereventlistener.GameEventsListener;
import szakdolgozat.client.serverevents.MessageEvent;
import szakdolgozat.client.serverevents.MoveEvent;
import szakdolgozat.shared.User;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.HTMLTable.Cell;
import com.google.gwt.widgetideas.graphics.client.Color;
import com.google.gwt.widgetideas.graphics.client.GWTCanvas;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.WidgetCanvas;

import de.novanic.eventservice.client.event.domain.Domain;
import de.novanic.eventservice.client.event.domain.DomainFactory;

public class GameDialog extends DialogBox {
	private Canvas canvas;
	public static GWTCanvas lineCanvas;
	private Game game;
	public User opponent;
	private FlexTable table;
	private TextArea textArea;
	private VerticalPanel talkVerticalPanel;
	public boolean isMineTurn;
	Domain movesListeningDomain;

	public GameDialog() {
		setGlassEnabled(true);
		//setAutoHideEnabled(true);

		game = new Game();
		lineCanvas = new GWTCanvas(512, 471);

		lineCanvas.setLineWidth(1);
		lineCanvas.setStrokeStyle(Color.GREEN);
		lineCanvas.setBackgroundColor(Color.LIGHTGREY);

		VerticalPanel verticalPanel = new VerticalPanel();
		verticalPanel
				.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		verticalPanel.setBorderWidth(1);
		setWidget(verticalPanel);
		verticalPanel.setSize("515px", "545px");

		canvas = new Canvas();
		canvas.setSize("512px", "471px");
		canvas.addChild(lineCanvas);

		table = new FlexTable();
		WidgetCanvas widgetCanvas = new WidgetCanvas(table);
		canvas.addChild(widgetCanvas);
		widgetCanvas.setRect(0, 0, 512, 471);
		final GameDialog gd = this;
		ClickHandler ch = new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				Cell cell = table.getCellForEvent(event);
				int row = cell.getRowIndex();
				int col = cell.getCellIndex();
				if (isMineTurn) {
					if (game.isNodeSelectable(row, col)) {						
						sendMoveToOpponent(row, col);
						makeMove(row, col);
						if (game.isGameEndState() == true)
							processGameEnd(true);
					} else {
						RadioButton rb = ((RadioButton) table.getWidget(row,
								col));
						rb.setValue(false);
						rb.setFocus(false);
					}
				} else {
					RadioButton rb = ((RadioButton) table.getWidget(row, col));
					rb.setValue(false);
					rb.setFocus(false);
				}
			}
		};
		verticalPanel.add(canvas);

		talkVerticalPanel = new VerticalPanel();
		talkVerticalPanel
				.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
		talkVerticalPanel
				.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		verticalPanel.add(talkVerticalPanel);
		talkVerticalPanel.setWidth("512px");

		textArea = new TextArea();
		textArea.setVisibleLines(2);
		talkVerticalPanel.add(textArea);
		textArea.setWidth("504px");
		textArea.setReadOnly(true);

		final TextBox textBox = new TextBox();
		talkVerticalPanel.add(textBox);
		textBox.setWidth("504px");

		for (int i = 0; i < 20; i++) {
			for (int j = 0; j < 20; j++) {
				lineCanvas.setFillStyle(Color.GREY);
				RadioButton rb = new RadioButton(20 * i + j + "");
				rb.addClickHandler(ch);
				table.setWidget(i, j, rb);
			}
		}

		textBox.addKeyPressHandler(new KeyPressHandler() {
			public void onKeyPress(KeyPressEvent event) {
				if (event.getCharCode() == KeyCodes.KEY_ENTER) {
					String date = DateTimeFormat.getFormat("HH:mm:ss").format(
							new Date());
					sendMessageToOpponent(textBox.getText());
					textArea.setText(textArea.getText()
							+ UI.currentUser.getUsername() + " (" + date
							+ ") : " + textBox.getText() + "\n");
					textBox.setText("");

					textArea.getElement().setScrollTop(
							textArea.getElement().getScrollHeight());

				}
			}
		});

		movesListeningDomain = DomainFactory.getDomain(UI.currentUser
				.getUsername()
				+ "-gamelistener");

		UI.theEventService.addListener(movesListeningDomain,
				new GameEventsListener() {

					@Override
					public void onMoveEvent(MoveEvent anEvent) {
						MoveEvent me = (MoveEvent) anEvent;
						makeMove(me.getRow(), me.getCol());
						if (game.isGameEndState())
							processGameEnd(false);

					}

					@Override
					public void onMessageEvent(MessageEvent event) {
						String date = DateTimeFormat.getFormat("HH:mm:ss")
								.format(new Date());
						textArea.setText(textArea.getText()
								+ opponent.getUsername() + " (" + date + ") : "
								+ event.getMessage() + "\n");
						textArea.getElement().setScrollTop(
								textArea.getElement().getScrollHeight());

					}
				});

	}

	public void colorButtons() {
		final int canvasleft = lineCanvas.getAbsoluteLeft();
		final int canvastop = lineCanvas.getAbsoluteTop();
		for (int i = 0; i < 20; i++) {
			for (int j = 0; j < 20; j++) {
				lineCanvas.setFillStyle(Color.LIGHTGREY);
				RadioButton rb = ((RadioButton) table.getWidget(i, j));
				int absleft = rb.getAbsoluteLeft() + 10;
				int abstop = rb.getAbsoluteTop() + 6;
				if ((i == 0 || i == 19) && (j != 0 && j != 19)) {
					lineCanvas.setFillStyle(Color.GREEN);
				} else if ((j == 0 || j == 19) && (i != 0 && i != 19)) {
					lineCanvas.setFillStyle(Color.BLUE);
				} else if ((i == 0 || i == 19) && (j == 0 || j == 19)) {
					lineCanvas.setFillStyle(Color.BRIGHT_ORANGE);
				}

				int posInBrowX = absleft - canvasleft - 5;
				int posInBrowY = abstop - canvastop - 6;
				lineCanvas.fillRect(posInBrowX, posInBrowY, 13, 13);
			}
		}
	}

	protected void sendMessageToOpponent(String text) {
		UI.servicesHandler.sendMessageToGamePartner(opponent, text,
				new AsyncCallback<Void>() {

					@Override
					public void onSuccess(Void result) {
						// TODO Auto-generated method stub

					}

					@Override
					public void onFailure(Throwable caught) {
						// TODO Auto-generated method stub

					}
				});

	}

	protected void makeMove(int row, int col) {
		RadioButton rb = ((RadioButton) table.getWidget(row, col));
		rb.setValue(true);
		rb.setEnabled(false);
		rb.setFocus(false);
		int absleft = rb.getAbsoluteLeft() + 10;
		int abstop = rb.getAbsoluteTop() + 6;
		int canvasleft = lineCanvas.getAbsoluteLeft();
		int canvastop = lineCanvas.getAbsoluteTop();
		game.nodeSelected(row, col, absleft - canvasleft, abstop - canvastop);
		isMineTurn = isMineTurn == true ? false : true;
		String title = isMineTurn ? "Ön lép!" : "Ellenfél lép!";
		this.setTitle(title);
	}

	private void processGameEnd(boolean iWon) {
		for (int i = 0; i < 20; i++) {
			for (int j = 0; j < 20; j++) {
				((RadioButton) table.getWidget(i, j)).setEnabled(false);
			}
		}
		if (iWon == true) {
			UI.servicesHandler.gameWonByUser(UI.currentUser,
					new AsyncCallback<Void>() {

						@Override
						public void onFailure(Throwable caught) {
							// TODO Auto-generated method stub

						}

						@Override
						public void onSuccess(Void result) {
							// TODO Auto-generated method stub

						}
					});
			this.clear();
			this.add(new Label("Gratulálunk, nyert!"));
		} else {
			this.clear();
			this.add(new Label("Sajnos most kikapott :("));
		}
		//this.center();
		this.hide();
		UI.userListWindow.userListGrid.show();
		UI.theEventService.removeListeners(movesListeningDomain);
		
	}

	protected void sendMoveToOpponent(int row, int col) {
		UI.servicesHandler.sendMoveToOpponent(opponent, row, col,
				new AsyncCallback<Void>() {

					@Override
					public void onSuccess(Void result) {
					}

					@Override
					public void onFailure(Throwable caught) {

					}
				});

	}
	@Override
	protected void onUnload() {
		// TODO Auto-generated method stub
		super.onUnload();
		UI.userListWindow.userListGrid.show();
		UI.userListWindow.getUserListFromServer();
		UI.userListWindow.refreshUserList();
	}
}
