//-----------------------------------------------------//
//
//  Ejemplo de uso de la libreria de USW,
//
//  UnSitioWeb.com para programar juegos
//
//  libUSW (http://UnSitioWeb.com)
//  (cc) 2009 Vicente J. Fdez.
//
//-----------------------------------------------------//

// Definiciones de los recursos.
// El icono de la ventana.
#define IDI_USW		107
// Un tipo de letra que se ha incluido
// como recurso.
#define LETRA_1 109

// Lo mas importante, incluir el fichero de
// cabecera. Su lectura aclara el uso de todas
// las funciones.
#include "uswlib.hpp"

// Creamos el objeto principal de libUSW.
// Lo usaremos continuamente en el programa.
// Desde este momento tendremos una ventana
// de 600x400 y OpenGL inicializado.
// Tambien el gestor de texturas y el objeto
// para escribir en pantalla.
// Los parametro en este caso seran:
// 50 - 		el maximo de texturas cargadas a la vez. Pueden ser menos o mas.
// true - 		habilitamos el uso de la log.
// IDI_USW - 	el identificativo del icono que hemos incluido como
// 				recurso para la ventana.
appUSW ap(50,true,IDI_USW);

// Definimos unos interuptores para gestionar
// algunas teclas con las que haremos cosas.
// El parametro es el "Virtual Key Code" de la
// tecla a controlar.

ControlTeclaUSW tecla_V('V');

ControlTeclaUSW tecla_P('P');

ControlTeclaUSW tecla_R('R');

ControlTeclaUSW tecla_F1(VK_F1);

// Definiremos algunos graficos que presentaremos
// en pantalla.
// Este lo creo y lo cargo a la vez. Ademas se carga desde
// dentro de un fichero ZIP llamado tex.zip.
bmpUSW dibu_logo("usw.png", "tex.zip");
// Este lo creo pero no lo cargo ahora.
bmpUSW dibu_madera;
// Este es un puntero a un dibujo. Habra que crearlo mas tarde
// y al final preocuparnos de borrarlo.
bmpUSW *dibu_nivel;

// Dos variables para usarlas luego.
int dx=300, dy=100;

// Para el id de una textura, el de libUSW no el id de OpenGL.
int textura1;

//--------------------------------------------------------------
// Funcion para inicializar. Luego se la pasaremos al objeto "ap"
// para que la ejecute cuando sea preciso.
void IniciaApp()
{
	glClearColor(0,0,0.4,1.0f);
	// Cargamos los tipos de letra.
	// Esta se carga desde un recurso que hemos añadido a nuestro
	// proyecto (recurso del tipo FONTTEX).
	// Le damos un nombre para luego usarla con el, en este caso
	// "letra1"
	ap.Letra.Carga("letra1", "", "", LETRA_1 );
	// Esta la cargamos desde disco de forma normal.	
	ap.Letra.Carga("letra2", "font/gotica.fnt");
	// Esta se carga desde un fichero zip llamado tex.zip.
	ap.Letra.Carga("letra3", "arial.fnt", "tex.zip");

	// Cargamos las texturas que no hemos cargado todavia.
	// Esta se carga desde un ZIP.
	dibu_madera.carga("mad.png", "tex.zip");
	// En esta creamos el objeto y cargamos el grafico
	// desde disco.
	dibu_nivel = new bmpUSW("dibus/nivel.png");
	
	// Carga de una textura directamente por el gestor de texturas
	// para su uso via bind.
	// el ientificativo que retorna es solo para el gestor de testuras
	// ,no para OpenGL.
	textura1=ap.Tex.Carga("dibus/nubes.jpg");
	
	// Puedo poner la velocidad a lo que quiera.
	ap.PonFPS(300);

	// Envio un mensaje a la log, que para eso la he iniciado.
	ap.Log.Pon("He inicializado\n");


} // Fin IniciaApp

//--------------------------------------------------------------
// Funcion del bucle principal.
void Pinta()
{
	
    
	// Seleccionamos la primera fuente que cargamos, por su nombre.
	ap.Letra.Fuente("letra1");
	// De color blanco
	ap.Letra.Color(1,1,1);
	// 20 pixels de alto.
	ap.Letra.Alto(20);
	// Escribimos en pantalla las coordenadas actuales del raton y de la vez anterior que se
	// puso un boton.
	ap.Letra.Escribe(400,30,"Ratón prev: %i %i", ap.Raton->prev_x, ap.Raton->prev_y );	
	ap.Letra.Escribe(400,50,"     Ratón: %i %i", ap.Raton->x, ap.Raton->y );
    
	// Si presionamos F1 escribiremos los FPS a los que se mueve el programa.
	// Si la presionamos de nuevo, ya no se vera.
	if( tecla_F1.Interruptor() ) ap.Letra.Escribe(400,10,"FPSs: %f", ap.DimeFPS() );
    
	// Si pulsamos la tecla V el programa se vera en una ventana de 700x500
	if( tecla_V.Pulsacion() )   ap.TamVentana(700,500);
	// Si pulsamos la tecla P el programa se pondra en pantalla completa
	if( tecla_P.Pulsacion() )   ap.PantaCompleta();
	// Si pulsamos la tecla R el programa se pondra en pantalla completa y
	// cambiara a 800x600 de resolucion, si puede.
	if( tecla_R.Pulsacion() )
	{
		ap.PantaCompleta(800,600);
		
		// Pongo en la log que he cambiado la resolucion.
		ap.Log.Pon("Cambio de resolucion a %i x %i\n", ap.TamX(), ap.TamY());
	}

	// Cambiamos el tipo de letra, esta vez por indice, a la segunda
	// que cargamos.
 	ap.Letra.Fuente(1);
	// Color amarillo.
	ap.Letra.Color(1,1,0);
 	// Tamaño mas grande, 50.
	ap.Letra.Alto(50);
    
	// Si presiono el boton izquierdo del raton o la tecla Z pongo un clasico
	// mensaje al mundo en la posicion donde este el raton.
	if( ap.Raton->izquierdo || ap.Teclas['Z'] ) 
	{
       	ap.Letra.Escribe(ap.Raton->x, ap.Raton->y, "  Holita mundillo");


		// Aprovecho para pintar algo con OpenGL y ponerle
		// una de las texturas que he cargado.
		// Estas son cosas normales en OpenGL.
		glDisable(GL_LIGHTING);
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		gluPerspective(50.0f, (float)ap.TamX()/(float)ap.TamY(),0.1f, 50.0f);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		glTranslatef(0,0,-3);
		glRotatef ( 90.0, 0.0, 1.0, 0.0 );

		// Habilito texturas, claro.
		glEnable(GL_TEXTURE_2D);
		// Hago bind pero con nuestro gestor de texturas.
		ap.Tex.Bind(textura1);

		// Luego pinto lo que sea, esta vez una bola con GLU.
		glColor3f ( 1.0, 1.0, 1.0 );
		GLUquadricObj* q = gluNewQuadric ( );
		gluQuadricDrawStyle ( q, GLU_FILL );
		gluQuadricNormals ( q, GLU_SMOOTH );
		gluQuadricTexture ( q, GL_TRUE );
		gluSphere (q, 1.0, 20, 20 );
		gluDeleteQuadric ( q );


		// Pongo en pantalla una de las texturas que cargue para
		// ver el caso de un objeto creado con el operador new.
		dibu_nivel->pinta(0,100,200,100);

	}

 	// Pinto el logo en la esquina superior derecha
	dibu_logo.pinta( 10, 10, 300, 75);
	// Pinto el dibujo mad.png en las coordenadas de dx y dy.
	dibu_madera.pinta(dx,dy, 200,300);

	// Cuando suelto el boton central del raton pongo en
	// dx y dy las coordenadas del raton. Esto afectara a la
	// posicion en que se pinta dibu_madera.
	if(ap.Raton->suelto_cen) {dx=ap.Raton->x; dy=ap.Raton->y; }

	// Mareamos un poco mas a dibu_madera.
 	// Moviendo la rueda del raton sube y baja.
	if(ap.Raton->rueda > 0) dy-=5;
	if(ap.Raton->rueda < 0) dy+=5;
	// Con las flechas izquierda y derecha del teclado se mueve
 	// tambien.
 	if(ap.Teclas[VK_RIGHT]) dx+=2;
	if(ap.Teclas[VK_LEFT]) dx-=2;
 	
	// Aparte de la tecla ESCape o el aspa de la ventana, tambien puedo salir del programa
	// con esta funcion. Asociado a pulsar la tela Q y antes pone mensaje.
	if(ap.Teclas['Q'])
	{
		// Cambiamos el tipo de letra, esta vez por nombre, a la tercera
		// que cargamos.
		ap.Letra.Fuente("letra3");
 		// Color rojo.
		ap.Letra.Color(1,0,0);
		// Tamaño mas grande.
		ap.Letra.Alto(60);
		// Doble de ancho
		ap.Letra.Ancho(2);
		// Escribo lo que sea.
		ap.Letra.Escribe(50, 200, "Hasta mañana");
		// Planto lo escrito en pantalla.
		ap.Letra.Pon();
		// Cambio bufferes para que se vea.
		ap.CambiaBuffer();
		// Esperamos 4 segundos.
		Sleep(4000);

		// Fin del programa ordenadamente.
		ap.Terminar();
	}

} // Fin Pinta.


//--------------------------------------------------------------
// Funcion de cierre de programa.
void cierro()
{
	// Borro lo que tengo que borrar.
	delete dibu_nivel;
	
	// Grabo un mensaje en la log. En dos veces para ver la diferencia
	// de terminar con \n o no.
	ap.Log.Pon("Esta vez me he acordado de");
	ap.Log.Pon(" borrar dibu_nivel\n");
}

//------------------------------------------------------------------
// Funcion principal de un programa Windows (como main en C normal, aqui WinMain)
// el prorama empieza a ejecutarse a partir de esta funcion.
int WinMain(HINSTANCE , HINSTANCE ,LPSTR ,int )
{
	// Le indico al objeto principal de la aplicacion
	// cuales son la funciones de inicio, principal y cierre.
	ap.PonFuncionInicia(IniciaApp);
	ap.PonFuncionPrincipal(Pinta);
	ap.PonFuncionCierre(cierro);

	// Ejecuta funcion de inicio y se queda
	// ejecutando la principal hasta terminar
	// el programa por el usuario o por programa.
	// anter de terminar ejecuta la funcio de cierre.
	ap.Corre();
	
	
} // fin WinMain.
//------------------------------------------------------------------