import javax.microedition.amms.control.tuner.TunerControl;
import javax.microedition.midlet.MIDletStateChangeException;

import org.eclipse.ercp.swt.mobile.Command;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Drawable;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;



/**
 * Clase principal de la aplicación.
 * 
 * @author luis
 *
 */
public class Juego extends Main implements SelectionListener , PaintListener, MouseListener {
	
	
	public static int NUM_CUADROS	= 8;
	public static int TAM_CUADRO	= 40;
	public static int MARGEN_X		= 20;
	public static int MARGEN_Y		= 10;
	public static int INSET_X		= 4;
	public static int INSET_Y		= 4;

	private Command 	salir;
	private Command 	nueva;
	
	private Image		fichaHombre;
	private Image		fichaMaquina;
	private Image		fichaHombreGanadora;
	private Image		fichaMaquinaGanadora;
	private Image		tablero;
	private Image		logo;
	
	private	Color		colorFondoTablero;
	private Color		colorLineasTablero;
	private Color		colorTexto;
	private Color		colorFondo;
	
	private Modelo		modelo;
	
	
	private final int 	ESTADO_TURNO_HOMBRE=0;
	private final int	ESTADO_TURNO_MAQUINA=1;
	private final int   ESTADO_GANA_HOMBRE=2;
	private final int	ESTADO_GANA_MAQUINA=3;
	private int			estado=ESTADO_TURNO_HOMBRE;
	
	private int			yFichaBajando=-1;
	private int			xFichaBajando=-1;
	
	public void setXFichaBajando(int fichaBajando) {
		xFichaBajando = fichaBajando;
	}

	public void play() {
		colorFondoTablero=new Color(display, 255,255,255 );
		colorLineasTablero=new Color(display, 0, 0, 0);
		colorTexto=new Color(display, 255,255,255);
		colorFondo=new Color(display, 0, 32, 64);
		
		nueva=new Command(shell,Command.SELECT, 0);
		nueva.addSelectionListener(this);
		nueva.setText("Nueva");
		
		salir=new Command(shell,Command.EXIT, 0);
		salir.addSelectionListener(this);
		salir.setText("Salir");

		shell.addPaintListener(this);
		shell.addMouseListener(this);
		
		fichaHombre=new Image(display, getClass().getResourceAsStream("FichaHombre.png"));
		fichaMaquina=new Image(display, getClass().getResourceAsStream("FichaMaquina.png"));
		fichaHombreGanadora=new Image(display, getClass().getResourceAsStream("FichaHombreGanadora.png"));
		fichaMaquinaGanadora=new Image(display, getClass().getResourceAsStream("FichaMaquinaGanadora.png"));
		tablero=new Image(display, getClass().getResourceAsStream("Tablero.png"));
		logo=new Image(display, getClass().getResourceAsStream("Logo.png"));		
		
		modelo=new Modelo();
		
	}
	
	public void setYFichaBajando(int y) {
		yFichaBajando=y;
	}

	public void widgetDefaultSelected(SelectionEvent arg0) {
	}

	public void widgetSelected(SelectionEvent e) {
		if(e.widget.equals(salir)) {
			try {
				destroyApp(true);
			} catch(MIDletStateChangeException ex) {
				// Nada que hacer.
			}
		} else if(e.widget.equals(nueva)) {
			modelo.limpiar();
			estado=ESTADO_TURNO_HOMBRE;
			shell.redraw();
		}
	}

	public void paintControl(PaintEvent e) {
		if(yFichaBajando < 0) {
			pintarTablero(e.gc);
		}
	}	
	
	private void pintarFichaBajando(GC gc, int tipo) {
		int x=xFichaBajando;
		int y=yFichaBajando;
		
		if(y<NUM_CUADROS-1) {
			gc.setBackground(colorFondoTablero);
			Rectangle rect=new Rectangle(MARGEN_X + x * TAM_CUADRO + INSET_X,
						MARGEN_Y + ( NUM_CUADROS - y - 2) * TAM_CUADRO + INSET_Y,
						TAM_CUADRO-INSET_X*2, TAM_CUADRO-INSET_Y*2);
			gc.fillRectangle(rect);
		}
		Image ficha;
		if(tipo==Modelo.HOMBRE) {
			ficha=fichaHombre;
		} else {
			ficha=fichaMaquina;
		}
		
		gc.drawImage(ficha, MARGEN_X + x * TAM_CUADRO + INSET_X, 
				MARGEN_Y + 
				(NUM_CUADROS - y - 1) * TAM_CUADRO + INSET_Y);		
	}
	
	private void pintarTablero(GC gc) {
		gc.setBackground(colorFondo);
		gc.fillRectangle(display.getBounds());
		gc.drawImage(tablero, 10, 0);
		
		gc.setForeground(colorFondoTablero);
		gc.drawRectangle(MARGEN_X, MARGEN_Y, NUM_CUADROS*TAM_CUADRO, NUM_CUADROS*TAM_CUADRO);
		gc.setForeground(colorLineasTablero);
		for(int i=0; i<=NUM_CUADROS; i++) {
			gc.drawLine(MARGEN_X, 							MARGEN_Y+i*TAM_CUADRO, 
						MARGEN_X+NUM_CUADROS*TAM_CUADRO, 	MARGEN_Y+i*TAM_CUADRO);
			
			gc.drawLine(MARGEN_X+i*TAM_CUADRO, 				MARGEN_Y,
						MARGEN_X+i*TAM_CUADRO,				MARGEN_Y+NUM_CUADROS*TAM_CUADRO);
		}
		
		for(int x=0; x<NUM_CUADROS; x++) {
			for(int y=0; y<NUM_CUADROS; y++) {
				int tipo=modelo.get(x,y);
				switch(tipo) {
					case Modelo.HOMBRE:
						ponerFicha(gc, fichaHombre, x, y);
						break;
					case Modelo.HOMBRE_GANADORA:
						ponerFicha(gc, fichaHombreGanadora, x, y);
						break;
					case Modelo.MAQUINA:
						ponerFicha(gc, fichaMaquina, x, y);
						break;
					case Modelo.MAQUINA_GANADORA:
						ponerFicha(gc, fichaMaquinaGanadora, x, y);
						break;
				}
			}
		}	
		
		String mensaje=null;
		switch(estado) {
			case ESTADO_TURNO_HOMBRE:
				mensaje="Tú Juegas";
				break;
			case ESTADO_TURNO_MAQUINA:
				mensaje="Estoy pensando";
				break;
			case ESTADO_GANA_HOMBRE:
				mensaje="¡ Enhorabuena, has ganado !";
				break;
			case ESTADO_GANA_MAQUINA:
				mensaje="¡ Gana la máquina !";
				break;
		}
		gc.setForeground(colorTexto);
		gc.drawString(mensaje, MARGEN_X * 2, 420, true);
		gc.drawImage(logo, 0, 480);
	}
	
	private void ponerFicha(GC gc, Image tipo, int x, int y) {
		if(tipo==null) {
			return;
		}
		gc.drawImage(tipo, MARGEN_X + x * TAM_CUADRO + INSET_X, 
							MARGEN_Y + 
							(NUM_CUADROS - y - 1) * TAM_CUADRO + INSET_Y);
	}

	public void mouseDoubleClick(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	public void mouseDown(MouseEvent arg0) {
		// TODO Auto-generated method stub
		
	}
	
	public void juegaMaquina() {
		int x=modelo.JuegaMaquina();
		if(x>=0) {
			display.syncExec(new PonedorFicha(this, x, Modelo.MAQUINA));
		}
		if(modelo.cuatroEnRaya()) {
			estado=ESTADO_GANA_MAQUINA;
		} else {
			estado=ESTADO_TURNO_HOMBRE;
		}
		shell.redraw();						
	}
		
	public void mouseUp(MouseEvent evento) {
		if(estado != ESTADO_TURNO_HOMBRE) {
			return;
		}
		int x= (evento.x - MARGEN_X) / TAM_CUADRO;
		int y= (evento.y - MARGEN_Y) / TAM_CUADRO;
		if(x>=0 && x<NUM_CUADROS && y>=0 && y<NUM_CUADROS && modelo.hayLibre(x)) {
			display.syncExec(new PonedorFicha(this, x, Modelo.HOMBRE));			
			modelo.addHombre(x);			
			if(modelo.cuatroEnRaya()) {
				estado=ESTADO_GANA_HOMBRE;
				shell.redraw();
			} else {
				estado=ESTADO_TURNO_MAQUINA;
				shell.redraw();	
				display.asyncExec(new Pensador(this));
				
			}

		}		
	}

	class PonedorFicha implements Runnable {
		private Juego juego;
		private int	  x;
		private int   tipoFicha;
		public PonedorFicha(Juego juego, int x, int tipoFicha) {
			this.juego=juego;
			this.x=x;
			this.tipoFicha=tipoFicha;
		}
		public void run() {
			GC gc=new GC(juego.shell);
			int y=juego.modelo.libre(x);
			juego.setXFichaBajando(x);
			int tiempo=50;
			for(int yActual=NUM_CUADROS-1; yActual>=y; yActual--) {
				try { Thread.sleep(tiempo); } catch(Exception e) {}
				juego.setYFichaBajando(yActual);
				juego.pintarFichaBajando(gc, tipoFicha);
				tiempo-=10;
			}
			juego.setYFichaBajando(-1);
			gc.dispose();
		}
	}
	
	class Pensador implements Runnable {
		
		private Juego juego;
		
		Pensador(Juego juego) {
			this.juego=juego;
		}

		public void run() {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// 	Nada que hacer
			}
			juego.juegaMaquina();			
		}
	}
	
}

