
typedef struct menuwindow menuwindow;
//typedef struct labelbox labelbox;

menuwindow *mainscreen;
menuwindow *startgamewindow;
menuwindow *newsoldierwindow;
menuwindow *openwindows[10];
menuwindow **fgwindow;

void deselectlabel();

struct button {
	int x1, y1, x2, y2;
	int tox, toy;
	ABITMAP *textbmpup;
	ABITMAP *textbmpdown;
	ABITMAP *buttonup;
	ABITMAP *buttondown;
	int state;
	bool on;
	void (*func)(int a);
	int param;
	menuwindow *parent;

	button() {
		on = false;
		state = 0;
		param = 0;
		parent = NULL;
	}

	void mousedown() {
		if(!on) return;
		if(parent != NULL && parent != *fgwindow) {
			//MAKE A BEEP SOUND!!! BEEP!
			return;
		}
		else if(mx > x1 && mx < x2 && my > y1 && my < y2) {
			state = 1;
			buttonpressed = true;
		}
	}

	void mouseup() {
		if(!on) return;
		if(state == 1) {
			func(param);
		}
		state = 0;
	}

	void draw() {
		if(!on || !buttonup) return;
		if(state == 0) {
			gldrawsprite(x1, y2, buttonup);
			gldrawsprite(x1 + tox, y2 - toy, textbmpup);
		}
		else {
			gldrawsprite(x1, y2, buttondown);
			gldrawsprite(x1 + tox, y2 - toy, textbmpdown);
		}
	}
};

button buttons[MAXBUTTONS];
int numbuttons;

void drawbuttons() {
	int i;
	button *b;
	for(i = 0, b = &(buttons[0]); i < numbuttons; i++, b++) {
		if(b->on) b->draw();
	}
}

void msdownbuttons() {
	int i;
	button *b;
	for(i = 0, b = &(buttons[0]); i < numbuttons; i++, b++) {
		if(b->on) b->mousedown();
	}
}

void msupbuttons() {
	int i;
	button *b;
	for(i = 0, b = &(buttons[0]); i < numbuttons; i++, b++) {
		if(b->on) b->mouseup();
	}
}

//addbutton(263 + offx, 500 + offy, 20, 20, exitbmp, buttonup, buttondown, exit);
button *addbutton(int x, int y, int tox, int toy, ABITMAP *textbmpup, ABITMAP *textbmpdown, ABITMAP *buttonup, ABITMAP *buttondown, void (*func)(int a)) {
	button *b;
	b = &(buttons[numbuttons]);
	numbuttons++;
	b->on = true;
	b->state = 0;
	b->x1 = x;
	b->y1 = y;
	b->x2 = x + buttonup->w;
	b->y2 = y + buttonup->h;
	b->tox = tox;
	b->toy = toy;
	b->func = func;
	b->textbmpup = textbmpup;
	b->textbmpdown = textbmpdown;
	b->buttonup = buttonup;
	b->buttondown = buttondown;
	return b;
}

button *addbutton(int x, int y, int w, int h, void (*func)(int a), int param) {
	button *b;
	b = &(buttons[numbuttons]);
	numbuttons++;
	b->on = true;
	b->state = 0;
	b->x1 = x;
	b->y1 = y;
	b->x2 = x + w;
	b->y2 = y + h;
	b->tox = b->toy = 0;
	b->textbmpup = b->textbmpdown = b->buttonup = b->buttondown = NULL;
	b->func = func;
	b->param = param;
	return b;
}

struct labelbox {
	char contents[1000];
	int x, y;
	float r, g, b;
	bool editable;
	menuwindow *parent;

	labelbox() {
		r = g = b = 0;
		editable = false;
		parent = NULL;
	}

	void setcolor(float nr, float ng, float nb) {
		r = nr;
		g = ng;
		b = nb;
	}

	void draw() {
		glColor3f(r, g, b);
		gltextout(x, y, contents);
	}
};

struct menuwindow {
	button **mybuttons;
	int mynumbuttons;
	labelbox *mylabelboxes;
	int mynumlabelboxes;
	bool on;
	int x, y;
	ABITMAP *bmp;


	menuwindow() {
		mynumbuttons = 0;
		bmp = NULL;
		on = false;
	}

	void init(int numbuttons, int numlabelboxes, ABITMAP *nbmp, int nx, int ny) {
		mybuttons = (struct button **)malloc(numbuttons * sizeof(struct button *));
		mylabelboxes = (struct labelbox *)malloc(numlabelboxes * sizeof(struct labelbox));
		x = nx;
		y = ny;
		bmp = nbmp;
		on = true;
	}

	void addbutton(int x, int y, int tox, int toy, ABITMAP *textbmpup, ABITMAP *textbmpdown, ABITMAP *buttonup, ABITMAP *buttondown, void (*func)(int a)) {
		mybuttons[mynumbuttons] = ::addbutton(x, y, tox, toy, textbmpup, textbmpdown, buttonup, buttondown, func);
		mybuttons[mynumbuttons]->parent = this;
		mynumbuttons++;
	}

	void addbutton(int x, int y, int w, int h, void (*func)(int a), int param) {
		mybuttons[mynumbuttons] = ::addbutton(x, y, w, h, func, param);
		mybuttons[mynumbuttons]->parent = this;
		mynumbuttons++;
	}

	labelbox *addlabelbox(int x, int y) {
		mylabelboxes[mynumlabelboxes].x = x;
		mylabelboxes[mynumlabelboxes].y = y;
		mylabelboxes[mynumlabelboxes].parent = this;
		mynumlabelboxes++;
		return &(mylabelboxes[mynumlabelboxes - 1]);
	}

	void draw() {
		int i;

		if(bmp) gldrawsprite(x, y, bmp);
		for(i = 0; i < mynumbuttons; i++) {
			mybuttons[i]->draw();
		}
		for(i = 0; i < mynumlabelboxes; i++) {
			mylabelboxes[i].draw();
		}
		glColor3f(1.0,1.0,1.0);
	}

	void turnon() {
		int i;

		on = true;
		for(i = 0; i < mynumbuttons; i++) {
			mybuttons[i]->on = true;
		}

		fgwindow++;
		*fgwindow = this;
		deselectlabel();
	}

	void turnoff() {
		int i;

		on = false;
		for(i = 0; i < mynumbuttons; i++) {
			mybuttons[i]->on = false;
		}

		if(*fgwindow == this) fgwindow--;

		buttonpressed = false;
		deselectlabel();
	}
};

menuwindow menuwindows[MAXMENUWINDOWS];
int nummenuwindows;

menuwindow *addmenuwindow() {
	menuwindow *r;
	r = &(menuwindows[nummenuwindows]);
	nummenuwindows++;
	return r;
}

void drawmenuwindows() {
	int i;
	menuwindow *b;
	for(i = 0, b = &(menuwindows[0]); i < nummenuwindows; i++, b++) {
		if(b->on) b->draw();
	}
}

void startgame(int p) {
	startgamewindow->turnon();
}

void options(int p) {
}

void highscores(int p) {
}

void newsoldier(int p) {
	newsoldierwindow->turnon();
}

void continuefunc(int p) {
}

void cancel(int p) {
	startgamewindow->turnoff();
	buttonpressed = false;
}

void delsoldier(int p) {
}

void exitfunc(int p) {
	PostMessage(NULL, WM_QUIT, 0, 0);
}

void ns_cancel(int p) {
	newsoldierwindow->turnoff();
	buttonpressed = false;
}

void ns_ok(int p) {
	newsoldierwindow->turnoff();
	buttonpressed = false;
}

void selectlabel(labelbox *l) {
	if(l == selectedlabel) {
		if(selectedlabel != NULL) selectedlabel->setcolor(0.0,0.0,0.0);
		selectedlabel = NULL;
		return;
	}
	if(selectedlabel != NULL) selectedlabel->setcolor(0.0,0.0,0.0);
	selectedlabel = l;
}

void selectlabel(int li) {
	labelbox *l = (labelbox *)li;
	if(l == selectedlabel) {
		if(selectedlabel != NULL) selectedlabel->setcolor(0.0,0.0,0.0);
		selectedlabel = NULL;
		return;
	}
	if(selectedlabel != NULL) selectedlabel->setcolor(0.0,0.0,0.0);
	selectedlabel = l;
}

void deselectlabel() {
	if(selectedlabel != NULL) selectedlabel->setcolor(0.0,0.0,0.0);
	selectedlabel = NULL;
}

void selectsoldier(int s) {
	/*
	startgamewindow->mylabelboxes[selectedsoldier].setcolor(0.0, 0.0, 0.0);
	if(s != selectedsoldier) selectedsoldier = s;
	else selectedsoldier = -1;
	*/
	selectlabel(&(startgamewindow->mylabelboxes[s]));
	if(s != selectedsoldier)
		selectedsoldier = s;
	else selectedsoldier = -1;	
}

void doselectedcolor() {
	if(selectedlabel == NULL) return;
	if(selectedlabel->parent && selectedlabel->parent->on == false) {
		selectedlabel = NULL;
		return;
	}
	float g = 0.8 - fabs(frame % 80 - 40) * 0.005;
	selectedlabel->setcolor(0.0, g, 0.0);
	/*
	glcolor3f(0.0, g, 0.0);
	glBegin(GL_QUADS);
		glVertex2f(se
	//if(selectedlabel >= 0) startgamewindow->mylabelboxes[selectedsoldier].setcolor(0.0, 0.8 - fabs(frame % 80 - 40) * 0.005, 0.0);
	//fprintf(debug, "%f\n", 0.6 - fabs((frame % 100) * 0.0025));
	*/
}

void dotextboxblink() {
}

/*
void clearuptextbox() {
	if(textboxblinkstate == 1) {
		int i;
		for(i = 0; i < 1000 && selectedtextbox->contents[i] != '\0'; i++) ;
		if(i > 0)
			selectedtextbox->contents[i-1] = '\0';
		textboxblinkstate = 0;
	}
}

void selecttextbox(int li) {
	labelbox *l = (labelbox *)li;
	if(selectedtextbox == l) {
		clearuptextbox();
		selectedtextbox = NULL;
		textboxblinkstate = 0;
	}
	else selectedtextbox = l;
}
*/

/*
void drawmenu() {
	static ABITMAP *mainmenu = NULL;
	static ABITMAP *exitbmp = NULL;
	static ABITMAP *highscoresbmp = NULL;
	static ABITMAP *optionsbmp = NULL;
	static ABITMAP *startgamebmp = NULL;
	static ABITMAP *buttondown = NULL;
	static ABITMAP *buttonup = NULL;
	static ABITMAP *anykey = NULL;
	
	int offx, offy;
	offx = 100;
	offy = 0;

	if(anykey == NULL) {
		anykey = load_bitmap_notex("graphics\\gui\\anykey.tga");
	}
	if(menumode != 0 && mainmenu == NULL) {
		mainmenu = load_bitmap_notex("graphics\\gui\\mainmenu.tga");

		buttondown = load_bitmap_notex("graphics\\gui\\buttondown.tga");
		buttonup = load_bitmap_notex("graphics\\gui\\buttonup.tga");

		exitbmp = load_bitmap_notex("graphics\\gui\\exit.tga");
		highscoresbmp = load_bitmap_notex("graphics\\gui\\highscores.tga");
		optionsbmp = load_bitmap_notex("graphics\\gui\\options.tga");
		startgamebmp = load_bitmap_notex("graphics\\gui\\startgame.tga");

		addbutton(284 + offx, 135 + offy, 43, 10, startgamebmp, buttonup, buttondown, &startgame);
		addbutton(284 + offx, 210 + offy, 43, 10, optionsbmp, buttonup, buttondown, &options);
		addbutton(284 + offx, 285 + offy, 43, 10, highscoresbmp, buttonup, buttondown, &highscores);
		addbutton(284 + offx, 360 + offy, 43, 10, exitbmp, buttonup, buttondown, &exit);
	}
	if(menumode == 0) {
		gldrawsprite(425, 592, anykey);
		return;
	}
	else if(menumode == 1) {
		gldrawsprite(253 + offx, 484 + offy, mainmenu);
		drawbuttons();
	}
}
*/

/*		DIFFICULTY LEVELS
1: Very Easy
2: Easy
3: Normal
4: Hard
5: Insanely Hard
*/

struct user {
	char name[255];
	bool on;
	int difficulty;
	bool completed[MAXGAMELEVELS];
	int scores[MAXGAMELEVELS];

	user() {
		int i;
		on = false;
		name[0] = '\0';
		difficulty = 3;
		for(i = 0; i < MAXGAMELEVELS; i++) {
			completed[i] = false;
			scores[i] = 0;
		}
	}
};

user users[MAXUSERS];
int numusers;

void writeusers() {
	FILE *output;	
	output = fopen("players.dat", "w+b");
	fwrite(&numusers, sizeof(int), numusers, output);
	fwrite(users, sizeof(struct user), MAXUSERS, output);
	fclose(output);
}

void readusers() {
	FILE *input;	
	input = fopen("players.dat", "rb");
	fread(&numusers, sizeof(int), numusers, input);
	fread(users, sizeof(user), MAXUSERS, input);
	fclose(input);
}

void adduser(char *name, int difficulty) {
	user *u;
	u = &(users[0]);
	while(u->on) u++;
	if(u == &(users[numusers])) numusers++;

	strcpy(u->name, name);
	u->difficulty = difficulty;
	u->on = true;
}

void sortusers() {
	user tmp;
	int a, b;
	user *max;

	for(a = 0; a < numusers; a++) {
		if(users[a].on) {
			max = &(users[a]);
			for(b = a + 1; b < numusers; b++) {
				if(users[b].on && strcmp(max->name, users[b].name) > 0)
					max = &(users[b]);
			}
			tmp = users[a];
			users[a] = *max;
			*max = tmp;
		}
	}
}

void setupuserlist() {
	int i, l;
	for(i = 0, l = 0; i < numusers; i++) {
		if(users[i].on && l < 7) {
			strcpy(startgamewindow->mylabelboxes[l].contents, users[i].name);
			l++;
		}
	}
	for(; l < 7; l++) {
		strcpy(startgamewindow->mylabelboxes[l].contents, "*");
	}
}

void drawmenu() {
	static ABITMAP *mainmenu = NULL;
	static ABITMAP *exitbmp = NULL;
	static ABITMAP *highscoresbmp = NULL;
	static ABITMAP *optionsbmp = NULL;
	static ABITMAP *startgamebmp = NULL;
	static ABITMAP *exitdbmp = NULL;
	static ABITMAP *highscoresdbmp = NULL;
	static ABITMAP *optionsdbmp = NULL;
	static ABITMAP *startgamedbmp = NULL;
	static ABITMAP *buttondown = NULL;
	static ABITMAP *buttonup = NULL;
	static ABITMAP *anykey = NULL;
	static ABITMAP *newsoldierbmp = NULL;
	static ABITMAP *delsoldierbmp = NULL;
	static ABITMAP *cancelbmp = NULL;
	static ABITMAP *continuebmp = NULL;
	static ABITMAP *newsoldierdbmp = NULL;
	static ABITMAP *delsoldierdbmp = NULL;
	static ABITMAP *canceldbmp = NULL;
	static ABITMAP *continuedbmp = NULL;
	static ABITMAP *startgamewindowbmp = NULL;
	static ABITMAP *newsoldierwindowbmp = NULL;
	static ABITMAP *okbmp = NULL;
	static ABITMAP *okdbmp = NULL;
	
	int offx, offy;
	offx = 0;
	offy = 0;

	if(anykey == NULL) {
		anykey = load_bitmap_notex("graphics\\gui\\anykey.tga");
	}

	if(menumode != 0 && mainmenu == NULL) {
		fgwindow = &(openwindows[0]);
		//mainmenu = load_bitmap_notex("graphics\\gui\\mainmenu.tga");
		mainmenu = (ABITMAP *)1;

		buttondown = load_bitmap_notex("graphics\\gui\\buttondown.tga");
		buttonup = load_bitmap_notex("graphics\\gui\\buttonup.tga");

		exitbmp = load_bitmap_notex("graphics\\gui\\exitup.tga");
		highscoresbmp = load_bitmap_notex("graphics\\gui\\highscoresup.tga");
		optionsbmp = load_bitmap_notex("graphics\\gui\\optionsup.tga");
		startgamebmp = load_bitmap_notex("graphics\\gui\\startgameup.tga");
		exitdbmp = load_bitmap_notex("graphics\\gui\\exitdown.tga");
		highscoresdbmp = load_bitmap_notex("graphics\\gui\\highscoresdown.tga");
		optionsdbmp = load_bitmap_notex("graphics\\gui\\optionsdown.tga");
		startgamedbmp = load_bitmap_notex("graphics\\gui\\startgamedown.tga");

		mainscreen = addmenuwindow();
		mainscreen->init(4, 0, NULL, 0, 0);

		mainscreen->addbutton(180 - 62 + offx, 510 - 21 + offy, 0, 0, startgamebmp, startgamedbmp, buttonup, buttondown, &startgame);
		mainscreen->addbutton(180 - 62 + offx, 560 - 21 + offy, 0, 0, optionsbmp, optionsdbmp, buttonup, buttondown, &options);
		mainscreen->addbutton(820 - 62 + offx, 510 - 21 + offy, 0, 0, highscoresbmp, highscoresdbmp, buttonup, buttondown, &highscores);
		mainscreen->addbutton(820 - 62 + offx, 560 - 21 + offy, 0, 0, exitbmp, exitdbmp, buttonup, buttondown, &exitfunc);

		mainscreen->turnon();

		//bmp = load_bitmap_notex("graphics\\gui\\bmp.tga");
		
		startgamewindowbmp = load_bitmap_notex("graphics\\gui\\startgamewindow.tga");
		newsoldierbmp = load_bitmap_notex("graphics\\gui\\newsoldierup.tga");
		cancelbmp = load_bitmap_notex("graphics\\gui\\cancelup.tga");
		delsoldierbmp = load_bitmap_notex("graphics\\gui\\delsoldierup.tga");		
		continuebmp = load_bitmap_notex("graphics\\gui\\continueup.tga");
		newsoldierdbmp = load_bitmap_notex("graphics\\gui\\newsoldierdown.tga");
		canceldbmp = load_bitmap_notex("graphics\\gui\\canceldown.tga");
		delsoldierdbmp = load_bitmap_notex("graphics\\gui\\delsoldierdown.tga");		
		continuedbmp = load_bitmap_notex("graphics\\gui\\continuedown.tga");

		offx = 500 - 151;
		offy = 300 + 147;

		startgamewindow = addmenuwindow();

		startgamewindow->init(11, 7, startgamewindowbmp, offx, offy);

		/*
		startgamewindow->addbutton(23 + offx, offy - 103, 0, 0, newsoldierbmp, newsoldierdbmp, buttonup, buttondown, &newsoldier);
		startgamewindow->addbutton(offx + 302 - 23 - 124, offy - 103, 0, 0, continuebmp, continuedbmp, buttonup, buttondown, &continuefunc);
		startgamewindow->addbutton(23 + offx, offy - 66, 0, 0, delsoldierbmp, delsoldierdbmp, buttonup, buttondown, &delsoldier);
		startgamewindow->addbutton(offx + 302 - 23 - 124, offy - 66, 0, 0, cancelbmp, canceldbmp, buttonup, buttondown, &cancel);
		*/

		startgamewindow->addbutton(23 + offx, offy - 103, 0, 0, newsoldierbmp, newsoldierdbmp, buttondown, buttondown, &newsoldier);
		startgamewindow->addbutton(offx + 302 - 23 - 124, offy - 103, 0, 0, continuebmp, continuedbmp, buttondown, buttondown, &continuefunc);
		startgamewindow->addbutton(23 + offx, offy - 66, 0, 0, delsoldierbmp, delsoldierdbmp, buttondown, buttondown, &delsoldier);
		startgamewindow->addbutton(offx + 302 - 23 - 124, offy - 66, 0, 0, cancelbmp, canceldbmp, buttondown, buttondown, &cancel);

		startgamewindow->addlabelbox(offx + 55, offy - 294 + 82);
		startgamewindow->addbutton(offx + 55, offy - 294 + 82, 194, 15, selectsoldier, 0);
		startgamewindow->addlabelbox(offx + 55, offy - 294 + 97);
		startgamewindow->addbutton(offx + 55, offy - 294 + 97, 194, 15, selectsoldier, 1);
		startgamewindow->addlabelbox(offx + 55, offy - 294 + 112);
		startgamewindow->addbutton(offx + 55, offy - 294 + 112, 194, 15, selectsoldier, 2);
		startgamewindow->addlabelbox(offx + 55, offy - 294 + 127);
		startgamewindow->addbutton(offx + 55, offy - 294 + 127, 194, 15, selectsoldier, 3);
		startgamewindow->addlabelbox(offx + 55, offy - 294 + 142);
		startgamewindow->addbutton(offx + 55, offy - 294 + 142, 194, 15, selectsoldier, 4);
		startgamewindow->addlabelbox(offx + 55, offy - 294 + 157);
		startgamewindow->addbutton(offx + 55, offy - 294 + 157, 194, 15, selectsoldier, 5);
		startgamewindow->addlabelbox(offx + 55, offy - 294 + 172);
		startgamewindow->addbutton(offx + 55, offy - 294 + 172, 194, 15, selectsoldier, 6);

		writeusers();
		readusers();
		setupuserlist();

		newsoldierwindowbmp = load_bitmap_notex("graphics\\gui\\newsoldierwindow.tga");
		okbmp = load_bitmap_notex("graphics\\gui\\okup.tga");
		okdbmp = load_bitmap_notex("graphics\\gui\\okdown.tga");

		newsoldierwindow = addmenuwindow();
		
		offx = 500 - 151;
		offy = 300 + 78;

		labelbox *l;

		newsoldierwindow->init(4, 2, newsoldierwindowbmp, offx, offy);
		l = newsoldierwindow->addlabelbox(offx + 86, offy - 156 + 49);
		newsoldierwindow->addbutton(offx + 86, offy - 156 + 49, 194, 16, selectlabel, (int)l);
		//newsoldierwindow->addbutton(0, 0, 500, 500, selectlabel, (int)l);
		l->editable = true;
		strcpy(l->contents, "");
		l = newsoldierwindow->addlabelbox(offx + 86, offy - 156 + 74);
		newsoldierwindow->addbutton(offx + 86, offy - 156 + 74, 138, 16, selectlabel, (int)l);
		//l->editable = true;
		strcpy(l->contents, "Normal");
		
		newsoldierwindow->addbutton(offx + 151 - 62 - 66, offy - 62, 0, 0, okbmp, okdbmp, buttondown, buttondown, &ns_cancel);
		newsoldierwindow->addbutton(offx + 151 - 62 + 66, offy - 62, 0, 0, cancelbmp, canceldbmp, buttondown, buttondown, &ns_ok);

		newsoldierwindow->turnoff();

		/*
		strcpy(startgamewindow->mylabelboxes[0].contents, "Test1");
		strcpy(startgamewindow->mylabelboxes[1].contents, "Test2");
		strcpy(startgamewindow->mylabelboxes[2].contents, "Test3");
		strcpy(startgamewindow->mylabelboxes[3].contents, "Test4");
		strcpy(startgamewindow->mylabelboxes[4].contents, "Test5");
		strcpy(startgamewindow->mylabelboxes[5].contents, "Test6");
		strcpy(startgamewindow->mylabelboxes[6].contents, "Test7");
		*/

		startgamewindow->turnoff();
	}
	gldrawsprite(425, 592, anykey);
	drawmenuwindows();
	doselectedcolor();
}