/*
Solar Conquest
Copyright (C) 2006 Greg Beaman

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

//#include "stdafx.h"

#include <SDL.h>
#include <SDL_opengl.h>
#include <vorbis/vorbisfile.h>
#include <vorbis/vorbisenc.h>
//#include <SDL_mixer.h>
#include <SDL_image.h>
//#include <GL/glaux.h>

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <iostream>
#include <fstream>
//#include <time.h>
//#include <sys/time.h>

#include "Debug.h"
//#include "VoiceSystem.h"

//normal frame calc
#define TIME_METHOD_1
//get time of day
//#define TIME_METHOD_2
//clump of frames
//#define TIME_METHOD_3

#define MAX_STRING_SIZE 256
#define MAX_TEXTVALUE_SIZE 2048
#define MAX_STARS 100

#define RADAR_RADIUS 75

#define NUM_TEAMS 3
#define STATISTICS_MODE
#define SHIP_DEBRIS_DETAIL 200

#define GAME_SCREEN_MENU 1
#define GAME_SCREEN_EMPIRE 2
#define GAME_SCREEN_ACTION 3

#define VIEW_MODE_LOCK 0
#define VIEW_MODE_FOLLOW 1
#define VIEW_MODE_COUNT 1

SDL_Surface* screen = NULL;
Uint32 lastFrame;
float elapsedTime;
bool paused;
bool progRunning;

bool g_fullscreen;
int g_resolution;
float g_gameSpeed;
bool g_soundEnabled;

int g_screenWidth;
int g_screenHeight;
int g_screenDepth;
bool g_updateResolution;
int g_curScreen;
int g_numBackgrounds;

int input_speed, input_turn, input_view,input_strafe;
bool left_mouse_click, right_mouse_click;
bool input_fire;
bool input_view_lastFrame;
bool input_mapView;
int view_mode = VIEW_MODE_LOCK;
int ObjectCount[NUM_TEAMS];

bool starsLoaded = false;
GLuint stars;
bool radarLoaded = false;
GLuint radar;

int g_alliedFighterCarriers;
int g_alliedBomberCarriers;
int g_alliedAdvFighterCarriers;
int g_alliedAdvBomberCarriers;
int g_alliedDestroyers;
int g_enemyFighterCarriers;
int g_enemyBomberCarriers;
int g_enemyAdvFighterCarriers;
int g_enemyAdvBomberCarriers;
int g_enemyDestroyers;
int g_level;

#include "Common.h"
Vector cameraPos;

#include "TextureList.h"
#include "SoundList.h"
#include "Model.h"
#include "WireText.h"
CBitmapFont* g_MainFont = NULL;
CTextureListNode* g_curBackground = NULL;

#include "Map.h"

//#include "Planet.h"
#include "Particles.h"
#include "ProjectileData.h"
#include "Projectile.h"
#include "ObjectData.h"
#include "Object.h"
#include "Factory.h"
//#include "Fleet.h"
#include "AISystem.h"
//#include "CommonSolarSystem.h"
#include "LevelFunctions.h"

#include "MenuScreen.h"
#include "ActionScreen.h"
//#include "EmpireScreen.h"

void InitializeScreens()
{
	//Create menu screens
	g_respawnScreen = new CMenuScreen();
	if (g_respawnScreen)
	{
		//Button IDs match data IDs
		float center = g_screenWidth/2 - ((strlen("Adv. Fighter") * (FONT_SIZE_X + FONT_SPACING) + 12) + (strlen("Adv. Bomber") * (FONT_SIZE_X + FONT_SPACING) + 12) + 5)/2;
		g_respawnScreen->AddText(0, g_screenWidth/2 - (strlen("Choose your ship") * (FONT_SIZE_X + FONT_SPACING))/2,g_screenHeight/2 - FONT_SIZE_Y - 2, "Choose your ship");
		g_respawnScreen->AddButton(4, center,g_screenHeight/2, "Adv. Fighter");
		g_respawnScreen->AddButton(6, center + (strlen("Adv. Fighter") * (FONT_SIZE_X + FONT_SPACING) + 12) + 5,g_screenHeight/2, "Adv. Bomber");
	}

	g_victoryScreen = new CMenuScreen();
	if (g_victoryScreen)
	{
		//Button IDs match data IDs
		float center = g_screenWidth/2 - ((strlen("Main Menu") * (FONT_SIZE_X + FONT_SPACING) + 12) + (strlen("Continue") * (FONT_SIZE_X + FONT_SPACING) + 12) + 5)/2;
		g_victoryScreen->AddText(0, g_screenWidth/2 - (strlen("Victory") * (FONT_SIZE_X + FONT_SPACING))/2,g_screenHeight/2 - FONT_SIZE_Y - 2, "Victory");
		g_victoryScreen->AddButton(1, center,g_screenHeight/2, "Main Menu");
		g_victoryScreen->AddButton(2, center + (strlen("Main Menu") * (FONT_SIZE_X + FONT_SPACING) + 12) + 5,g_screenHeight/2, "Continue");
	}

	g_defeatScreen = new CMenuScreen();
	if (g_defeatScreen)
	{
		//Button IDs match data IDs
		float center = g_screenWidth/2 - ((strlen("Main Menu") * (FONT_SIZE_X + FONT_SPACING) + 12) + (strlen("Restart") * (FONT_SIZE_X + FONT_SPACING) + 12) + 5)/2;
		g_defeatScreen->AddText(0, g_screenWidth/2 - (strlen("Defeat") * (FONT_SIZE_X + FONT_SPACING))/2,g_screenHeight/2 - FONT_SIZE_Y - 2, "Defeat");
		g_defeatScreen->AddButton(1, center,g_screenHeight/2, "Main Menu");
		g_defeatScreen->AddButton(2, center + (strlen("Main Menu") * (FONT_SIZE_X + FONT_SPACING) + 12) + 5,g_screenHeight/2, "Restart");
	}

	g_escapeScreen = new CMenuScreen();
	if (g_escapeScreen)
	{
		float center = g_screenWidth/2 - ((strlen("Return To Game") * (FONT_SIZE_X + FONT_SPACING) + 12))/2;
		float ycenter = g_screenHeight/2;
		float yfactor = FONT_SIZE_Y+14;
		g_escapeScreen->AddButton(1, center,ycenter-yfactor*2, "Return To Game");
		g_escapeScreen->AddButton(2, center,ycenter-yfactor, "Information   ");
		g_escapeScreen->AddButton(3, center,ycenter, "Edit Options  ");
		g_escapeScreen->AddButton(4, center,ycenter+yfactor, "Main Menu     ");
		g_escapeScreen->AddButton(5, center,ycenter+yfactor*2, "Exit Game     ");

		g_escapeScreen->menuFunction = UpdateEscapeMenu;
	}

	g_mainMenuScreen = new CMenuScreen();
	if (g_mainMenuScreen)
	{
		float center = g_screenWidth/2 - ((strlen("solar conquest") * (FONT_SIZE_X + FONT_SPACING) + 12))/2;
		g_mainMenuScreen->AddText(0, center, g_screenHeight/2-FONT_SIZE_Y/2, "solar conquest");

		float width = ((strlen("Load Level") * (FONT_SIZE_X + FONT_SPACING) + 12)) + 5;
		float yfactor = FONT_SIZE_Y+14;
		g_mainMenuScreen->AddButton(1,width,g_screenHeight-yfactor,  "New Game  ");
		g_mainMenuScreen->AddButton(5,width*2,g_screenHeight-yfactor,"Skirmish  ");
		g_mainMenuScreen->AddButton(2,width*3,g_screenHeight-yfactor,"Load Level");
		g_mainMenuScreen->AddButton(3,width*4,g_screenHeight-yfactor,"Options   ");
		g_mainMenuScreen->AddButton(4,width*5,g_screenHeight-yfactor,"Exit Game ");

		g_mainMenuScreen->menuFunction = UpdateMainMenu;
	}

	g_difficultyMenuScreen = new CMenuScreen();
	if (g_difficultyMenuScreen)
	{
		float width = ((strlen("Cancel") * (FONT_SIZE_X + FONT_SPACING) + 12)) + 5;
		float yfactor = FONT_SIZE_Y+14;
		g_difficultyMenuScreen->AddButton(1,width,g_screenHeight-yfactor,  "Easy  ");
		g_difficultyMenuScreen->AddButton(2,width*2,g_screenHeight-yfactor,"Medium");
		g_difficultyMenuScreen->AddButton(3,width*3,g_screenHeight-yfactor,"Hard  ");
		g_difficultyMenuScreen->AddButton(4,width*4,g_screenHeight-yfactor,"Stress");
		g_difficultyMenuScreen->AddButton(5,width*5,g_screenHeight-yfactor,"Cancel");

		g_difficultyMenuScreen->menuFunction = UpdateDifficultyMenu;
	}

	g_optionsMenuScreen = new CMenuScreen();
	if (g_optionsMenuScreen)
	{
		float center = g_screenWidth/2 - ((strlen("Sound: Disabled") * (FONT_SIZE_X + FONT_SPACING) + 12))/2;
		float rbpos = center + ((strlen("Sound: Disabled") * (FONT_SIZE_X + FONT_SPACING) + 6));
		float lbpos = center - ((strlen("<") * (FONT_SIZE_X + FONT_SPACING) + 12));
		float ycenter = g_screenHeight/2;
		float yfactor = FONT_SIZE_Y+14;

		CMenuItem* item;
		char text[MAX_STRING_SIZE];

		float width = (4*(FONT_SIZE_X+FONT_SPACING) + 14);
		float resPos = g_screenWidth/2 - width*1.5;
		item = g_optionsMenuScreen->AddTextBox(1, resPos, ycenter-yfactor*2, 4);
		if (item)
		{
			sprintf(text,"%d",g_screenWidth);
			item->SetText(text);
		}
		item = g_optionsMenuScreen->AddTextBox(2, resPos + width, ycenter-yfactor*2, 4);
		if (item)
		{
			sprintf(text,"%d",g_screenHeight);
			item->SetText(text);
		}
		item = g_optionsMenuScreen->AddTextBox(100, resPos + width*2, ycenter-yfactor*2, 2);
		if (item)
		{
			sprintf(text,"%d",g_screenDepth);
			item->SetText(text);
		}

		g_optionsMenuScreen->AddButton(3, lbpos-5,ycenter-yfactor, "<");
		g_optionsMenuScreen->AddText(101,center,ycenter-yfactor + 6,"Windowed");
		g_optionsMenuScreen->AddButton(4, rbpos,ycenter-yfactor, ">");

		g_optionsMenuScreen->AddButton(5, lbpos-5,ycenter, "<");
		g_optionsMenuScreen->AddText(102,center,ycenter + 6,"Sound: Disabled");
		g_optionsMenuScreen->AddButton(6, rbpos,ycenter, ">");

		g_optionsMenuScreen->AddButton(7, lbpos-5,ycenter+yfactor, "<");
		g_optionsMenuScreen->AddText(103,center,ycenter+yfactor + 6,"Speed: 1.0");
		g_optionsMenuScreen->AddButton(8, rbpos,ycenter+yfactor, ">");

		center = g_screenWidth/2 - ((strlen("Back To Menu") * (FONT_SIZE_X + FONT_SPACING) + 12))/2;
		g_optionsMenuScreen->AddButton(9, center,ycenter+yfactor*2, "Back To Menu");

//		center = g_screenWidth/2 - ((strlen("Notice: Resolution changes require program restart.") * (FONT_SIZE_X + FONT_SPACING) + 12))/2;
//		g_optionsMenuScreen->AddText(0,center,ycenter+yfactor*3 + 6,"Notice: Resolution changes require program restart.");

		UpdateOptionsMenuText();
		g_optionsMenuScreen->menuFunction = UpdateOptionsMenu;
	}

	g_empireInfoScreen = new CMenuScreen();
	if (g_empireInfoScreen)
	{
		float center = g_screenWidth/2 - ((strlen("Back To Menu") * (FONT_SIZE_X + FONT_SPACING) + 12))/2;
		g_empireInfoScreen->AddButton(1, center,g_screenHeight/2, "Back To Menu");

		g_empireInfoScreen->AddText(0, 0, (FONT_SIZE_Y+3)*3, "This screen is used to manage your empire. This is not yet complete, as this is the Combat Beta.");
		g_empireInfoScreen->AddText(0, 0, (FONT_SIZE_Y+3)*4, "You can move around the map by using the arrow keys.");

		g_empireInfoScreen->AddText(0, 0, (FONT_SIZE_Y+3)*6, "At the moment, you may select fleets by clicking on one from your team.");
		g_empireInfoScreen->AddText(0, 0, (FONT_SIZE_Y+3)*7, "To select a fleet, click on one of the blue U shaped objects.");
		g_empireInfoScreen->AddText(0, 0, (FONT_SIZE_Y+3)*8, "After selecting a fleet, you may tell it to attack another fleet by click on a red planet or fleet.");
		g_empireInfoScreen->AddText(0, 0, (FONT_SIZE_Y+3)*9, "You may also move the fleet around by clicking on the map.");
		g_empireInfoScreen->AddText(0, 0,(FONT_SIZE_Y+3)*10, "You can merge with another fleet by clicking on a fleet from your team.");
		g_empireInfoScreen->AddText(0, 0,(FONT_SIZE_Y+3)*11, "You may deselect the fleet by right clicking.");

		g_empireInfoScreen->menuFunction = UpdateInfoMenu;
	}

	g_actionInfoScreen = new CMenuScreen();
	if (g_actionInfoScreen)
	{
		float center = g_screenWidth/2 - ((strlen("Back To Menu") * (FONT_SIZE_X + FONT_SPACING) + 12))/2;
		g_actionInfoScreen->AddButton(1, center,g_screenHeight/2, "Back To Menu");

		g_actionInfoScreen->AddText(0, 0, (FONT_SIZE_Y+3)*10, "Use your mouse to point where you want your ship to go. You can hold down the left mouse");
		g_actionInfoScreen->AddText(0, 0, (FONT_SIZE_Y+3)*11, "button to fire. W and S keys will accelerate and decelerate your ship. A and D keys");
		g_actionInfoScreen->AddText(0, 0, (FONT_SIZE_Y+3)*12, "will move your ship sideways. If you get lost, you can hold down the tab key for a");
		g_actionInfoScreen->AddText(0, 0, (FONT_SIZE_Y+3)*13, "map of the area.");

		g_actionInfoScreen->menuFunction = UpdateInfoMenu;
	}

	g_planetControlScreen = new CMenuScreen();
	if (g_planetControlScreen)
	{
		float width = ((strlen("Close") * (FONT_SIZE_X + FONT_SPACING) + 12)) + 5;
		float yfactor = FONT_SIZE_Y+14;
		g_planetControlScreen->AddButton(1,g_screenWidth/2-width/2,g_screenHeight/2+100,"Close");

		width = strlen("Power Consumption: 999999") * (FONT_SIZE_X+FONT_SPACING);
		float xpos;
		float ypos = g_screenHeight/2-50;
		xpos = (g_screenWidth/2 + width/2) - (strlen("Power Usage") * (FONT_SIZE_X+FONT_SPACING))/2;
		g_planetControlScreen->AddText(0, xpos, ypos-FONT_SIZE_Y-2, "Power Usage");

		xpos = g_screenWidth/2;
		g_planetControlScreen->AddBarChart(2, xpos,ypos, width,100);
		g_planetControlScreen->AddText(3, xpos, ypos+100+2, "Power Generation: ");
		g_planetControlScreen->AddText(4, xpos, ypos+100+2+(FONT_SIZE_Y+2), "Power Consumption: ");
		g_planetControlScreen->AddText(5, xpos, ypos+100+2+(FONT_SIZE_Y+2)*2, "Resource Rate: ");
		g_planetControlScreen->AddText(6, xpos, ypos+100+2+(FONT_SIZE_Y+2)*3, "Resources: ");

		xpos = (g_screenWidth/2 - width/2) - (strlen("Work Force") * (FONT_SIZE_X+FONT_SPACING))/2;
		g_planetControlScreen->AddText(0, xpos, ypos-FONT_SIZE_Y-2, "Work Force");
		xpos = g_screenWidth/2 - width;
		g_planetControlScreen->AddBarChart(7, xpos,ypos, width,100);
		g_planetControlScreen->AddText( 8, xpos, ypos+100+2, "Population: ");
		g_planetControlScreen->AddText( 9, xpos, ypos+100+2+(FONT_SIZE_Y+2), "Housing: ");
		g_planetControlScreen->AddText(10, xpos, ypos+100+2+(FONT_SIZE_Y+2)*2, "Producers: ");
		g_planetControlScreen->AddText(11, xpos, ypos+100+2+(FONT_SIZE_Y+2)*3, "Defenders: ");
		g_planetControlScreen->AddText(12, xpos, ypos+100+2+(FONT_SIZE_Y+2)*4, "Economic: ");

		g_planetControlScreen->AddButton(20,xpos,ypos-(FONT_SIZE_Y+6)*3,"Housing");
		width = ((strlen("Housing") * (FONT_SIZE_X + FONT_SPACING) + 12)) + 5;
		g_planetControlScreen->AddButton(21,xpos+width,ypos-(FONT_SIZE_Y+6)*3,"Producer");
		width += ((strlen("Producer") * (FONT_SIZE_X + FONT_SPACING) + 12)) + 5;
		g_planetControlScreen->AddButton(22,xpos+width,ypos-(FONT_SIZE_Y+6)*3,"Defender");
		width += ((strlen("Defender") * (FONT_SIZE_X + FONT_SPACING) + 12)) + 5;
		g_planetControlScreen->AddButton(23,xpos+width,ypos-(FONT_SIZE_Y+6)*3,"Power");

		width = strlen("Buy") * (FONT_SIZE_X + FONT_SPACING);
		g_planetControlScreen->AddText(0,g_screenWidth/2-width/2,ypos-(FONT_SIZE_Y+6)*4,"Buy");

//		g_planetControlScreen->menuFunction = UpdatePlanetControlScreen;
	}

	g_skirmishScreen = new CMenuScreen();
	if (g_skirmishScreen)
	{
		float center = g_screenWidth/2;
		float ycenter = g_screenHeight/2;
		float yfactor = FONT_SIZE_Y+14;
		float width;
		CMenuItem* item;

		g_alliedFighterCarriers = 4;
		g_alliedBomberCarriers = 4;
		g_enemyFighterCarriers = 4;
		g_enemyBomberCarriers = 4;

		width = strlen("Allied Fighter Carriers: ") * (FONT_SIZE_X+FONT_SPACING);
		g_skirmishScreen->AddText(0,center-width,ycenter-yfactor*2 + 6,"Allied Fighter Carriers: ");
		item = g_skirmishScreen->AddTextBox(1, center + FONT_SIZE_X+FONT_SPACING, ycenter-yfactor*2, 4);
		if (item)
			sprintf(item->caption,"%d",g_alliedFighterCarriers);

		width = strlen("Allied Bomber Carriers: ") * (FONT_SIZE_X+FONT_SPACING);
		g_skirmishScreen->AddText(0,center-width,ycenter-yfactor + 6,"Allied Bomber Carriers: ");
		item = g_skirmishScreen->AddTextBox(2, center + FONT_SIZE_X+FONT_SPACING, ycenter-yfactor, 4);
		if (item)
			sprintf(item->caption,"%d",g_alliedBomberCarriers);

		width = strlen("Enemy Fighter Carriers: ") * (FONT_SIZE_X+FONT_SPACING);
		g_skirmishScreen->AddText(0,center-width,ycenter + 6,"Enemy Fighter Carriers: ");
		item = g_skirmishScreen->AddTextBox(3, center + FONT_SIZE_X+FONT_SPACING, ycenter, 4);
		if (item)
			sprintf(item->caption,"%d",g_enemyFighterCarriers);

		width = strlen("Enemy Bomber Carriers: ") * (FONT_SIZE_X+FONT_SPACING);
		g_skirmishScreen->AddText(0,center-width,ycenter+yfactor + 6,"Enemy Bomber Carriers: ");
		item = g_skirmishScreen->AddTextBox(4, center + FONT_SIZE_X+FONT_SPACING, ycenter+yfactor, 4);
		if (item)
			sprintf(item->caption,"%d",g_enemyBomberCarriers);


		width = ((strlen("Start") * (FONT_SIZE_X + FONT_SPACING) + 12)) + 5;
		g_skirmishScreen->AddButton(10,width,g_screenHeight-yfactor,"Start");
		g_skirmishScreen->AddButton(9,width*2,g_screenHeight-yfactor,"Exit");

		g_skirmishScreen->menuFunction = UpdateSkirmishScreen;
	}

	g_introScreen = new CMenuScreen();
	if (g_introScreen)
	{
		float width;
		width = strlen("Start") * (FONT_SIZE_X+FONT_SPACING) + 12;
		g_introScreen->AddButton(1, g_screenWidth-width, g_screenHeight - (FONT_SIZE_Y+14), "Start");
		/*
		It is the year 2054. A corporation known as AeonTech had launched a voyage to a previously\n
		unreachable solar system. This marked a milestone in space technology. At this point in time,\n
		fleets were sent with large ships capable of producing smaller, AI operated ships, that\n
		could handle tasks and keep the fleet going. This expedition was to push such technology to\n
		the limit, forcing it to keep a human crew of 500 alive, and transport them far from Earth.\n
		\n\n
		The crew reached the new solar system. Immediately, research began on these new worlds, and\n
		snapshots of the planets were sent back to Earth. However, at the same time, Admrial Moretti\n
		was taking advantage of the distance from Earth, and slowly using the AI to increase his power\n
		and enforce his rule.\n
		\n\n
		Then one day, the Admrial declared Marshal Law, and declared the solar system to be part of\n
		the "Morettian Empire". To keep others in line, Moretti hand picked a few of the crew members\n
		and executed them under charges of treason. He locked the scientists up and had them research\n
		military applications for the new materials on these planets.\n
		\n\n
		Not long after that, a distress call was sent back to Earth. A small amount of the crew also\n
		hijacked some carriers, and planned to start a rebellion.\n
		\n\n
		AeonTech and the Earth Space Forces are preparing to launch a rescue party. However, it\n
		will be a few months before they arrive. The rebellion must do everything they can to\n
		keep the Admrial in check, and to survive until the rescue party arrives...
		*/
		g_introScreen->AddBigText(2,0,0,"It is the year 2054. A corporation known as AeonTech had launched a voyage to a previously\nunreachable solar system. This marked a milestone in space technology. At this point in time,\nfleets were sent with large ships capable of producing smaller, AI operated ships, that\ncould handle tasks and keep the fleet going. This expedition was to push such technology to\nthe limit, forcing it to keep a human crew of 500 alive, and transport them far from Earth.\n\n\nThe crew reached the new solar system. Immediately, research began on these new worlds, and\nsnapshots of the planets were sent back to Earth. However, at the same time, Admrial Moretti\nwas taking advantage of the distance from Earth, and slowly using the AI to increase his power\nand enforce his rule.\n\n\nThen one day, the Admrial declared Marshal Law, and declared the solar system to be part of\nthe \"Morettian Empire\". To keep others in line, Moretti hand picked a few of the crew members\nand executed them under charges of treason. He locked the scientists up and had them research\nmilitary applications for the new materials on these planets.\n\n\nNot long after that, a distress call was sent back to Earth. A small amount of the crew also\nhijacked some carriers, and planned to start a rebellion.\n\n\nAeonTech and the Earth Space Forces are preparing to launch a rescue party. However, it\nwill be a few months before they arrive. The rebellion must do everything they can to\nkeep the Admrial in check, and to survive until the rescue party arrives...");

		g_introScreen->menuFunction = UpdateIntroScreen;
	}

	g_loadLevelScreen = new CMenuScreen();
	if (g_loadLevelScreen)
	{
		float yfactor = FONT_SIZE_Y+14;
		g_loadLevelScreen->AddButton(1,0,0,         "Mission 1: Enlistment               ");
		g_loadLevelScreen->AddButton(2,0,yfactor,   "Mission 2: Violent Minority         ");
		g_loadLevelScreen->AddButton(3,0,yfactor*2, "Mission 3: Life of a Vulture        ");
		g_loadLevelScreen->AddButton(4,0,yfactor*3, "Mission 4: Dance of Death           ");
		g_loadLevelScreen->AddButton(5,0,yfactor*4, "Mission 5: Bit the hand that fed you");

		g_loadLevelScreen->AddButton(100, g_screenWidth-(strlen("Exit") * (FONT_SIZE_X+FONT_SPACING) + 12), g_screenHeight - (FONT_SIZE_Y+14), "Exit");

		g_loadLevelScreen->menuFunction = UpdateLoadLevelScreen;
	}
}

bool SetScreenSize(int width, int height, int colors)
{
	printf("Updating resolution: %d %d %d\n",width,height,colors);

	if (g_fullscreen)
		screen = SDL_SetVideoMode(width,height,colors,SDL_OPENGL | SDL_FULLSCREEN | SDL_RESIZABLE);
	else
		screen = SDL_SetVideoMode(width,height,colors,SDL_OPENGL | SDL_RESIZABLE);

	if (screen == NULL)
		return false;

	glViewport(0,0,width,height);
	
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0, width, height, 0, -1, 1);
	
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	
	g_screenWidth = screen->w;
	g_screenHeight = screen->h;

	//Clean up all the old stuff
	if (radarLoaded)
	{
		glDeleteLists(radar,1);
		radarLoaded = false;
	}
	if (starsLoaded)
	{
		glDeleteLists(stars,1);
		starsLoaded = false;
	}
	DestroyScreens();

	//Recreate all the screen-size dependent stuff
	DebugMessage(3,"Generating stars");
	stars = glGenLists(1);
	glNewList(stars,GL_COMPILE);
	glBegin(GL_POINTS);
		{
		for (int i=0; i < MAX_STARS; i++)
		{
			int color = rand()%5;
			if (color == 0)
				glColor4f(1,1,1,1);
			else if (color == 1)
				glColor4f(1,1,0,1);
			else if (color == 2)
				glColor4f(0,1,0,1);
			else if (color == 3)
				glColor4f(1,1,1,1);
			else if (color == 4)
				glColor4f(1,0,1,1);
			glVertex2f(rand()%g_screenWidth,rand()%g_screenHeight);
		}
		}
	glEnd();
	glEndList();
	if (checkGLError() == GL_NO_ERROR)
		starsLoaded = true;
	else
		starsLoaded = false;
	
	DebugMessage(3,"Generating radar");
	
	radar = glGenLists(1);
	glNewList(radar,GL_COMPILE);
		int circleDepth = 30;
		//Draw the main circle
		glDisable(GL_BLEND);
	//	glColor4f(0,0,0.5,0.5);
		glColor4f(0,0,0.3,0.5);
		glBegin(GL_TRIANGLE_FAN);
			glVertex2f((RADAR_RADIUS),16+RADAR_RADIUS);
			{
			for (int i=0; i <= circleDepth; i++)
				glVertex2f((RADAR_RADIUS)+(sin(i*ToRadians(360/circleDepth))*RADAR_RADIUS),(16+RADAR_RADIUS)+(cos(i*ToRadians(360/circleDepth))*RADAR_RADIUS));
			}
		glEnd();

		glEnable(GL_BLEND);
		glColor4f(0,0,0.3,0.5);
	//	glColor4f(0,0,0.5,1.0);
		//Draw inner circles and south strip
		glBegin(GL_LINE_STRIP);
	//		glColor4f(0,0,0,0);
	//		glVertex2f(RADAR_RADIUS,g_screenHeight-RADAR_RADIUS);
			float radius = RADAR_RADIUS+2;
			{
			for (int z=1; z <= 5; z++)
			{
				for (int i=0; i <= circleDepth; i++)
				{
					glVertex2f((RADAR_RADIUS)+(sin(i*ToRadians(360/circleDepth))*((radius/5)*z)),(16+RADAR_RADIUS)+(cos(i*ToRadians(360/circleDepth))*((radius/5)*z)));
				}
			}
			}
		glEnd();
		glBegin(GL_LINE_STRIP);
	//		glColor4f(0,0,0,0);
	//		glVertex2f(RADAR_RADIUS,g_screenHeight-RADAR_RADIUS);
			radius = RADAR_RADIUS-2;
			{
			for (int z=1; z <= 5; z++)
			{
				for (int i=0; i <= circleDepth; i++)
				{
					glVertex2f((RADAR_RADIUS)+(sin(i*ToRadians(360/circleDepth))*((radius/5)*z)),(16+RADAR_RADIUS)+(cos(i*ToRadians(360/circleDepth))*((radius/5)*z)));
				}
			}
			}
		glEnd();
		//Draw rest of strips
		glBegin(GL_LINES);
			glVertex2f((RADAR_RADIUS)+(sin(ToRadians(-47))*RADAR_RADIUS),(16+RADAR_RADIUS)+(cos(ToRadians(-47))*RADAR_RADIUS));
			glVertex2f((RADAR_RADIUS)+(sin(ToRadians(133))*RADAR_RADIUS),(16+RADAR_RADIUS)+(cos(ToRadians(133))*RADAR_RADIUS));
			glVertex2f((RADAR_RADIUS)+(sin(ToRadians(-43))*RADAR_RADIUS),(16+RADAR_RADIUS)+(cos(ToRadians(-43))*RADAR_RADIUS));
			glVertex2f((RADAR_RADIUS)+(sin(ToRadians(137))*RADAR_RADIUS),(16+RADAR_RADIUS)+(cos(ToRadians(137))*RADAR_RADIUS));
		
			glVertex2f((RADAR_RADIUS)+(sin(ToRadians(47))*RADAR_RADIUS),(16+RADAR_RADIUS)+(cos(ToRadians(47))*RADAR_RADIUS));
			glVertex2f((RADAR_RADIUS)+(sin(ToRadians(-133))*RADAR_RADIUS),(16+RADAR_RADIUS)+(cos(ToRadians(-133))*RADAR_RADIUS));
			glVertex2f((RADAR_RADIUS)+(sin(ToRadians(43))*RADAR_RADIUS),(16+RADAR_RADIUS)+(cos(ToRadians(43))*RADAR_RADIUS));
			glVertex2f((RADAR_RADIUS)+(sin(ToRadians(-137))*RADAR_RADIUS),(16+RADAR_RADIUS)+(cos(ToRadians(-137))*RADAR_RADIUS));
		
			glVertex2f((RADAR_RADIUS)+(sin(ToRadians(-2))*RADAR_RADIUS),(16+RADAR_RADIUS)+(cos(ToRadians(-2))*RADAR_RADIUS));
			glVertex2f((RADAR_RADIUS)+(sin(ToRadians(182))*RADAR_RADIUS),(16+RADAR_RADIUS)+(cos(ToRadians(182))*RADAR_RADIUS));
			glVertex2f((RADAR_RADIUS)+(sin(ToRadians(2))*RADAR_RADIUS),(16+RADAR_RADIUS)+(cos(ToRadians(2))*RADAR_RADIUS));
			glVertex2f((RADAR_RADIUS)+(sin(ToRadians(178))*RADAR_RADIUS),(16+RADAR_RADIUS)+(cos(ToRadians(178))*RADAR_RADIUS));
		
			glVertex2f((RADAR_RADIUS)+(sin(ToRadians(-92))*RADAR_RADIUS),(16+RADAR_RADIUS)+(cos(ToRadians(-92))*RADAR_RADIUS));
			glVertex2f((RADAR_RADIUS)+(sin(ToRadians(92))*RADAR_RADIUS),(16+RADAR_RADIUS)+(cos(ToRadians(92))*RADAR_RADIUS));
			glVertex2f((RADAR_RADIUS)+(sin(ToRadians(-88))*RADAR_RADIUS),(16+RADAR_RADIUS)+(cos(ToRadians(-88))*RADAR_RADIUS));
			glVertex2f((RADAR_RADIUS)+(sin(ToRadians(88))*RADAR_RADIUS),(16+RADAR_RADIUS)+(cos(ToRadians(88))*RADAR_RADIUS));
		glEnd();

		glDisable(GL_BLEND);
		//Draw inner circles and south strip as black
		glBegin(GL_LINE_STRIP);
	//		glColor4f(0,0,1,0.2);
			glColor4f(0,0,0,0);
	//		glColor4f(0,0,0,0);
	//		glVertex2f(RADAR_RADIUS,g_screenHeight-RADAR_RADIUS);
			{
			for (int z=1; z <= 5; z++)
			{
				for (int i=0; i <= circleDepth; i++)
				{
					glVertex2f((RADAR_RADIUS)+(sin(i*ToRadians(360/circleDepth))*((RADAR_RADIUS/5)*z)),(16+RADAR_RADIUS)+(cos(i*ToRadians(360/circleDepth))*((RADAR_RADIUS/5)*z)));
				}
			}
			}
		glEnd();
		//Draw rest of strips as black
		glBegin(GL_LINES);
			glColor4f(0,0,0,0.2);
			glVertex2f((RADAR_RADIUS)+(sin(ToRadians(-45))*RADAR_RADIUS),(16+RADAR_RADIUS)+(cos(ToRadians(-45))*RADAR_RADIUS));
			glVertex2f((RADAR_RADIUS)+(sin(ToRadians(135))*RADAR_RADIUS),(16+RADAR_RADIUS)+(cos(ToRadians(135))*RADAR_RADIUS));
		
			glVertex2f((RADAR_RADIUS)+(sin(ToRadians(45))*RADAR_RADIUS),(16+RADAR_RADIUS)+(cos(ToRadians(45))*RADAR_RADIUS));
			glVertex2f((RADAR_RADIUS)+(sin(ToRadians(-135))*RADAR_RADIUS),(16+RADAR_RADIUS)+(cos(ToRadians(-135))*RADAR_RADIUS));
		
			glVertex2f((RADAR_RADIUS),(16+RADAR_RADIUS));
			glVertex2f((RADAR_RADIUS)+(sin(3.14)*RADAR_RADIUS),(16+RADAR_RADIUS)+(cos(3.14)*RADAR_RADIUS));
		
			glVertex2f((RADAR_RADIUS)+(sin(-3.14/2)*RADAR_RADIUS),(16+RADAR_RADIUS)+(cos(-3.14/2)*RADAR_RADIUS));
			glVertex2f((RADAR_RADIUS)+(sin(3.14/2)*RADAR_RADIUS),(16+RADAR_RADIUS)+(cos(3.14/2)*RADAR_RADIUS));
		glEnd();
		glEnable(GL_BLEND);
	/*	//Draw inner circles and south strip
		glBegin(GL_LINE_STRIP);
	//		glColor4f(0,0,1,0.2);
			glColor4f(0,0,0.5,0.5);
	//		glColor4f(0,0,0,0);
	//		glVertex2f(RADAR_RADIUS,g_screenHeight-RADAR_RADIUS);
			for (z=2; z <= 5; z++)
			{
				float radius = RADAR_RADIUS-2;
				for (int i=0; i <= circleDepth; i++)
				{
					glVertex2f(RADAR_RADIUS+(sin(i*ToRadians(360/circleDepth))*((radius/5)*z)),(g_screenHeight-RADAR_RADIUS)+(cos(i*ToRadians(360/circleDepth))*((radius/5)*z)));
				}
			}
		glEnd();
*/
	glEndList();
	if (checkGLError() == GL_NO_ERROR)
		radarLoaded = true;
	else
		radarLoaded = false;

	InitializeScreens();

	if (g_curScreen == GAME_SCREEN_MENU)
		g_curMenuScreen = g_mainMenuScreen;
	else
		g_curMenuScreen = g_escapeScreen;

	printf("Finished resizing screen\n");
	g_updateResolution = false;
	return true;
}

void init()
{
	input_speed = 0;
	input_strafe = 0;
	input_turn = 0;
	input_view = 0;
	input_view_lastFrame = false;
	input_fire = false;
	left_mouse_click = false;
	right_mouse_click = false;
	paused = false;

//	g_MainVoice = new CVoiceSystem();
	
	DebugMessage(3,"Creating sound list");
	g_soundList = new CSoundList();
	if (g_soundList)
	{
		DebugMessage(4,"-Loading Fighter_Fire.wav");
		g_soundList->AddSound(1,"sounds/Fighter_Fire.wav");
		DebugMessage(4,"-Loading Missile_Fire.wav");
		g_soundList->AddSound(2,"sounds/Missile_Fire.wav");
		DebugMessage(4,"-Loading AutoRifleFire.wav");
		g_soundList->AddSound(3,"sounds/AutoRifleFire.wav");
	}
	
	DebugMessage(3,"Creating texture list");
	glEnable(GL_TEXTURE_2D);
	
	g_textureList = new CTextureList();
#ifdef LIGHT_VERSION
	g_textureList->AddTexture(1,"images/explosion.png",IMAGE_TYPE_PNG);
#else
	g_textureList->AddTexture(1,"images/explosion_detailed.png",IMAGE_TYPE_PNG);
#endif
/*	g_textureList->AddTexture(100,"images/backgrounds/404-spacesun.bmp",IMAGE_TYPE_BMP);
	g_textureList->AddTexture(101,"images/backgrounds/cosmic_planet_born_1024.bmp",IMAGE_TYPE_BMP);
	g_textureList->AddTexture(102,"images/backgrounds/little3_pollutedcosmo_1024.bmp",IMAGE_TYPE_BMP);
	g_textureList->AddTexture(103,"images/backgrounds/warren_icebound_1024.bmp",IMAGE_TYPE_BMP);
*/
	g_numBackgrounds = 0;

	DebugMessage(3,"Creating particle list");
	g_particles = new CParticleList();
	if (g_particles)
		g_particles->SetupCache();
	checkGLError();
	
	DebugMessage(3,"Creating font");
	g_MainFont = new CBitmapFont("images/fonts/smallfont.bmp");
	checkGLError();

	DebugMessage(3,"Creating map");
	g_Map = new CMap();
//	g_Map->LoadMap("Maps/Main.txt");
	
	glDisable(GL_TEXTURE_2D);

	srand(SDL_GetTicks());
	
	DebugMessage(3,"Creating projectile data");
	CProjectileData* pData;
	//Fighter bullet
	pData = AddProjectileData(1);
	if (pData)
	{
		pData->lifeTime = 6.0;
		pData->fireDelay = 0.5; //0.2
		pData->maxSpeed = 800.0; //800
		pData->strafeSpeed = 0.0;
		pData->turnRate = 0.0;
		pData->radius = 8;
		pData->type = PROJECTILE_TYPE_BULLET;
		pData->damage = 1;
		pData->colorR = 1;
		pData->colorG = 1;
		pData->colorB = 0;
		pData->colorA = 1.0;
		
		if (g_soundList)
			pData->sound = g_soundList->FindNode(1);
	}
	
	//Bomber rocket
	pData = AddProjectileData(2);
	if (pData)
	{
		pData->lifeTime = 3.0;
		pData->fireDelay = 2.0; //1.0
		pData->maxSpeed = 600.0; //1000
		pData->strafeSpeed = 0.0;
		pData->turnRate = 0.0;
		pData->radius = 8;
		pData->type = PROJECTILE_TYPE_SMALLROCKET;
		pData->damage = 4;
		pData->colorR = 1;
		pData->colorG = 1;
		pData->colorB = 0;
		pData->colorA = 1.0;
	
		if (g_soundList)
			pData->sound = g_soundList->FindNode(2);
	}
	
	//Sniper Laser
	pData = AddProjectileData(3);
	if (pData)
	{
		pData->lifeTime = 6.0;
		pData->fireDelay = 0.2; //0.5
		pData->maxSpeed = 1000.0;
		pData->strafeSpeed = 0.0;
		pData->turnRate = 0.0;
		pData->radius = 8;
		pData->type = PROJECTILE_TYPE_LASER;
		pData->damage = 5;
		pData->colorR = 1;
		pData->colorG = 1;
		pData->colorB = 0;
		pData->colorA = 1.0;
	}
	
	//Repair laser
	pData = AddProjectileData(4);
	if (pData)
	{
		pData->lifeTime = 6.0;
		pData->fireDelay = 0.5;
		pData->maxSpeed = 800.0;
		pData->strafeSpeed = 0.0;
		pData->turnRate = 0.0;
		pData->radius = 8;
		pData->type = PROJECTILE_TYPE_LASER;
		pData->damage = -1;
		pData->colorR = 0;
		pData->colorG = 1;
		pData->colorB = 1;
		pData->colorA = 1.0;
	}
	
	//Air Superority Fighter Plasma bolt
	pData = AddProjectileData(5);
	if (pData)
	{
		pData->lifeTime = 6.0;
		pData->fireDelay = 0.2;
		pData->maxSpeed = 1000.0;
		pData->strafeSpeed = 0.0;
		pData->turnRate = 0.0;
		pData->radius = 8;
		pData->type = PROJECTILE_TYPE_PLASMA;
		pData->damage = 4;
		pData->colorR = 0;
		pData->colorG = 1;
		pData->colorB = 1;
		pData->colorA = 0.8;
	
		if (g_soundList)
			pData->sound = g_soundList->FindNode(3);
	}
	
	//Serpent Plasma rocket
	pData = AddProjectileData(6);
	if (pData)
	{
		pData->lifeTime = 3.0;
		pData->fireDelay = 1.0; //2.0
		pData->maxSpeed = 600.0; //1000
		pData->strafeSpeed = 100.0;
		pData->turnRate = 0;
//		pData->turnRate = ToRadians(1)*100;
		pData->radius = 8;
		pData->type = PROJECTILE_TYPE_ROCKET;
		pData->damage = 10;
		pData->colorR = 0;
		pData->colorG = 1;
		pData->colorB = 1;
		pData->colorA = 1.0;
	
		if (g_soundList)
			pData->sound = g_soundList->FindNode(2);
	}

	//Flak Shell
	pData = AddProjectileData(7);
	if (pData)
	{
		pData->lifeTime = 6.0;
		pData->fireDelay = 0.2; //0.5
		pData->maxSpeed = 800.0; //800
		pData->strafeSpeed = 0.0;
		pData->turnRate = 0.0;
		pData->radius = 8;
		pData->type = PROJECTILE_TYPE_FLAK;
		pData->damage = 5;
		pData->colorR = 1;
		pData->colorG = 1;
		pData->colorB = 0;
		pData->colorA = 1.0;
	}

	//Seeker rocket
	pData = AddProjectileData(8);
	if (pData)
	{
		pData->lifeTime = 3.0; //3.0
		pData->fireDelay = 0.5; //1.0
		pData->maxSpeed = 400.0; //600
		pData->strafeSpeed = 0.0;
		pData->turnRate = ToRadians(5)*100;
		pData->radius = 8;
		pData->type = PROJECTILE_TYPE_ROCKET;
		pData->lockonProjectile = true;
		pData->damage = 4;
		pData->colorR = 1;
		pData->colorG = 1;
		pData->colorB = 0;
		pData->colorA = 1.0;
	
		if (g_soundList)
			pData->sound = g_soundList->FindNode(2);
	}

	DebugMessage(3,"Creating object data");
	CModel* model;
	CObjectData* cData;
	//Fighter
	cData = AddObjectData(1);
	if (cData)
	{
		cData->maxHealth = 15;
		cData->acceleration = 1000;
		cData->maxSpeed = 500; //500
//		cData->strafeSpeed = 100;
		cData->strafeSpeed = 300;
		cData->width = 10;
		cData->height = 10;
		cData->radius = 12;
		cData->type = OBJ_TYPE_FIGHTER;
		cData->turnRate = ToRadians(5)*100;
		cData->projectile = FindProjectileData(1);
		cData->attackRange = 300;
	}
	
	//Bomber
	cData = AddObjectData(2);
	if (cData)
	{
		cData->maxHealth = 30;
		cData->acceleration = 200;
		cData->maxSpeed = 200; //200
		cData->strafeSpeed = 100;
		cData->width = 12;
		cData->height = 12;
		cData->radius = 40;
		cData->type = OBJ_TYPE_BOMBER;
		cData->turnRate = ToRadians(1)*100;
		cData->projectile = FindProjectileData(2);
		cData->attackRange = 300;
	}

	//Repair turret
	cData = AddObjectData(100);
	if (cData)
	{
		cData->maxHealth = 50;
		cData->acceleration = 0;
		cData->maxSpeed = 0;
		cData->strafeSpeed = 0;
		cData->width = 2;
		cData->height = 2;
		cData->radius = 2;
		cData->type = OBJ_TYPE_REPAIRTURRET;
		cData->turnRate = ToRadians(1)*100;
		cData->projectile = FindProjectileData(4);
		cData->attackRange = 800;
	}
	
	//Repair ship
	cData = AddObjectData(3);
	if (cData)
	{
		cData->maxHealth = 5;
		cData->acceleration = 200;
		cData->maxSpeed = 200;
		cData->strafeSpeed = 100;
		cData->width = 12;
		cData->height = 12;
		cData->radius = 20;
		cData->type = OBJ_TYPE_REPAIRSHIP;
		cData->turnRate = ToRadians(1)*100;
		cData->projectile = FindProjectileData(4);
		cData->turret = FindObjectData(100);
		cData->attackRange = 300;
	}
	
	//Advanced Fighter
	cData = AddObjectData(4);
	if (cData)
	{
		model = new CModel();
		if (model)
			model->LoadModel("shapes/advancedfighter.txt");
		cData->model = model;

		cData->maxHealth = 100;
		cData->acceleration = 1000;
		cData->maxSpeed = 600;
		cData->strafeSpeed = 600;
		cData->width = 10;
		cData->height = 10;
		cData->radius = 12;
		cData->type = OBJ_TYPE_ADV_FIGHTER;
		cData->turnRate = ToRadians(5)*100;
		cData->projectile = FindProjectileData(5);
		cData->attackRange = 300;
	}
	
	//Carrier turret
	cData = AddObjectData(5);
	if (cData)
	{
		model = new CModel();
		if (model)
			model->LoadModel("shapes/laserturret.txt");
		cData->model = model;

		cData->maxHealth = 100; //50
		cData->acceleration = 0;
		cData->maxSpeed = 0;
		cData->strafeSpeed = 0;
		cData->width = 10;
		cData->height = 10;
		cData->radius = 10;
		cData->type = OBJ_TYPE_IMMOBILE_TURRET;
		cData->turnRate = ToRadians(1)*100;
		cData->projectile = FindProjectileData(3);
		cData->attackRange = 500; //1000
	}

	//Advanced Bomber
	cData = AddObjectData(6);
	if (cData)
	{
		model = new CModel();
		if (model)
			model->LoadModel("shapes/advancedbomber.txt");
		cData->model = model;

		cData->maxHealth = 200; //100
		cData->acceleration = 800; //1000
		cData->maxSpeed = 400; //600
		cData->strafeSpeed = 200; //400
		cData->width = 20;
		cData->height = 20;
		cData->radius = 20;
		cData->type = OBJ_TYPE_ADV_BOMBER;
		cData->turnRate = ToRadians(5)*100;
		cData->projectile = FindProjectileData(6);
		cData->attackRange = 300;
	}

	//Flak turret
	cData = AddObjectData(7);
	if (cData)
	{
		model = new CModel();
		if (model)
			model->LoadModel("shapes/laserturret.txt");
		cData->model = model;

		cData->maxHealth = 100; //50
		cData->acceleration = 0;
		cData->maxSpeed = 0;
		cData->strafeSpeed = 0;
		cData->width = 10;
		cData->height = 10;
		cData->radius = 10;
		cData->type = OBJ_TYPE_IMMOBILE_TURRET;
		cData->turnRate = ToRadians(1)*100;
		cData->projectile = FindProjectileData(7);
		cData->attackRange = 800;
	}

	//Destroyer Seeker turret
	cData = AddObjectData(8);
	if (cData)
	{
		model = new CModel();
		if (model)
			model->LoadModel("shapes/laserturret.txt");
		cData->model = model;

		cData->maxHealth = 100; //50
		cData->acceleration = 0;
		cData->maxSpeed = 0;
		cData->strafeSpeed = 0;
		cData->width = 10;
		cData->height = 10;
		cData->radius = 10;
		cData->type = OBJ_TYPE_IMMOBILE_TURRET;
		cData->turnRate = ToRadians(1)*100;
		cData->projectile = FindProjectileData(8);
		cData->attackRange = 500; //1000
	}

	//Fighter with Laser
	cData = AddObjectData(9);
	if (cData)
	{
		cData->maxHealth = 15;
		cData->acceleration = 1000;
		cData->maxSpeed = 500; //500
//		cData->strafeSpeed = 100;
		cData->strafeSpeed = 300;
		cData->width = 10;
		cData->height = 10;
		cData->radius = 12;
		cData->type = OBJ_TYPE_FIGHTER;
		cData->turnRate = ToRadians(5)*100;
		cData->projectile = FindProjectileData(3);
		cData->attackRange = 500;
	}

	//Capital ship (Aircraft Carrier)
	cData = AddObjectData(200);
	if (cData)
	{
		model = new CModel();
		if (model)
			model->LoadModel("shapes/aircraftcarrier.txt");
		cData->model = model;

		cData->maxHealth = 1000; //2000, 200
		cData->acceleration = 0;
		cData->maxSpeed = 0;
		cData->strafeSpeed = 0;
		cData->width = 30;
		cData->height = 30;
		cData->radius = 35;
		cData->type = OBJ_TYPE_CAPITALSHIP;
		cData->turnRate = 0;
		cData->projectile = NULL;
	}

	//Capital ship (Destroyer)
	cData = AddObjectData(201);
	if (cData)
	{
		model = new CModel();
		if (model)
			model->LoadModel("shapes/destroyer.txt");
		cData->model = model;

		cData->maxHealth = 1000; //2000, 200
		cData->acceleration = 0;
		cData->maxSpeed = 0;
		cData->strafeSpeed = 0;
		cData->width = 30;
		cData->height = 30;
		cData->radius = 35;
		cData->type = OBJ_TYPE_CAPITALSHIP;
		cData->turnRate = 0;
		cData->projectile = NULL;
	}

	//Capital ship (Turret Station)
	cData = AddObjectData(202);
	if (cData)
	{
		model = new CModel();
		if (model)
			model->LoadModel("shapes/turretstation.txt");
		cData->model = model;

		cData->maxHealth = 2000;
		cData->acceleration = 0;
		cData->maxSpeed = 0;
		cData->strafeSpeed = 0;
		cData->width = 30;
		cData->height = 30;
		cData->radius = 35;
		cData->type = OBJ_TYPE_CAPITALSHIP;
		cData->turnRate = 0;
		cData->projectile = NULL;
	}

	//Capital ship (Space Station)
	cData = AddObjectData(203);
	if (cData)
	{
		model = new CModel();
		if (model)
			model->LoadModel("shapes/spacestation.txt");
		cData->model = model;

		cData->maxHealth = 2000;
		cData->acceleration = 0;
		cData->maxSpeed = 0;
		cData->strafeSpeed = 0;
		cData->width = 30;
		cData->height = 30;
		cData->radius = 35;
		cData->type = OBJ_TYPE_CAPITALSHIP;
		cData->turnRate = 0;
		cData->projectile = NULL;
	}

	g_curScreen = GAME_SCREEN_MENU;
	g_introState = 1;
	g_curMenuScreen = g_introScreen;

/*	DebugMessage(3,"Placing player");
	CObject* obj;
	obj = AddObject(FindObjectData(4));
	if (obj)
	{
		obj->SetState(OBJ_STATE_PLAYER);
		obj->SetPosition(0,0);
		obj->SetTeam(1);
		obj->SetHealth(obj->GetHealth());
		playerObject = obj;
	}
	else
		playerObject = NULL;
		
	DebugMessage(3,"Placing other objects");
/*
	for (int i=0; i < 200; i++)
	{
		obj = AddObject(FindObjectData((rand()%2)+1));
		obj->SetPosition((rand()%500)*10,(rand()%500)*10);
		obj->SetTeam((rand()%2)+1);
	}
*/
/*
	CFactory* factory;
//	for (int i=0; i < 100; i++)
	for (int i=50; i < 100; i++)
	{
//		for (int z=0; z < 10; z++)
		for (int z=0; z < 1; z++)
		{
			factory = AddFactory();
			if (factory)
			{
				factory->team = 1;
				if (rand()%10 == 1)
					factory->obj = 3;
				else
					factory->obj = (rand()%2)+1;
				factory->position = CreateVector(100+(i*80),5000-(z*80));
			}
			
			if (factory)
			{
				factory = AddFactory();
				factory->team = 2;
				if (rand()%10 == 1)
					factory->obj = 3;
				else
					factory->obj = (rand()%2)+1;
				factory->position = CreateVector(100+(i*80),(z*80));
			}
		}
	}
*/
//	g_MainVoice->Speak(L"Command system online.");
}

void Cleanup()
{
	DeleteAllObjects();
	DeleteAllObjectData();
	DeleteAllFactories();
	DeleteAllProjectiles();
	DeleteAllProjectileData();

	if (radarLoaded)
	{
		glDeleteLists(radar,1);
		radarLoaded = false;
	}
	if (starsLoaded)
	{
		glDeleteLists(stars,1);
		starsLoaded = false;
	}

	if (g_particles)
		delete g_particles;
	g_particles = NULL;
		
	if (g_MainFont)
		delete g_MainFont;
	g_MainFont = NULL;

	if (g_Map)
		delete g_Map;
	g_Map = NULL;

	if (g_textureList)
		delete g_textureList;
	g_textureList = NULL;
	
#ifdef ENABLE_PROFILING
	if (g_profile)
		delete g_profile;
	g_profile = NULL;
#endif

	if (g_soundList)
		delete g_soundList;
	g_soundList = NULL;
	
	DestroyScreens();

//	if (g_MainVoice)
//		delete g_MainVoice;
//	g_MainVoice = NULL;

//	if (screen)
//		SDL_FreeSurface(screen);
	SDL_Quit();
}

void Update()
{
	if (g_updateResolution)
	{
		bool success = SetScreenSize(g_screenWidth,g_screenHeight,g_screenDepth);
		if (!success)
		{
			printf("ERROR WITH NEW SCREEN RESOLUTION\n");
			progRunning = false;
		}
		printf("Continuing program...\n");
	}

	Uint32 curFrame = SDL_GetTicks();
	float realElapsedTime = ( (curFrame-lastFrame) );
	if (realElapsedTime > 0)
	{
		elapsedTime = (float)(realElapsedTime / 1000);
		elapsedTime *= g_gameSpeed;
		lastFrame = curFrame;
		UpdateFPS();

		if (g_curMenuScreen)
		{
			if (g_curMenuScreen->menuFunction)
			{
				paused = true;
				g_curMenuScreen->menuFunction();
			}
		}

		if (paused)
			elapsedTime = 0;
		
		if (g_curScreen == GAME_SCREEN_ACTION)
			UpdateActionScreen();
	}
}

void DrawScene()
{
	glClear(GL_COLOR_BUFFER_BIT);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	
	if (g_curScreen == GAME_SCREEN_ACTION)
		DrawActionScreen();
	else if (g_curScreen != GAME_SCREEN_MENU)
	{
		if (g_MainFont)
		{
			g_MainFont->Enable();
			g_MainFont->RenderText(0,0,1,1,"Unknown game screen");
			g_MainFont->Disable();
		}
	}
	else
	{
		if (starsLoaded)
			glCallList(stars);
	}

//	glBlendFunc(GL_SRC_ALPHA,GL_ONE);

	if (g_curMenuScreen)
	{
		glLineWidth(1);
		g_curMenuScreen->DrawMenuScreen();
		g_curMenuScreen->DrawMenuScreenText();
		glLineWidth(2);
	}
	
//	glFlush();
	SDL_GL_SwapBuffers();

	glClear(0); //This may be stopping a memory leak....
}

int main(int argc, char **argv)
{
#ifdef NO_SOUND
	if (SDL_Init(SDL_INIT_VIDEO) < 0)
#else
	if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0)
#endif
	{
//		cout << "ERROR: Could not init SDL " << SDL_GetError() << "\n";
		DebugMessage(1,"Could not initialize SDL video");
		return 1;
	}

#ifdef ENABLE_PROFILING
	g_profile = new CProfiler();
#endif

	LoadGameSettings();

	if (!SetScreenSize(g_screenWidth,g_screenHeight,g_screenDepth))
//	if (!SetScreenSize(1024,768,32))
	{
//		cout << "ERROR: Could not set video mode (640x480x32) " << SDL_GetError() << "\n";
		DebugMessage(1,"Could not set resolution");
		Cleanup();
		return 1;
	}
	SDL_WM_SetCaption("Solar Conquest",NULL);
	
#ifdef STATISTICS_MODE
	printf("Memory statistics:\n");
	printf("-Object size: %d\n", sizeof(CObject));
	printf("-Projectile size: %d\n", sizeof(CProjectile));
	printf("-Factory size: %d\n", sizeof(CFactory));
	printf("-Particle size: %d\n", sizeof(CParticleNode));
#endif

	DebugMessage(2,"Tweaking OpenGL settings");
	glClearColor(0,0,0,1);
	glDisable(GL_LIGHTING);
	glDisable(GL_DEPTH_TEST);
	glDisable(GL_TEXTURE_2D);
	glDisable(GL_CULL_FACE);
	
	//Rendering hints, may wish to toy with for FPS reasons
/*	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
	glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
	glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
*/
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
	glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST);
	glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
	
	glLineWidth(2);

	glEnable(GL_BLEND);
//	glBlendFunc(GL_ONE_MINUS_SRC_ALPHA,GL_ONE_MINUS_DST_COLOR);
	glBlendFunc(GL_SRC_ALPHA,GL_DST_ALPHA);
//	glBlendFunc(GL_SRC_ALPHA,GL_ONE);

	DebugMessage(2,"OpenGL options have been set, initializing game");
	init();
	DebugMessage(2,"Initialization complete");
	
	progRunning = true;
	lastFrame = SDL_GetTicks();
	
	while (progRunning)
	{
		SDL_Event event;

		while ( SDL_PollEvent(&event) )
		{
			if (event.type == SDL_QUIT)
				progRunning = false;

			else if (event.type == SDL_KEYDOWN)
			{
				if (g_curScreen == GAME_SCREEN_EMPIRE)
				{
					if (event.key.keysym.sym == SDLK_UP)
						input_speed = 1;
					else if (event.key.keysym.sym == SDLK_DOWN)
						input_speed = -1;
					else if (event.key.keysym.sym == SDLK_LEFT)
						input_turn = -1;
					else if (event.key.keysym.sym == SDLK_RIGHT)
						input_turn = 1;
				}
//					else if (event.key.keysym.sym == SDLK_v)
//						input_view = 1;
				else
				{
					if (event.key.keysym.sym == SDLK_w)
						input_speed = 1;
					else if (event.key.keysym.sym == SDLK_s)
						input_speed = -1;
					else if (event.key.keysym.sym == SDLK_a)
						input_strafe = 1;
					else if (event.key.keysym.sym == SDLK_d)
						input_strafe = -1;
					else if (event.key.keysym.sym == SDLK_LCTRL)
						input_fire = true;
				}
				if (event.key.keysym.sym == SDLK_TAB)
					input_mapView = true;
			}
		
			else if (event.type == SDL_KEYUP)
			{
				if (event.key.keysym.sym == SDLK_ESCAPE)
				{
					if (!g_curMenuScreen && g_curScreen != GAME_SCREEN_MENU)
					{
						if (g_escapeScreen)
							g_curMenuScreen = g_escapeScreen;
						else
							progRunning = false;
					}
				}

				if (g_curScreen == GAME_SCREEN_EMPIRE)
				{
					if (event.key.keysym.sym == SDLK_UP)
						input_speed = 0;
					else if (event.key.keysym.sym == SDLK_DOWN)
						input_speed = 0;
					else if (event.key.keysym.sym == SDLK_LEFT)
						input_turn = 0;
					else if (event.key.keysym.sym == SDLK_RIGHT)
						input_turn = 0;
				}
//				else if (event.key.keysym.sym == SDLK_v)
//					input_view = 0;
				else
				{
					if (event.key.keysym.sym == SDLK_w)
						input_speed = 0;
					else if (event.key.keysym.sym == SDLK_s)
						input_speed = 0;
					else if (event.key.keysym.sym == SDLK_a)
						input_strafe = 0;
					else if (event.key.keysym.sym == SDLK_d)
						input_strafe = 0;
					else if (event.key.keysym.sym == SDLK_LCTRL)
						input_fire = false;
				}
				if (event.key.keysym.sym == SDLK_TAB)
					input_mapView = false;

				if (g_curMenuScreen)
				{
					if (g_curMenuScreen->selectedItem)
					{
						CTextBox* textBox = (CTextBox*)g_curMenuScreen->selectedItem;
						textBox->OnChar(event.key.keysym.sym);
					}
				}
#ifdef ENABLE_PROFILING
				if (event.key.keysym.sym == SDLK_SPACE)
				{
					LARGE_INTEGER freq;
					QueryPerformanceFrequency(&freq);
					int i = 0;
				}
#endif
			}
		
			else if (event.type == SDL_MOUSEBUTTONDOWN)
			{
				if (g_curMenuScreen)
				{
				}
				else if (g_curScreen == GAME_SCREEN_ACTION)
				{
					if (event.button.button == SDL_BUTTON_LEFT)
						input_fire = true;
//					else if (event.button.button == SDL_BUTTON_RIGHT)
//						input_speed = -1;
				}
			}
		
			else if (event.type == SDL_MOUSEBUTTONUP)
			{
				if (g_curMenuScreen)
				{
					int targX, targY;
					SDL_GetMouseState(&targX,&targY);
					g_curMenuScreen->MouseClick(targX,targY);
				}
				else if (g_curScreen == GAME_SCREEN_ACTION)
				{
					if (event.button.button == SDL_BUTTON_LEFT)
						input_fire = false;
//					else if (event.button.button == SDL_BUTTON_RIGHT)
//						input_speed = 0;
				}
				else
				{
					if (event.button.button == SDL_BUTTON_LEFT)
						left_mouse_click = true;
					else if (event.button.button == SDL_BUTTON_RIGHT)
						right_mouse_click = true;
				}
			}
		}
		Update();
		DrawScene();
	}

	Cleanup();
	return 0;
}
