
bool didaddnewgame;
bool didaddoptions;
bool didaddexit;



#include <fstream.h>
#include <math.h>
#include <time.h>
#include <windows.h>
#include <stdio.h>
#include <gl\gl.h>
#include <gl\glu.h>
#include "texture.h"
//#include "tgaloader.cpp"
#include "defines.h"
#include "textoutput.cpp"
#include "allegfuncs.cpp"
#include "playback.cpp"
#include "physics.cpp"
#include "gui.cpp"
#include "glfuncs.cpp"
#include "structs.cpp"
#include "vehicles.cpp"
#include "helperfuncs.cpp"
#include "guibars.cpp"
#include "drawing.cpp"

/*		**LEVELS**

  0: Nothing interacts with this. Used for debris
  1: The human player
  2: The upper part of buildings (that the player cannot walk through)
  3: The human's bullets
  4: The lower part of buildings (that the player can walk through)
  5: Enemy soldiers
  6: Enemy bullets
  7: Empty vehicles
  8: Corpses
  9: Acts like bullets (bomb bullets)
  10: Personnel bullets
  11: Friendly controlled vehicles
  12: Enemy controlled vehicles
  13: Friendly bombs
  14: Enemy bombs
  15: Gravity-less, non-interacting atoms (Plane's wheel)
  16: Rope
  17: Rung
  18: Letter
  19: Noninteracting letter
  20: Menu atom - everything interacts
 
*/
void init_allegro_graphics() {
}

void spawndiversion() {
	static int num = 0;
	static int next = 5000;

	if(frame >= next) {
		next = frame + rand() % 1000;
		//fprintf(debug, "%i joins the fray!\n", num);
		compsoldier *e;
		tank *t;
		plane *p;
		bool side;
		int vehicle;
		int randno;
		int count;
		int i;
		soldier *s;
		int troops[2];

		troops[0] = troops[1] = 0;

		for(i = 0, s = &soldiers[0]; i < numsoldiers; i++, s++) {
			if(!s->dead) troops[s->side]++;
		}
		if(troops[0] != 0 && troops[1] != 0) {
			if(troops[0] + troops[1] > 45) return;
			
			randno = rand() % (troops[0] + troops[1] + 1);
			if(randno > troops[0]) side = 0;
			else side = 1;
		}
		else {
			if(troops[0] == 0) side = 0;
			else side = 1;
		}
		
		randno = rand() % 6;
		vehicle = 0;

		if(randno < 4) vehicle = 0;
		if(randno == 4) vehicle = 0;
		if(randno == 5) vehicle = 0;

		if(vehicle == 1 || vehicle == 2) {
			count = 0;
			for(i = 0; i < numrigidbodies; i++) {
				if(rigidbodies[i].on) {
					count++;
					fprintf(debug, "%i: on\n", i);
				}
			}
			fprintf(debug, "count at %i\n", count);
			if(count > MAXRIGIDBODIES - 2)
				vehicle = 0;
		}
		if(vehicle == 1) {
			count = 0;
			for(i = 0; i < numplanes; i++) {
				if(planes[i].on) count++;
			}
			if(count > MAXPLANES - 2) {
				vehicle = 0;
			}
			else {
				fprintf(debug, "Flight %i ready for takeoff!\n", count);
			}
		}
		else if(vehicle == 2) {
			count = 0;
			for(i = 0; i < numtanks; i++) {
				if(tanks[i].on) count++;
			}
			if(count > MAXTANKS - 2) {
				vehicle = 0;
			}
			else {
				fprintf(debug, "Tank %i ready for action\n", count);
			}
		}
		//if(vehicle == 0) return;
		
		fprintf(debug, "%i joins the fray!\n", num);

		if(side == FRIEND)
			e = addcompsoldier(50, 400, side);
		else
			e = addcompsoldier(950, 400, side);

		if(vehicle == 0) {
			e->dohunt();
		}
		else if(vehicle == 1) {
			if(side == FRIEND) {
				p = addplane(50, 200, side);
				p->setdirection(RIGHT);
			}
			else {
				p = addplane(950, 200, side);
				p->setdirection(LEFT);
			}
			e->doplanepilot(p);
			e->dohunt();
		}
		else if(vehicle == 2) {
			if(side == FRIEND) {
				t = addtank(50, 300, side);
			}
			else {
				t = addtank(950, 300, side);
			}
			e->dotankdriver(t);
			e->dohunt();
		}

		e->dohunt();
		num++;
	}
}

void update() {
	bullet *b;
	int i;

	if(level == -1) spawndiversion();

	updaterigidbodies();
	physics_update();
	updatetrailanims();
	updatecompsoldiers();
	updatesoldiers();
	updateaaguns();
	updatejeeps();
	updatetanks();
	updateplanes();
	updatehelis();
	updatebombs();
	//updatebuttons();
	b = &(bullets[0]);
	for(i = 0; i < MAXBULLETS; i++) {
		b->update();
		b++;
	}
	
	/*
	if(level == -1 && lmb) {
		menuatom->x = mouse_x + 100;
		menuatom->y = mouse_y;
		menuatom->ix = 0;
		menuatom->iy = 0;
	}
	*/
}

bool boxadded;
bool saved;
bool loaded;

void dokeys() {
	if(keys['R']) {
		int i;
		reset();
		destroy_bitmap(ground);
		destroy_bitmap(buf);
		destroy_bitmap(sky);
		destroy_bitmap(bg);
		ground = buf = sky = bg = NULL;
		for(i = 0; i < numjeeps; i++) {
			jeeps[i].killvoices();
			jeeps[i].reset();
			//jeeps[i].init();
		}
		numjeeps = 0;
		for(i = 0; i < numtanks; i++) {
			tanks[i].killvoices();
			tanks[i].reset();
		}
		numtanks = 0;
		for(i = 0; i < numplanes; i++) {
			planes[i].killvoices();
			planes[i].reset();
			//planes[i].init();
		}
		numplanes = 0;
		for(i = 0; i < numhelis; i++) {
			helis[i].killvoices();
			helis[i].reset();
			//planes[i].init();
		}
		numhelis = 0;
		for(i = 0; i < MAXBULLETS; i++) {
			bullets[i].life = 0;
			bullets[i].update();
			bullets[i].init();
		}
		for(i = 0; i < MAXBOMBS; i++) {
			bombs[i].on = false;
			bombs[i].init();
		}
		numbombs = 0;
		for(i = 0; i < MAXDEBRIS; i++) {
			debris[i].on = false;
			debris[i].init();
		}
		for(i = 0; i < numsoldiers; i++) {
			soldiers[i].killvoices();
			soldiers[i].reset();
		}
		numsoldiers = 0;
		for(i = 0; i < numcompsoldiers; i++) {
			compsoldiers[i].reset();
		}
		numcompsoldiers = 0;
		for(i = 0; i < numanimations; i++) {
			animations[i].reset();
		}
		numanimations = 0;
		for(i = 0; i < MAXTRAILANIMS; i++) {
			trailanims[i].reset();
		}
		numtrailanims = 0;
		for(i = 0; i < numaaguns; i++) {
			aaguns[i].reset();
		}
		numaaguns = 0;
		initlevel();
		while(keys['R']) ;
		frame = 0;
	}

	if(keys[VK_F6] && !saved) {
		savestate("quicksave.dat");
		/*
		int x, y, i;
			for(x = 0; x < MAXBOXX; x++) {
				for(y = 0; y < MAXBOXY; y++) {
					fprintf(debug, "(%i,%i)\n", x, y);
					for(i = 0; i < boxes[x][y].count; i++) {
						fprintf(debug, "%i:%i\n", i, boxes[x][y].list[i]);
					}
				}
			}
			fprintf(debug, "ATOMS\n");
			for(i = 0; i < numatoms; i++) {
				fprintf(debug, "%i: %i, (%f, %f)\n", i, &(atoms[i]), atoms[i].x, atoms[i].y);
			}
			*/
		//fprintf(debug, "SAVING STATE AT FRAME %i\n", frame);
		//movie_savemovie(script, "quickscript.mvi");
		//compsoldiers[0].doscript(script, 0, -frame);
		saved = true;
	}
	else if(!keys[VK_F6]) {
		saved = false;
	}

	if(keys[VK_F7] && !loaded) {
		loadstate("quicksave.dat");
		didaddnewgame = false;
		didaddoptions = false;
		didaddexit = false;
		/*
		int x, y, i;
			for(x = 0; x < MAXBOXX; x++) {
				for(y = 0; y < MAXBOXY; y++) {
					fprintf(debug, "(%i,%i)\n", x, y);
					for(i = 0; i < boxes[x][y].count; i++) {
						fprintf(debug, "%i:%i\n", i, boxes[x][y].list[i]);
					}
				}
			}
			fprintf(debug, "ATOMS\n");
			for(i = 0; i < numatoms; i++) {
				fprintf(debug, "%i: %i, (%f, %f)\n", i, &(atoms[i]), atoms[i].x, atoms[i].y);
			}
			*/
		//savemovie(script, "quickscript.mvi");
		//movie_savemovie(script, "quickscript.mvi");
		/*
		movie_loadmovie(script, "quickscript.mvi");
		recording = false;
		compsoldiers[0].doscript(script, 0, -frame + 1);
		*/
		loaded = true;
	}
	else if(!keys[VK_F7]) {
		loaded = false;
	}
}

void deinitgamevars() {
	KillFont();
}

void initgamevars() {
	int i;
	BuildFont();
	ABITMAP *tmp;
	boxadded = false;
	selectedlabel = NULL;
	//selectedbutton = NULL;
	selectedsoldier = -1;
	textboxblinkstate = 0;
	mousebmp = load_bitmap("graphics\\target.tga");
	black = makecol16(0,0,0);
	green = makecol16(0,255,0);
	white = makecol16(255,255,255);
	magenta = makecol16(255, 0, 255);
	gray = makecol16(122, 122, 122);
	yellow = makecol16(220, 220, 0);
	nullcolor = makecol(0,0,0,0);
	convk = 128.0 / pi;
	convk2 = pi / 128.0;
	COMPFRAMES = 6;
	srand((unsigned)time( NULL ));
	settmplevels();
	mgun = load_sample("mgun.wav");
	bombdrop = load_sample("bombdrop.wav");
	aagunfire = load_sample("aagun.wav");
	tankfire = load_sample("tankfire.wav");
	gurgle = load_sample("gurgle.wav");
	splash = load_sample("splash.wav");
	engine = load_sample("engine.wav");
	enginestart = load_sample("enginestart.wav");
	prop = load_sample("prop.wav");
	propstart = load_sample("propstart.wav");
	death1 = load_sample("death1.wav");
	//play_sample(mgun, 255, 122, 1000, 0);
	explode = load_sample("explodelarge.wav");
	explodesmall = load_sample("explodesm.wav");
	music = load_midi("lev1.mid");
	initguibars();
	script = movie_createmovie();
	recording = false;

	//play_midi(music, true);
	numanimations = 0;
	numtrailanims = 0;
	numbombs = 0;
	jeep *j;
	for(i = 0; i < MAXJEEPS; i++) {
		j = &(jeeps[i]);
		j->unoc = load_bitmap("graphics\\jeepu.tga");
		j->unocl = load_bitmap("graphics\\jeepul.tga");
		j->occ = load_bitmap("graphics\\jeepo.tga");
		j->occl = load_bitmap("graphics\\jeepol.tga");
		j->exp = load_bitmap("graphics\\jeepd.tga");
		j->expl = load_bitmap("graphics\\jeepdl.tga");
	}

	tankbase = load_bitmap("graphics\\tanku.tga");
	tankbasee = load_bitmap("graphics\\tankue.tga");
	tankd = load_bitmap("graphics\\tankd.tga");
	tankde = load_bitmap("graphics\\tankde.tga");

	planeunoc = load_bitmap("graphics\\planeu.tga");
	planeocc = load_bitmap("graphics\\planeo.tga");
	planefiring = load_bitmap("graphics\\planef.tga");
	planeexp = load_bitmap("graphics\\planed.tga");
	planedamaged = load_bitmap("graphics\\planeh.tga");
	planedamagedo = load_bitmap("graphics\\planeho.tga");
	planedamagedf = load_bitmap("graphics\\planehf.tga");

	planeunoce = load_bitmap("graphics\\planeue.tga");
	planeocce = load_bitmap("graphics\\planeoe.tga");
	planefiringe = load_bitmap("graphics\\planefe.tga");
	planeexpe = load_bitmap("graphics\\planede.tga");
	planedamagede = load_bitmap("graphics\\planehe.tga");
	planedamagedoe = load_bitmap("graphics\\planehoe.tga");
	planedamagedfe = load_bitmap("graphics\\planehfe.tga");

	heliunoc = load_bitmap("graphics\\heliu.tga");
	heliocc = load_bitmap("graphics\\helio.tga");
	helifiring = load_bitmap("graphics\\helif.tga");
	heliexp = load_bitmap("graphics\\helid.tga");
	helidamaged = load_bitmap("graphics\\heliu.tga");
	helidamagedo = load_bitmap("graphics\\helio.tga");
	helidamagedf = load_bitmap("graphics\\helif.tga");

	/*
	heliunoce = load_bitmap("graphics\\heliue.tga");
	heliocce = load_bitmap("graphics\\helioe.tga");
	helifiringe = load_bitmap("graphics\\helife.tga");
	heliexpe = load_bitmap("graphics\\helide.tga");
	helidamagede = load_bitmap("graphics\\helihe.tga");
	helidamagedoe = load_bitmap("graphics\\helihoe.tga");
	helidamagedfe = load_bitmap("graphics\\helihfe.tga");
	*/

	
	soldierarm = load_bitmap("graphics\\soldierarm.tga");
	soldierarme = load_bitmap("graphics\\soldierarme.tga");
	soldierhead = load_bitmap("graphics\\soldierhead.tga");
	soldierheade = load_bitmap("graphics\\soldierheade.tga");



	/*
	tank *t;
	for(i = 0; i < MAXTANKS; i++) {
		t = &(tanks[i]);
		t->base = tankbase;
		t->exp = tankd;
	}
	
	plane *p;
	for(i = 0; i < MAXPLANES; i++) {
		p = &(planes[i]);
		p->unoc = load_bitmap("graphics\\planeu.tga");
		p->occ = load_bitmap("graphics\\planeo.tga");
		p->firing = load_bitmap("graphics\\planef.tga");
		p->exp = load_bitmap("graphics\\planed.tga");
		p->expl = load_bitmap("graphics\\planedl.tga");
		p->damaged = load_bitmap("graphics\\planeh.tga");
		p->damagedo = load_bitmap("graphics\\planeoh.tga");
		p->damagedf = load_bitmap("graphics\\planehf.tga");
	}

	heli *h;
	for(i = 0; i < MAXHELIS; i++) {
		h = &(helis[i]);
		h->unoc = load_bitmap("graphics\\heliu.tga");
		h->occ = load_bitmap("graphics\\helio.tga");
		h->firing = load_bitmap("graphics\\helif.tga");
		h->exp = load_bitmap("graphics\\helid.tga");
		h->expl = load_bitmap("graphics\\helid.tga");
		h->damaged = load_bitmap("graphics\\heli.tga");
		h->damagedo = load_bitmap("graphics\\helio.tga");
		h->damagedf = load_bitmap("graphics\\helif.tga");
	}
	*/

	aagun *a;
	for(i = 0; i < MAXAAGUNS; i++) {
		a = &(aaguns[i]);
		a->barrel = load_bitmap("graphics\\aagunbarrel.tga");
		a->gunbg = load_bitmap("graphics\\aagunbg.tga");
		a->base = load_bitmap("graphics\\aagunbase.tga");
		a->baseo = load_bitmap("graphics\\aagunbaseo.tga");
		a->baseoe = load_bitmap("graphics\\aagunbaseoe.tga");
	}
	debris1 = load_bitmap("graphics\\debris1.tga");
	debris1a = load_bitmap("graphics\\debris1a.tga");
	debriso1 = load_bitmap("graphics\\debriso1.tga");
	grounddebris1 = load_bitmap("graphics\\grounddebris1.tga");

	particlebmp = load_bitmap("graphics\\particle.tga");

	debrisr[0] = load_bitmap("graphics\\debrisr1.tga");
	debrisr[1] = load_bitmap("graphics\\debrisr2.tga");
	debrisr[2] = load_bitmap("graphics\\debrisr3.tga");
	debrisr[3] = load_bitmap("graphics\\debrisr4.tga");

	debrisrm[0] = load_bitmap("graphics\\debrisrm1.tga");
	debrisrm[1] = load_bitmap("graphics\\debrisrm2.tga");
	debrisrm[2] = load_bitmap("graphics\\debrisrm3.tga");
	debrisrm[3] = load_bitmap("graphics\\debrisrm4.tga");

	debrisra[0] = load_bitmap("graphics\\debrisra1.tga");
	debrisra[1] = load_bitmap("graphics\\debrisra2.tga");
	debrisra[2] = load_bitmap("graphics\\debrisra3.tga");
	debrisra[3] = load_bitmap("graphics\\debrisra4.tga");

	scorch = load_bitmap("graphics\\scorch.tga");
	bombbmp = load_bitmap("graphics\\bomb.tga");
	missilebmp = load_bitmap("graphics\\missile.tga");
	shell = load_bitmap("graphics\\shell.tga");
	tmp = load_bitmap("graphics\\explosion.tga");
	int x, y;

	for(x = 0; x < 4; x++) {
		for(y = 0; y < 4; y++) {
			explosionanim[x + y*4] = create_bitmap_ex(32, 64, 64);
			blitopaque(tmp, explosionanim[x + y*4], x * 64, (3 - y) * 64, 0, 0, 64, 64);
		}
	}

	destroy_bitmap(tmp);
	
	tmp = load_bitmap("graphics\\soldierbody.tga");
	for(x = 0; x < 8; x++) {
		soldierbody[x] = create_bitmap_ex(32, 19, 19);
		blitopaque(tmp, soldierbody[x], x * 19, 0, 0, 0, 19, 19);
	}
	destroy_bitmap(tmp);
	
	tmp = load_bitmap("graphics\\soldierbodye.tga");
	for(x = 0; x < 8; x++) {
		soldierbodye[x] = create_bitmap_ex(32, 19, 19);
		blitopaque(tmp, soldierbodye[x], x * 19, 0, 0, 0, 19, 19);
	}
	destroy_bitmap(tmp);

	tmp = load_bitmap("graphics\\explosionsmall.tga");
	for(x = 0; x < 24; x++) {
		explosionsmallanim[x] = create_bitmap_ex(32, 9, 9);
		clear(explosionsmallanim[x]);
		blitopaque(tmp, explosionsmallanim[x], x * 9, 0, 0, 0, 9, 9);
	}

	destroy_bitmap(tmp);
	tmp = load_bitmap("graphics\\tankbarrel.tga");
	for(y = 0; y < 10; y++) {
		tankbarrelanim[y] = create_bitmap_ex(32, 32, 8);
		blitopaque(tmp, tankbarrelanim[y], 0, y * 8, 0, 0, 32, 8);
		createtexture(tankbarrelanim[y]);
	}

	destroy_bitmap(tmp);
	tmp = load_bitmap("graphics\\smoke.tga");
	for(x = 0; x < 24; x++) {
		smokeanim[x] = create_bitmap_ex(32, 30, 30);
		blitopaque(tmp, smokeanim[x], x * 30, 0, 0, 0, 30, 30);
	}

	destroy_bitmap(tmp);
	tmp = load_bitmap("graphics\\redpart.tga");
	for(x = 0; x < 24; x++) {
		redanim[x] = create_bitmap_ex(32, 30, 30);
		blitopaque(tmp, redanim[x], x * 30, 0, 0, 0, 30, 30);
	}

	destroy_bitmap(tmp);
	tmp = load_bitmap("graphics\\yellowpart.tga");
	for(x = 0; x < 24; x++) {
		yellowanim[x] = create_bitmap_ex(32, 30, 30);
		blitopaque(tmp, yellowanim[x], x * 30, 0, 0, 0, 30, 30);
	}

	destroy_bitmap(tmp);
	tmp = load_bitmap("graphics\\whitepart.tga");
	for(x = 0; x < 24; x++) {
		whiteanim[x] = create_bitmap_ex(32, 30, 30);
		clear(whiteanim[x]);
		blitopaque(tmp, whiteanim[x], x * 30, 0, 0, 0, 30, 30);
	}

	destroy_bitmap(tmp);
	tmp = load_bitmap("graphics\\splash.tga");
	for(x = 0; x < 6; x++) {
		splashanim[x] = create_bitmap(9, 4);
		blitopaque(tmp, splashanim[x], x * 9, 0, 0, 0, 9, 4);
	}

	destroy_bitmap(tmp);
	tmp = load_bitmap("graphics\\trail.tga");
	for(x = 0; x < 9; x++) {
		misstrailanim[x] = create_bitmap(20, 20);
		blitopaque(tmp, misstrailanim[x], x * 20, 0, 0, 0, 20, 20);
	}

	destroy_bitmap(tmp);
}

void initlevel() {
	if(level == 10 || level == 11) {
		ground = load_bitmap_notex("graphics\\emptylev.tga");
		readpath("emptylev.pat");
		waterlevel = 700;
	}

	if(level < 10) sky = load_bitmap_notex("graphics\\sky.tga");
	else {
		sky = load_bitmap_notex("graphics\\emptylev.tga");
	}
	bg = create_bitmap(ground->w, ground->h);
	buf = create_bitmap(ground->w, ground->h);
	if(level != -1)
		draw_sprite(bg, sky, 0, 0);
	else
		blit(sky, bg, 3320, 0, 0, 0, 1000, 800);
	draw_sprite(bg, ground, 0, 0);
	draw_sprite(buf, bg, 0, 0);

	//tmplevels[2] = false;

	//exptemp = create_bitmap_ex(32, 

	compsoldier *e;
	aagun *a;
	tank *t;
	plane *p;
	
	if(level == 10 || level == 11) {
		cleartmplevels();
		center = addatom(500, 400, tmplevels, 0);
		center->rmdt = 0.23;
		center->fixed = true;
		human = addsoldier();
		human->init(center, FRIEND);
		human->dead = true;
	}
	else if(level == 11) {
		cleartmplevels();
		center = addatom(500, 400, tmplevels, 0);
		center->rmdt = 0.23;
		center->fixed = true;
		human = addsoldier();
		human->init(center, FRIEND);
		human->dead = true;
	}
}

int rungame(MSG &msg) {
	int compframe = 0;//, frame = 0;
	bool boxadded = false;
	int x, y, i;

	didaddnewgame = false;
	didaddoptions = false;
	didaddexit = false;
	//numinteracted = 0;
	menumode = -1;

	level = 11;

	initgamevars();
	physics_initvars();
	physics_initialize();
	initlevel();
	blueprint b;

	settmplevels();

	createtextures();
	frame = 0;
	drawframe = 0;
	dispframe = false;

	int msgval = 0;

	static bool wrote = false;
	while(!keys['Q'] && !keys[VK_ESCAPE] && menumode != -7 && msgval != 2) {
		compframe++;
		
		msgval = handlemessages(msg);
		while(msgval == 1) msgval = handlemessages(msg);

		if(compframe == COMPFRAMES) {
			newdraw();

			compframe = 0;
			frame++;
			drawframe++;
			dispframe = true;
			if(numsplashes > 0 && drawframe % 10 == 0) numsplashes--;
		}
		update();

		dispframe = false;

		dokeys();

		frame++;
	}

	deinitgamevars();

	return 1;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
	MSG msg;
	int done = 0;

	fullscreen = false;
	initvars();
	init_graphics();	
	//drawsomething();

	rungame(msg);

	deinitvars();
	KillGLWindow();												// Kill The Window
	return (msg.wParam);										// Exit The Program
}