/*
 * $Id: menu.cpp,v 1.14 2002/07/22 01:14:14 msell Exp $
 *
 *
 * $Log: menu.cpp,v $
 * Revision 1.14  2002/07/22 01:14:14  msell
 * Lopetussysteemi
 *
 * Revision 1.13  2002/07/21 22:50:39  msell
 * no message
 *
 * Revision 1.12  2002/07/21 20:14:28  msell
 * no message
 *
 * Revision 1.11  2002/07/21 16:37:00  msell
 * no message
 *
 * Revision 1.10  2002/07/19 22:38:37  msell
 * Pingviini
 *
 * Revision 1.9  2002/07/19 14:05:52  msell
 * Damagetextuurit näkyy
 *
 * Revision 1.8  2002/07/19 12:28:29  msell
 * 2D-mode
 *
 * Revision 1.7  2002/07/19 12:10:53  msell
 * Hups
 *
 * Revision 1.6  2002/07/18 23:05:31  msell
 * Partikkelit ja kakkospelaajan liike
 *
 * Revision 1.5  2002/07/17 22:45:54  msell
 * Ääniä vähän
 *
 * Revision 1.4  2002/07/17 20:32:47  msell
 * Detail-optio toimii
 *
 * Revision 1.3  2002/07/17 16:40:33  msell
 * Resoluution vaihto
 *
 * Revision 1.2  2002/07/16 18:55:16  msell
 * Äänet valikkoon
 *
 * Revision 1.1  2002/07/16 17:16:35  msell
 * Fontit ja valikot
 *
 *
 *
 * $Date: 2002/07/22 01:14:14 $
 *
 */

#include "main.h"

#include <math.h>

#include "legoblocks.h"
#include "camera.h"
#include "light.h"
#include "audio.h"
#include "object.h"
#include "appearance.h"
#include "sphere.h"
#include "vector.h" 
#include "collision.h"
#include "utils.h"
#include "graphics.h"
#include "objectfactory.h"
#include "world.h"
#include "3dutils.h"
#include "legoman.h"
#include "font.h"
#include "run.h"
#include "menu.h"
#include "fight.h"

#include "glapi.h"

Camera titlecamera;
Light titlelight;
World *titleworld;

Sound *changesound;
Sound *selectsound;
Sound *menumusic;

bool menuinitialized = false;

void initMenu(void){
	if (!menuinitialized){
		titleworld = new World();
	}

	titlelight.setColor(1, 1, 1);
	titlelight.setSpecular(1, 1, 1);
	titlelight.setPosition(-0.5, BLOCKHEIGHT*16, 0.5);
	titlelight.setAttenuation(0.0, 0.0, 0.01);

	if (!menuinitialized){
		Object *lamp;
		lamp = new Object();
		lamp->appearance = new LampAppearance();
		lamp->setPosition(-0.5, BLOCKHEIGHT*15.5, 0.5);
		titleworld->addChild(lamp);


		//Floor
		BasicBlock *floorblock;

		floorblock = new BasicBlock(33, 1, 5);
		floorblock->setPosition(-0.5, -BLOCKHEIGHT/2.0 + BLOCKHEIGHT*(4*3+1), 0.5-5);
		floorblock->setColor(0, 1, 0);
		titleworld->addChild(floorblock);

		floorblock = new BasicBlock(41, 1, 10);
		floorblock->setPosition(8.5-5, -BLOCKHEIGHT/2.0, 0.5-2.5);
		floorblock->setColor(0, 1, 0);
		titleworld->addChild(floorblock);

		floorblock = new BasicBlock(1, 4*3, 1);
		floorblock->setPosition(-14.5, BLOCKHEIGHT*4*3/2.0, 0.5-5);
		floorblock->setColor(1, 0, 0);
		titleworld->addChild(floorblock);

		floorblock = new BasicBlock(1, 4*3, 1);
		floorblock->setPosition(13.5, BLOCKHEIGHT*4*3/2.0, 0.5-5);
		floorblock->setColor(1, 0, 0);
		titleworld->addChild(floorblock);


		

		//Letters

		//B
		/*int Bsize = 8;
		int Bwidth = 5;
		int Bletter[8][4] = {
			{0, 0, 4, 1},
			{0, 4, 3, 1},
			{0, 8, 4, 1},
			{0, 1, 1, 7},
			//{3, 1, 2, 1},
			{2, 3, 3, 1},
			{2, 5, 3, 1},
			//{3, 7, 2, 1},
			{4, 0, 1, 3},
			{4, 6, 1, 3}};*/
		int Bsize = 10;
		int Bwidth = 5;
		int Bletter[10][4] = {
			{0, 0, 4, 1},
			{0, 4, 4, 1},
			{0, 8, 4, 1},
			{0, 1, 1, 7},
			{3, 1, 2, 1},
			{3, 3, 2, 1},
			{3, 5, 2, 1},
			{3, 7, 2, 1},
			{4, 2, 1, 1},
			{4, 6, 1, 1}};
		
		//l
		int lsize = 2;
		int lwidth = 4;
		int lletter[2][4] = {
			{0, 0, 4, 1},
			{0, 1, 1, 4}};
		
		//o
		int osize = 4;
		int owidth = 4;
		int oletter[4][4] = {
			{0, 0, 4, 1},
			{0, 4, 4, 1},
			{0, 1, 1, 3},
			{3, 1, 1, 3}};
		
		//c
		int csize = 5;
		int cwidth = 4;
		int cletter[5][4] = {
			{0, 0, 4, 1},
			{0, 4, 4, 1},
			{0, 1, 1, 3},
			{3, 1, 1, 1},
			{3, 3, 1, 1}};
	/*		{1, 0, 2, 1},
			{1, 4, 2, 1},
			{0, 1, 1, 3},
			{3, 1, 1, 1},
			{3, 3, 1, 1}};*/
		
		//k
		int ksize = 6;
		int kwidth = 4;
		int kletter[6][4] = {
			{0, 0, 1, 5},
			{1, 2, 2, 1},
			{2, 1, 2, 1},
			{2, 3, 2, 1},
			{3, 0, 1, 1},
			{3, 4, 1, 1}};
	/*		{0, 0, 1, 5},
			{1, 2, 1, 1},
			{2, 1, 1, 1},
			{2, 3, 1, 1},
			{3, 0, 1, 1},
			{3, 4, 1, 1}};*/
		
		//F
		int Fsize = 3;
		int Fwidth = 3;
		int Fletter[3][4] = {
			{0, 0, 1, 7},
			{0, 4, 3, 1},
			{0, 7, 6, 1}};
		
		//i
		int isize = 1;
		int iwidth = 1;
		int iletter[1][4] = {
			{0, 0, 1, 4}};
		
		//g
		int gsize = 5;
		int gwidth = 4;
		int gletter[5][4] = {
			{0, 0, 4, 1},
			{0, 4, 4, 1},
			{0, 1, 1, 3},
			{3, 1, 1, 1},
			{2, 2, 2, 1}};
		
		//h
		int hsize = 3;
		int hwidth = 1;
		int hletter[3][4] = {
			{0, 0, 1, 5},
			{3, 0, 1, 5},
			{0, 2, 4, 1}};
		
		//t
		int tsize = 2;
		int twidth = 4;
		int tletter[2][4] = {
			{3, 0, 1, 6},
			{0, 6, 7, 1}};
		
		//e
		int esize = 5;
		int ewidth = 4;
		int eletter[5][4] = {
			{0, 0, 4, 1},
			{0, 4, 4, 1},
			{0, 2, 3, 1},
			{0, 1, 1, 1},
			{0, 3, 1, 1}};
		
		//r
		int rsize = 6;
		int rwidth = 4;
		int rletter[6][4] = {
			{0, 0, 1, 5},
			{0, 2, 3, 1},
			{0, 4, 3, 1},
			{2, 1, 2, 1},
			{3, 0, 1, 1},
			{2, 3, 2, 1}};
		/*int rsize = 5;
		int rwidth = 4;
		int rletter[5][4] = {
			{0, 0, 1, 5},
			{0, 2, 3, 1},
			{0, 4, 3, 1},
			{3, 0, 1, 2},
			{3, 3, 1, 1}};*/

	#define LETTERCOUNT 6
		int lettersizes[LETTERCOUNT] = {
			Bsize,
			lsize,
			osize,
			csize,
			ksize,
			osize
		};
		int letterwidths[LETTERCOUNT] = {
			Bwidth,
			lwidth,
			owidth,
			cwidth,
			kwidth,
			owidth
		};
		int *letters[LETTERCOUNT] = {
			&Bletter[0][0],
			&lletter[0][0],
			&oletter[0][0],
			&cletter[0][0],
			&kletter[0][0],
			&oletter[0][0]
		};

	#define LETTERCOUNT2 7
		int lettersizes2[LETTERCOUNT2] = {
			Fsize,
			isize,
			gsize,
			hsize,
			tsize,
			esize,
			rsize
		};
		int letterwidths2[LETTERCOUNT2] = {
			Fwidth,
			iwidth,
			gwidth,
			hwidth,
			twidth,
			ewidth,
			rwidth
		};
		int *letters2[LETTERCOUNT2] = {
			&Fletter[0][0],
			&iletter[0][0],
			&gletter[0][0],
			&hletter[0][0],
			&tletter[0][0],
			&eletter[0][0],
			&rletter[0][0]
		};
		BasicBlock *letterblock;

		float z = 0.5;
		int i, j;
		int dx = -15;
		int dy = BLOCKHEIGHT*(4*3+1);
		int dz = -5;
		for (i = 0; i < LETTERCOUNT; i++){
			int size = lettersizes[i];
			int width = letterwidths[i];
			for (j = 0; j < size; j++){
				int x = letters[i][j*4+0];
				int y = letters[i][j*4+1]*3;
				int w = letters[i][j*4+2];
				int h = letters[i][j*4+3]*3;
				letterblock = new BasicBlock(w, h, 1);
				letterblock->setPosition(dx+x+w/2.0, dy+BLOCKHEIGHT*(y+h/2.0), dz+z + randomf(0.1));
				letterblock->setColor(1, 0.5, 1);
				titleworld->addChild(letterblock);
			}
			dx += width + 1;
		}
		dx = -5;
		dy = 0;
		dz = 0;
		for (i = 0; i < LETTERCOUNT2; i++){
			int size = lettersizes2[i];
			int width = letterwidths2[i];
			for (j = 0; j < size; j++){
				int x = letters2[i][j*4+0];
				int y = letters2[i][j*4+1]*3;
				int w = letters2[i][j*4+2];
				int h = letters2[i][j*4+3]*3;
				letterblock = new BasicBlock(w, h, 1);
				letterblock->setPosition(dx+x+w/2.0, dy+BLOCKHEIGHT*(y+h/2.0), dz+z + randomf(0.1));
				//float rotate[3] = {0, randomf(0.1), 0};
				//matrixCreateRotation(letterblock->rotation, rotate);
				letterblock->setColor(1, 0.5, 1);
				titleworld->addChild(letterblock);
			}
			dx += width + 1;
		}



		Object *flower;

		flower = new Object();
		flower->appearance = new FlowerAppearance(FLOWER_RED, FLOWER_WHITE, FLOWER_YELLOW);
		flower->setPosition(-7.5, 0, 1.5);
		titleworld->addChild(flower);

		flower = new Object();
		flower->appearance = new FlowerAppearance(FLOWER_YELLOW, FLOWER_RED, FLOWER_YELLOW);
		flower->setPosition(-11.5, 0, -2.5);
		titleworld->addChild(flower);

		flower = new Object();
		flower->appearance = new FlowerAppearance(FLOWER_WHITE, FLOWER_WHITE, FLOWER_RED);
		flower->setPosition(-14.5, 0, 0.5);
		titleworld->addChild(flower);



		changesound = new Sound(DATAPATH"menuchange.wav");
		selectsound = new Sound(DATAPATH"menuselect.wav");
		menumusic = new Sound(DATAPATH"menu.mp3", true);
	}
	
	titleworld->prepare();

	menuinitialized = true;
}

#define MODEMAIN 0
#define MODEOPTIONS 1

#define MAINSTART 0
#define MAINOPTIONS 1
#define MAINQUIT 2

#define OPTIONSRESOLUTION 0
#define OPTIONSFULLSCREEN 1
#define OPTIONSDETAIL 2
#define OPTIONSRETURN 3

int menuoption = MAINSTART;
int maxoption;
int menumode = MODEMAIN;
bool pressed = false;

float obx1, oby1, obx2, oby2;
float bx1, by1, bx2, by2;
float interpolator = 1.0;

int xres, yres;
int oldresolution;
int resolution = 2;
bool fullscreen = false;
int olddetail;
int detail = 2;

#define RESOLUTIONCOUNT 6
int resolutions[RESOLUTIONCOUNT][2] = {
	{640, 480},
	{800, 600},
	{1024, 768},
	{1280, 960},
	{1280, 1024},
	{1600, 1200}
};

#define DETAILCOUNT 4
char *details[DETAILCOUNT] = {"Off", "Low", "Medium", "High"};

int menurestartcounter = -1;

void menuRestart(void){
	menurestartcounter = 0;
}

void menuMain(void){
	interpolator = 0.0;
	menumode = MODEMAIN;
	menuoption = MAINOPTIONS;
	obx1 = bx1;
	oby1 = by1;
	obx2 = bx2;
	oby2 = by2;
}

float menufade;

int gamestart = 0;

bool loading = true;

void menuStartGame(void){
	menumusic->fadeOut(300);
	gamestart = 200;
	menurestartcounter = -1;
}

void menuStartGame2(void){
	titlelight.setEnabled(false);
	changeGameMode(FIGHTMODE);
	startFight();
	menurestartcounter = -1;
}

void menuOptions(void){
	interpolator = 0.0;
	menumode = MODEOPTIONS;
	menuoption = OPTIONSRESOLUTION;
	obx1 = bx1;
	oby1 = by1;
	obx2 = bx2;
	oby2 = by2;
	oldresolution = resolution;
	olddetail = detail;
}

int quitcounter = -1;

void menuEscPressed(void){
	menurestartcounter = -1;
	//menumusic->stop();
	menumusic->fadeOut(200);
	quitcounter = 0;
}

void menuQuit(void){
	exitProgram(0);
}


void menuResolution(int dir){
	resolution += dir;
	if (resolution < 0) resolution = 0;
	if (resolution >= RESOLUTIONCOUNT) resolution = RESOLUTIONCOUNT-1;
	//resolution = (resolution + RESOLUTIONCOUNT) % RESOLUTIONCOUNT;
}

void calculateMenu(int framecount){
	if (framecount == 1){
		menumusic->setVolume(0);
		menumusic->play();
		menumusic->fadeIn(300);
	}
	if (menurestartcounter != -1){
		menurestartcounter++;
		if (menurestartcounter == 300){
			menumusic->play();
			menumusic->fadeIn(100);
			menurestartcounter = -1;
		}
	}


	menufade = -1;

	titlelight.setEnabled(true);

	if (framecount < 200){
		menufade = 1-framecount/200.0;
	} else{
		loading = false;
	}

	if (gamestart > 0){
		gamestart--;
		if (gamestart == 0){
			menuStartGame2();
		}
		menufade = (200-gamestart)/200.0;
	}

	if (quitcounter != -1){
		menufade = quitcounter/200.0;
		quitcounter++;
		if (quitcounter == 200) menuQuit();
	}

	float cameratarget[3] = {0, 0, 0};
	titlecamera.setPosition(sin(framecount*0.001)*2-8, sin(framecount*0.0033)*2+15, cos(framecount*0.001)*2+25);
	titlecamera.setTarget(cameratarget);

	titleworld->move();

	xres = resolutions[resolution][0];
	yres = resolutions[resolution][1];

	switch(menumode){
		case MODEMAIN:
			maxoption = 2;

			bx1 = 0.03;
			by1 = 0.49;
			bx2 = 0.68;
			by2 = 0.96;

			break;
		case MODEOPTIONS:
			maxoption = 3;

			bx1 = 0.1;
			by1 = 0.3;
			bx2 = 0.9;
			by2 = 0.8;
			break;
	}

	if (interpolator < 1.0){
		interpolator += 0.02;
	} else{
		interpolator = 1.0;
		if (menufade == -1){
			if (keys[SDLK_DOWN]){
				if (!pressed){
					/*if (menuoption < maxoption){
						menuoption++;
						changesound->play();
					}*/
					menuoption = (menuoption + 1)%(maxoption+1);
					changesound->play();
					pressed = true;
				}
			} else if (keys[SDLK_UP]){
				if (!pressed){
					/*if (menuoption > 0){
						menuoption--;
						changesound->play();
					}*/
					menuoption = (menuoption + maxoption)%(maxoption+1);
					changesound->play();
					pressed = true;
				}
			} else if (keys[SDLK_LEFT]){
				if (!pressed){
					switch(menumode){
						case MODEOPTIONS:
							switch(menuoption){
								case OPTIONSRESOLUTION:
									menuResolution(-1);
									break;
								case OPTIONSDETAIL:
									if (detail > 0) detail--;
									break;
							}
							break;
					}
					selectsound->play();
					pressed = true;
				}
			} else if (keys[SDLK_RIGHT]){
				if (!pressed){
					switch(menumode){
						case MODEOPTIONS:
							switch(menuoption){
								case OPTIONSRESOLUTION:
									menuResolution(1);
									break;
								case OPTIONSDETAIL:
									if (detail < DETAILCOUNT-1) detail++;
									break;
							}
							break;
					}
					selectsound->play();
					pressed = true;
				}
			} else if (keys[SDLK_ESCAPE]){
				if (!pressed){
					switch(menumode){
						case MODEMAIN:
							if (menuoption != MAINQUIT){
								menuoption = MAINQUIT;
								changesound->play();
							}
							else menuEscPressed();
							break;
						case MODEOPTIONS:
							selectsound->play();
							resolution = oldresolution;
							detail = olddetail;
							menuMain();
							break;
					}
					pressed = true;
				}
			} else if (keys[SDLK_RETURN]){
				if (!pressed){
					switch(menumode){
						case MODEMAIN:
							switch(menuoption){
								case MAINSTART:
									menuStartGame();
									break;
								case MAINOPTIONS:
									menuOptions();
									break;
								case MAINQUIT:
									menuEscPressed();
									break;
							}
							break;
						case MODEOPTIONS:
							switch(menuoption){
								case OPTIONSRESOLUTION:
									if (resolution != oldresolution) changeResolution(xres, yres, fullscreen);
									oldresolution = resolution;
									break;
								case OPTIONSFULLSCREEN:
									fullscreen = !fullscreen;
									changeResolution(xres, yres, fullscreen);
									break;
								case OPTIONSDETAIL:
									setDetail(detail);
									olddetail = detail;
									break;
								case OPTIONSRETURN:
									if (resolution != oldresolution){
										changeResolution(xres, yres, fullscreen);
										oldresolution = resolution;
									}
									if (detail != olddetail){
										setDetail(detail);
										olddetail = detail;
									}
									menuMain();
									break;
							}
							break;
					}
					selectsound->play();
					pressed = true;
				}
			} else pressed = false;
		}
	}
}

void drawMenu(int framecount){
	//createSkyBox(0, -20, 0, 400, 200, 400);
	createSkyBox(-200, -200, -200, 400, 400, 400);
	glLoadIdentity();
	titlecamera.glUpdate();

	updateLights();
  
	

	titleworld->draw();


	flaretexture->enable();
	titlelight.createFlare();
	flaretexture->disable();


	/*//2D-view
	glDisable(GL_LIGHTING);
	glDisable(GL_CULL_FACE);
	glDisable(GL_DEPTH_TEST);
	glMatrixMode(GL_PROJECTION);
	glPushMatrix();
	glLoadIdentity();
	gluOrtho2D(0, 1, 1, 0);
	glMatrixMode(GL_MODELVIEW);
	glPushMatrix();
	glLoadIdentity();*/
	enable2D();

	glColor3f(1, 1, 1);
	print(0.73, 0.55,
		"Programming:\n" \
		"  Miika Sell\n" \
		"  Juha Kaarlas\n" \
		"\n" \
		"Graphics:\n" \
		"  Miika Sell\n" \
		"  Juha Kaarlas\n" \
		"\n" \
		"Musics:\n" \
		"  Osmand"
		, 0.03);

	print(0.35, 0.965, "http://blockofighter.kicks-ass.net/", 0.02);

	print(0.88, 0.96, "Version 2.0", 0.02);

	tuxtexture->enable();
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glColor3f(1, 1, 1);

	float tuxx = 0.9;
	float tuxy = 0.02;
	float tuxw = 0.1*3/4;
	float tuxh = 0.1;
	glBegin(GL_QUADS);
		glTexCoord2f(0, 0);
		glVertex2f(tuxx, tuxy);

		glTexCoord2f(1, 0);
		glVertex2f(tuxx+tuxw, tuxy);

		glTexCoord2f(1, 1);
		glVertex2f(tuxx+tuxw, tuxy+tuxh);

		glTexCoord2f(0, 1);
		glVertex2f(tuxx, tuxy+tuxh);
	glEnd();
	tuxtexture->disable();

	glColor3f(1, 1, 1);
	print(0.88, 0.12, "supported", 0.02);


	glEnable(GL_BLEND);
	glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
	glColor4f(0, 0, 0, 0.5);
	float x1, y1, x2, y2;
	x1 = (1-interpolator)*obx1 + interpolator*bx1;
	y1 = (1-interpolator)*oby1 + interpolator*by1;
	x2 = (1-interpolator)*obx2 + interpolator*bx2;
	y2 = (1-interpolator)*oby2 + interpolator*by2;
	glBegin(GL_QUADS);
		glVertex2f(x1, y1);
		glVertex2f(x2, y1);
		glVertex2f(x2, y2);
		glVertex2f(x1, y2);
	glEnd();

	if (interpolator == 1.0){
		switch(menumode){
			case MODEMAIN:
				glColor3f(1, 1, 1);
				print(0.05, 0.5, "Start game", 0.1);
				print(0.05, 0.65, "Options", 0.1);
				print(0.05, 0.8, "Quit", 0.1);

				x1 = 0.04;
				x2 = 0.67;
				switch(menuoption){
					case 0:
						y1 = 0.5;
						y2 = 0.65;
						break;
					case 1:
						y1 = 0.65;
						y2 = 0.79;
						break;
					case 2:
						y1 = 0.79;
						y2 = 0.95;
						break;
				}
				break;
			case MODEOPTIONS:
				glColor3f(1, 1, 1);
				char resolutionstring[22];
				sprintf(resolutionstring, "Resolution: %ix%i", xres, yres);
				print(0.12, 0.32, resolutionstring, 0.07);
				print(0.12, 0.42, "Toggle fullscreen", 0.07);
				char detailstring[22];
				sprintf(detailstring, "Detail:     %s", details[detail]);
				print(0.12, 0.52, detailstring, 0.07);
				print(0.12, 0.68, "Save and return", 0.07);

				x1 = 0.11;
				x2 = 0.89;
				switch(menuoption){
					case 0:
						y1 = 0.32;
						y2 = 0.42;
						break;
					case 1:
						y1 = 0.42;
						y2 = 0.52;
						break;
					case 2:
						y1 = 0.52;
						y2 = 0.62;
						break;
					case 3:
						y1 = 0.68;
						y2 = 0.78;
						break;
				}
				break;
		}

		glLineWidth(2);

		glColor4f(sin(framecount*0.04)*0.4+0.6, sin(framecount*0.04)*0.4+0.6, sin(framecount*0.04)*0.4+0.6, 0.5);
		glBegin(GL_LINE_LOOP);
			glVertex2f(x1, y1);
			glVertex2f(x2, y1);
			glVertex2f(x2, y2);
			glVertex2f(x1, y2);
		glEnd();
	}


	if (menufade != -1){
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		glColor4f(0, 0, 0, menufade);
		glBegin(GL_QUADS);
			glVertex2f(0, 0);
			glVertex2f(1, 0);
			glVertex2f(1, 1);
			glVertex2f(0, 1);
		glEnd();
		if (loading){
			glColor4f(menufade, menufade, menufade, menufade);
			print(0.08, 0.4, "Loading...", 0.2);
		}
	}

	disable2D();
	/*//Back to 3D-view
	glPopMatrix();
	glMatrixMode(GL_PROJECTION);
	glPopMatrix();
	glMatrixMode(GL_MODELVIEW);*/
}
