package scotlandyard.client.widget;
import java.io.Serializable;
import java.util.List;
import java.util.Stack;
import net.zschech.gwt.comet.client.CometClient;
import net.zschech.gwt.comet.client.CometListener;
import net.zschech.gwt.comet.client.CometSerializer;
import scotlandyard.client.network.comet.MyCometSerializer;
import scotlandyard.client.network.rpc.GameService;
import scotlandyard.client.network.rpc.GameServiceAsync;
import scotlandyard.client.util.Peao;
import scotlandyard.client.util.Quadrado;
import scotlandyard.shared.BoardState;
import scotlandyard.shared.messaging.Message;
import scotlandyard.shared.messaging.Message.MessageType;
import scotlandyard.shared.messaging.MessageGiveTurn;
import scotlandyard.shared.messaging.MessageMove;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
public class Tabuleiro extends AbsolutePanel {
public static final int N_COLUNAS = 23;
public static final int N_LINHAS = 18;
public static final String HIGHLIGHT_URL = "images/highlight.png";
public static final String CAMPO_URL = "images/Campo.png";
public static final String CAMPO_URL2 = "images/Campo2.png";
//String utilizada por HighLight para desconsiderar
public static String CAMPO_FULL_URL;
// Remote Services
GameServiceAsync game = GWT.create(GameService.class);
public static final String COMET_SERVER_URL = GWT.getModuleBaseURL()
+ "server2";
// private FlowPanel panel = new FlowPanel();
// Componentes visuais
final Label textToServerLabel = new Label();
final HTML serverResponseLabel = new HTML();
final Button closeButton = new Button("Close");
MoveHandler move = new MoveHandler();
//
private Peao[] peoes;
private int numeroDeJogadores;
private Quadrado quadrados[];
private Boolean enabled = false;
private Stack<Integer> highlights;
/*
* private final MovimentoServiceAsync tabMess = GWT
* .create(MovimentoService.class);
*/
public void criarPeoes (String[] nomes){
System.out.println("\tCriando peoes...");
for (int i = 0; i < nomes.length; i++) {
peoes[i] = new Peao(nomes[i], i);
peoes[i].setUrl("images/"+peoes[i].getID()+".gif");
System.out.println("\t\tPeao "+i+" ID: "+peoes[i].getID());
}
numeroDeJogadores = nomes.length;
System.out.print("\tOk.\n");
}
public Tabuleiro(String[] nomes) {
this();
//13 + 2 (11+9+7+5+3+1): max index for a 6 in dice
highlights = new Stack<Integer>();
criarPeoes(nomes);
// posicionarJogadores();
System.out.print("\tRequisitando BoardState...");
game.getBoardState(new AsyncCallback<BoardState>() {
@Override
public void onSuccess(BoardState result) {
System.out.println(" Ok.\n");
loadBoardState(result);
/*
estado = result;
if (estado == null)
System.out.println("estado � null");
System.out.println(estado);
if (estado.getMovableAreas() == null)
System.out.println("Movable areas � null");
System.out.println("Adicionando imagem e listener a areas and�veis...");
for (int a : estado.getMovableAreas()) {
if (quadrados[a] == null) {
System.out.println("Quadrado � null");
}
if (move == null)
System.out.println("Move � null");
quadrados[a].setUrl(CAMPO_URL);
quadrados[a].addClickHandler(move);
//System.out.println("\t"+ a + " - "+quadrados[a].getUrl());
}
//ISSO ESTA HORRIVEL
CAMPO_FULL_URL = quadrados[estado.getMovableAreas()[0]].getUrl();
System.out.println("Fim da adicao de listener e imagens");
System.out.println("Posicionando jogadores...");
for (int i = 0; i < numeroDeJogadores; i++) {
mover(peoes[i].getNomeJogador(),
90 + i,
90 + i);
}
System.out.println("Jogadores posicionados.");*/
}
@Override
public void onFailure(Throwable caught) {
System.out.print(" Falhou.\n");
}
});
}
private void loadBoardState (BoardState boardState){
if (boardState == null){
System.out.print("\t\tEstado � nulo!");
return;
}
else{
System.out.print("\t\tBoardState carregado com sucesso!");
}
buildWalkableAreas(boardState.getMovableAreas());
drawPlayers(boardState.getPlayerPositions());
System.out.print("\nNotificando sucesso na construcao da interface...");
game.interfaceReady(new AsyncCallback<Void>(){
@Override
public void onFailure(Throwable caught) {
System.out.print(" Falhou.\n");
}
@Override
public void onSuccess(Void result) {
System.out.print(" Ok.\n");
}
});
}
private void buildWalkableAreas(int[] walkableAreas){
System.out.print("\t\tBuilding walkable areas...");
for (int a : walkableAreas){
quadrados[a].setUrl(CAMPO_URL);
quadrados[a].addClickHandler(move);
}
System.out.println(" Ok.\n");
System.out.print("\t\tFazendo gambiarra... ");
CAMPO_FULL_URL = quadrados[walkableAreas[0]].getUrl();
System.out.print(" Feito.\n");
}
private void drawPlayers(int[] playerPositions){
System.out.print("\t\tDrawing players..." );
for (int i = 0; i < numeroDeJogadores; i++){
mover(peoes[i].getNomeJogador(),
playerPositions[i],
playerPositions[i]);
}
System.out.print("\t\tOk.\n");
}
/*
* private void posicionarJogadores() { for (int i = 0; i <
* numeroDeJogadores; i++) { mover(peoes[i].getNomeJogador(),
* estado.getPositionOfPlayer(i), estado.getPositionOfPlayer(i)); } }
*/
public Tabuleiro() {
//quadrados = new Quadrado[20];
System.out.print("\nCONSTRUINDO TABULEIRO\n");
System.out.print ("\tAlocando mem�ria... ");
quadrados = new Quadrado[N_LINHAS * N_COLUNAS];
this.setSize((N_COLUNAS)*50+"px", N_LINHAS*50+"px" );
peoes = new Peao[6];
System.out.println(" Ok.\n");
startCometSession();
criarQuadrados();
}
private void startCometSession() {
System.out.print("\tCriando sessao COMET... ");
CometListener listener = new CometListener() {
public void onConnected(int heartbeat) {
}
public void onDisconnected() {
}
public void onHeartbeat() {
}
public void onRefresh() {
}
public void onError(Throwable exception, boolean connected) {
// warn the user of the connection error
}
public void onMessage(List<? extends Serializable> messages) {
System.out.println("Recebi uma mensagem2!");
for (Serializable message : messages) {
System.out.println("Conegui a mensagem! " + message);
Message msg = (Message) message;
MessageType type = msg.getMessageType();
if (type == MessageType.MOVE) {
MessageMove movimento = (MessageMove) msg;
clearHighlights();
mover(movimento.getSenderName(), movimento.getSource(),
movimento.getDestination());
//bloquear interface
enabled = false;
} else if(type == MessageType.GIVE_TURN){
//desbloquear interface
MessageGiveTurn msgg = (MessageGiveTurn)message;
System.out.println("\tCLIENTE: Give turn: Desbloqueando interface:");
System.out.println("\tCLIENTE: Highlighting movable areas");
highlightMovableAreas(msgg.getPlayerPosition(), msgg.getDiceNumber());
enabled = true;
}
else if (type == MessageType.DISCONNECT) {
}
else if (type == MessageType.ERRO_MOVIMENTO_INVALIDO){
//MessageErro msgg = (MessageErro)message;
new ErrorDialog(message.toString()).show();
}
}
}
};
CometSerializer serializer = GWT.create(MyCometSerializer.class);
CometClient client = new CometClient(COMET_SERVER_URL, serializer,
listener);
client.start();
System.out.print(" Ok.\n");
}
/**
* Metodo que cria os quadrados dando a cada um um numero que vai de 0 a
* N_LINHAS*N_COLUNAS.
*
* Vale ressaltar que o construtor de Quadrado automaticamente calcula o
* numero da linha e o numero da coluna da instancia correspondente do
* quadrado.
*
* Esses valores sao utilizados, por exemplo, pela classe Validor para
* determinar se um movimento e ou nao valido.
*/
private void criarQuadrados() {
int n = 0;
int x, y;
System.out.print("\tAdicionando quadrados...");
for (int i = 0; i < quadrados.length; i++) {
quadrados[i] = new Quadrado(n++);
quadrados[i].setUrl(CAMPO_URL2);
//quadrados[i].setUrl();
x = quadrados[i].getX()*50;
y = quadrados[i].getY()*50;
this.add(quadrados[i], x, y);
//System.out.println("\t" + i + " - "+quadrados[i]);
}
System.out.print(" Ok.\n");
}
private int indexOf(String nomePeao) {
for (int i = 0; i < numeroDeJogadores; i++) {
if (peoes[i].getNomeJogador().equals(nomePeao)) {
return i;
}
}
System.out.println("jogador nao encontrado");
return -1;
}
public void mover(String nome, int src, int dest) {
// soma dos ID's dos jogadores, que identificam quantos jogadores est�o
// no quadrado
//int IDJogador = peoes[indexOf(nome)].getID();
//int x = quadrados[dest].acrescentarJogador(IDJogador);
//quadrados[dest].setUrl("images/" + x + ".png");
//quadrados[dest].setUltimoJogador(nome);
System.out.println("\n\t\t\tMOVENDO "+nome);
peoes[indexOf(nome)].setCurrentSquare(dest);
//x = quadrados[src].retirarJogador(IDJogador);
//Verifica se h� algum peao no quadrado de origem
//Se sim, desenha
//Se n�o desenha campo
Peao p = getPeaoAt (src);
System.out.println("\t\t\t\tSRC: "+src+" ");
if (p == null){
//System.out.println("nulo");
quadrados[src].setUrl(CAMPO_URL);
}else{
quadrados[src].setUrl(p.getUrl());
}
//quadrados[src].setUrl("images/" + x + ".png");
//Desenha peao no destino
System.out.println("\t\t\t\tDEST: "+dest+"\n");
quadrados[dest].setUrl(peoes[indexOf(nome)].getUrl());
}
public Peao getPeaoAt (int n){
for (int i = 0; i < numeroDeJogadores; i++){
if (peoes[i].getCurrentSquare() == n)
return peoes[i];
}
return null;
}
private void highlightMovableAreas(int startSquareNumber, int n){
int k = n;
int a,b;
int start_c = startSquareNumber % N_COLUNAS;
int start_r = startSquareNumber / N_COLUNAS;
int tmp;
for (int i = 0; i <= n; i++){
for (int j = start_c - k ; j <= start_c+k; j++){
a = start_r-i;
b = start_r+i;
//That's the square where the player is
//if (a == start_r*N_COLUNAS+start_c)
// continue;
if (j < 0 || j >= N_COLUNAS)
continue;
if (a >= 0 && a < N_LINHAS){
tmp = a*N_COLUNAS+j;
highlight (tmp);
}
if ( b>= 0 && b < N_LINHAS){
tmp = b*N_COLUNAS+j;
highlight (tmp);
}
}
//verifica se s�o linahs contiguas
//linhas horizontais
k--;
}
highlight();
//tabuleiro2[start_r*12+start_c] = 'S';
}
private void highlight (){
for (int i = 0; i < highlights.size(); i++)
quadrados[highlights.get(i)].setUrl(HIGHLIGHT_URL);
}
private void highlight(int i) {
Quadrado q = quadrados[i];
//System.out.println(i +"-"+ q.getUrl());
if (q.getUrl().equals(CAMPO_FULL_URL)){
highlights.push(i);
//System.out.println(i +"-"+ q.getUrl());
q.setUrl(HIGHLIGHT_URL);
}
}
private void clearHighlights() {
System.out.println("Clearing Highlights...");
while (!highlights.isEmpty()){
quadrados[highlights.pop()].setUrl(CAMPO_URL);
}
}
class MoveHandler implements ClickHandler, KeyUpHandler {
@Override
public void onKeyUp(KeyUpEvent event) {
}
@Override
public void onClick(ClickEvent event) {
//System.out.println("Clicaram em mim! "+ (Quadrado)event.getSource());
if (enabled) {
final Quadrado image = (Quadrado) event.getSource();
game.move(image.getNumero(), new AsyncCallback<Void>() {
@Override
public void onSuccess(Void result) {
//System.out.println("\tMovido com sucesso");
// fim da vez. bloquear interface.
//enabled = false;
//System.out.println("\tInterface bloqueada");
}
@Override
public void onFailure(Throwable caught) {
// TODO Auto-generated method stub
}
});
} else {
System.out.println("CLIENTE: Interface est� bloqueada.");
}
}
}
}