#include "game.h"
#include "test.h"
#include "data3.h"
#include "data2.h"
#include "string.h"

volatile int system_time;
volatile int ticks;
volatile int framerate;
volatile int draw_ticks;
PALETTE pal;
COLOR_MAP trans_table;
BITMAP *buffer;
int gFade_Timer;
int gTransparency;
int startpos;
int iTimer_Speed;
INPUT gInput;
bool iFrameRate;


games GAME;

	

void timer1(void)
{
	system_time++;			
}END_OF_FUNCTION(timer1);

void frametimer(void)
{
	framerate = draw_ticks;
	draw_ticks = 0;
}END_OF_FUNCTION(frametimer);


void init()
{
	//  Allegro Library
	if(allegro_init() != 0)
	{
		allegro_message("ERROR:  Failed to initialize allegro library.  Terminating program.\n");
		allegro_message("REPORT:  %s\n", allegro_error);
		exit(0);
	}

	//  Initial Config file stuff...
	GAME.configuration = new CONFIG;
	GAME.configuration->load();
	
	set_color_depth(GAME.configuration->bpp) ; // 24 bit colour	
	if (set_gfx_mode(GAME.configuration->MODE, GAME.configuration->w, GAME.configuration->h, 0, 0)<0)
	{
		set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
		allegro_message("ERROR:  Failure to init video mode!  Terminating program.\n");
		allegro_message("REPORT:  %s\n", allegro_error);
		exit(0);
	}
	
	set_window_title(" Toggles");

	//  Install Timer
	if(install_timer() != 0)
	{
		set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
		allegro_message("ERROR:  Failed to install timer.  Terminating program.\n");
		allegro_message("REPORT:  %s\n", allegro_error);
		exit(0);
	}
	


	//  Install Keyboard	
	if(install_keyboard() != 0)
	{
		set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
		allegro_message("ERROR:  Failed to install keyboard.  Terminating program.\n");
		allegro_message("REPORT:  %s\n", allegro_error);
		exit(0);
	}	

	//  Install Mouse
	if(install_mouse() < 0)
	{
		set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
		allegro_message("ERROR:  Failed to install mouse.  Terminating program.\n");
		allegro_message("REPORT:  %s\n", allegro_error);
		exit(0);
	}
	
	//text_mode(MASK);	
	reserve_voices(32,-1); ///Reserves more channels of sound for us
	
	//  Install Sound
	if(install_sound(DIGI_AUTODETECT, MIDI_NONE, NULL) != 0)	
	{
		allegro_message("ERROR:  Failure to install sound.  Attempting to run without sound.\n");
		allegro_message("REPORT:  %s\n", allegro_error);
		if(install_sound(DIGI_NONE, MIDI_NONE, NULL) != 0)
		{
			allegro_message("ERROR:  Failed to install sound.  Terminating program.\n");
			allegro_message("REPORT:  %s\n", allegro_error);
			exit(0);
		}		
	}
		
	srand( (unsigned) time(NULL));
	
	// Install Time Handler
	LOCK_VARIABLE(system_time);
	LOCK_VARIABLE(ticks);
	LOCK_VARIABLE(framerate);
	LOCK_VARIABLE(draw_ticks);
	LOCK_FUNCTION(timer1);
	LOCK_FUNCTION(frametimer);
	iTimer_Speed = GAME.configuration->clock_speed;
	install_int_ex(timer1, BPS_TO_TIMER(iTimer_Speed));
	install_int_ex(frametimer, BPS_TO_TIMER(1));
	//install_int(timer1, 1000);
	
	// Setup the buffer
	buffer = create_bitmap(GAME.configuration->w, GAME.configuration->h);

	// Setup translucent table
	create_trans_table(&trans_table, pal, 0, 0, 0, NULL);	
	color_map = &trans_table;
	set_trans_blender(0, 0, 0, 78);
	gFade_Timer = ticks;
	gTransparency = 0;

	// Map the keyboard and joystick
	gInput.map(CANCEL, 0, KEY_ESC, 0);
	gInput.map(LEFT, 0, KEY_LEFT, 0);
	gInput.map(RIGHT, 0, KEY_RIGHT, 0);
	gInput.map(DOWN, 0, KEY_DOWN, 0);
	gInput.map(UP, 0, KEY_UP, 0);
	gInput.map(ACCEPT, 0, KEY_SPACE, 0);
	gInput.map(ACTION_1, 0, KEY_LCONTROL, 0);	

	GAME.dat3 = load_datafile("./data/images/m.dat");
	if(!GAME.dat3)
	{
		allegro_message("ERROR:  Couldn't open dat3.dat file.");
		exit(0);
	}
	
	
}

int seconds(int iTime)
{
	return iTime * iTimer_Speed;
}

bool dTime(int iTime)
{
	return ticks % iTime == 0;
}

void shutdown()
{
	destroy_bitmap(buffer);
	allegro_exit();
}

void logo_screen(bool status)
{
	BITMAP *bAllegro;
	BITMAP *bSolo;
	BITMAP *bTransfer;	

	int transparency;

	// To skip the logo screen
	if(!status) return;



	bAllegro = load_bitmap_check("./data/images/allegro.pcx", NULL);			
	bSolo = (BITMAP *) GAME.dat3[SOLOGAMES].dat;
	bTransfer = create_bitmap_check(buffer->w, buffer->h);	

	clear(buffer);
	transparency = 0;
	set_trans_blender(0,0,0,0);
	ticks = 1;		
	
	while(ticks < seconds(3) && !key[KEY_ESC])
	{
		while(system_time > 0)
		{
			ticks++;
			if(transparency < 255 && dTime(5))
			{				
				transparency += 10;
				set_trans_blender(0,0,0, transparency);
			}			
			stretch_sprite(bTransfer, bAllegro, 0, 0, buffer->w, buffer->h);
			system_time--;	
		
		}	
		
		draw_ticks++;		
		draw_trans_sprite(buffer, bTransfer, 0, 0);				
		draw_sprite(screen, buffer, 0, 0);
		
	}
	while(key_pressed(KEY_ESC)){}

	set_trans_blender(0,0,0,0);
	transparency = 0;
	ticks = 1;
	//text_mode(WHITE);
	while(ticks < seconds(3) && !key[KEY_ESC])
	{
		while(system_time > 0)
		{
			ticks++;
			if(transparency < 255 && dTime(5))
			{				
				transparency += 10;
				set_trans_blender(0,0,0, transparency);
			}
			stretch_sprite(bTransfer, bSolo, 0, 0, buffer->w, buffer->h);
			textprintf_ex(bTransfer, font, 220, 10, BLACK, -1, "http://www.silvey-games.blogspot.com");											
			system_time--;
		}

		draw_ticks++;
		draw_trans_sprite(buffer, bTransfer, 0, 0);
		draw_sprite(screen, buffer, 0, 0);
		
	}
	//text_mode(MASK);
	ticks = 1;	
	transparency = 0;
	while(transparency < 255)
	{
		clear(bSolo);
		while(system_time > 0)
		{
			ticks++;
			if(dTime(5))
			{				
				transparency += 10;
				set_trans_blender(0,0,0, transparency);
			}
			stretch_sprite(bTransfer, bSolo, 0, 0, buffer->w, buffer->h);
			system_time--;
		}
		draw_trans_sprite(buffer, bTransfer, 0, 0);
		draw_sprite(screen, buffer, 0, 0);
		
	}

	while(key_pressed(KEY_ESC)){}

	
	destroy_bitmap(bAllegro);	
	destroy_bitmap(bTransfer);
	
	
}


void play_game()
{	
	if(GAME.configuration->framerate == 1)
		iFrameRate = true;
	else
		iFrameRate = false;
	game_init();

	
	GAME.audio.add_to_playlist("./data/music/Right On!.ogg");
	GAME.audio.add_to_playlist("./data/music/Toggle Me.ogg");
	GAME.audio.set_loop();
	//Title_Screen();	
	GAME.gHSC->get_local();
	
		GAME.audio.stop();
		while(!gInput.MAP(CANCEL,5) && !GAME.quit)
		{
			while(system_time)
			{
				system_time--;
				ticks++;
				game_update();				
			}		
				
			draw_ticks++;
			game_draw();

			if(iFrameRate) 
			{
				//text_mode(-1);	
				textprintf_ex(screen, font, 0, 0, -1, -1,"Framerate:  %dfps", framerate);					
			}
		}
		GAME.audio.stop();		
	
	GAME.audio.breakdown();
	game_shutdown();

}
int iSizeSet;
void game_init()
{	
	BITMAP *bTemp;

	GAME.dat2 = load_datafile("./data/sfx/s.dat");
	if(!GAME.dat2)
	{
		allegro_message("ERROR:  Couldn't open dat2.dat file.");
		exit(0);
	}

		
	GAME.dat4 = load_datafile("./data/images/bp.dat");
	if(!GAME.dat4)
	{
		allegro_message("ERROR:  Couldn't open dat4.dat file.");
		exit(0);
	}

	GAME.mydat = load_datafile("./data/fonts.dat");
	if(!GAME.mydat)
	{
		allegro_message("Couldn't open dat file.");
		return;
	}

	GAME.score_font = (FONT *)GAME.mydat[My_Font].dat;
	if(!GAME.score_font)
		allegro_message("ERROR:  Could not read font file.");		
	GAME.score_palette = (PALETTE *)GAME.mydat[My_Font_Palette].dat;
	if(!GAME.score_palette)
		allegro_message("ERROR: Could not load Palette for fonts.");
	
	GAME.help_font = (FONT *)GAME.mydat[My_Help].dat;
	if(!GAME.help_font)
		allegro_message("ERROR:  Could not read font file.");		
	GAME.help_palette = (PALETTE *)GAME.mydat[My_Help_Palette].dat;
	if(!GAME.help_palette)
		allegro_message("ERROR: Could not load Palette for fonts.");
	
	GAME.gScore = new SCORE;

	

	
	GAME.gHSC = new HSC;
	GAME.version = fVERSION;
	strcpy(GAME.cName, "");
	GAME.bMouse = load_bitmap("./data/images/mouse.bmp", NULL);
	if(GAME.configuration->mouse_icon == 1)
		show_mouse(screen);
	GAME.sToggles_Screen = new SIMPLE_GUI;
	GAME.sToggles_Screen->Setup("./data/images/back.pcx", buffer->w, buffer->h);
	GAME.sToggles_Screen->create_object(0, "Board Container", "./data/images/border.pcx", 0, 10, 10, 400, 400);
	GAME.sToggles_Screen->create_object(1, 0, "Board", 0, 15, 15, 365, 365);
	GAME.sToggles_Screen->create_object(2, "Toggle Progress", 0, 10, 420, 400, 50);
	GAME.sToggles_Screen->create_object(3, "Score", 0, 420, 10, 210, 50);	
	GAME.sToggles_Screen->set_draw_name(3, true);
	GAME.gScore->setup(210, 50);
	GAME.sToggles_Screen->create_object(4, "Level", 0, 420, 70, 210, 50);	
	GAME.sToggles_Screen->set_draw_name(4, true);
	GAME.bLevel = create_bitmap_check(210, 50);
	GAME.sToggles_Screen->create_object(5, "Time", 0, 530, 130, 100, 50);	
	GAME.sToggles_Screen->create_object(15, "Time", 0, 420, 130, 110, 50);	
	GAME.sToggles_Screen->set_draw_name(15, true);
	
	bTemp = load_bitmap_check("./data/images/slot.pcx", NULL);
	GAME.sToggles_Screen->create_object(6, "Bonuses", 0, 440, 270, 190, 130);	
	GAME.sToggles_Screen->create_object(16, "Bonuses", 0, 440, 220, 190, 50);	
	GAME.sToggles_Screen->set_draw_name(16, true);
	GAME.sToggles_Screen->create_none_object(7, "Slot", "./data/images/slot.pcx", 0, 450, 280, 50, 50);
	GAME.sToggles_Screen->create_none_object(8, "Slot1", "./data/images/slot.pcx", 0, 510, 280, 50, 50);
	GAME.sToggles_Screen->create_none_object(9, "Slot2", "./data/images/slot.pcx", 0, 570, 280, 50, 50);
	GAME.sToggles_Screen->create_none_object(10, "Slot3", "./data/images/slot.pcx", 0, 450, 340, 50, 50);
	GAME.sToggles_Screen->create_none_object(11, "Slot4", "./data/images/slot.pcx", 0, 510, 340, 50, 50);
	GAME.sToggles_Screen->create_none_object(12, "Slot5", "./data/images/slot.pcx", 0, 570, 340, 50, 50);

	//GAME.sToggles_Screen->create_object(13, "Help", 0, 440, 410, 190, 60);

	char f1[30];
	char f2[30];
	strcpy(f1, "./data/images/"); strcat(f1, GAME.configuration->wunder_water);
	strcpy(f2, "./data/images/"); strcat(f2, GAME.configuration->wwater_surface);
	GAME.wToggles_Water = new WATER(f1, f2);		
	GAME.bBoard = new BOARD;	
	GAME.bBoard->setup(365, 365, 0, "./data/images/toggle.pcx", "./data/images/toggle2.pcx", "./data/images/toggle3.pcx");
	
	GAME.pTime_Progress = new PROGRESS_BAR;
	

	GAME.peToggle_Stars = new PARTICLE_ENGINE;
	GAME.peToggle_Stars->setup("./data/images/fluff.bmp", 0, 8, 8, 2);
	GAME.peCombo  = new PARTICLE_ENGINE;
	GAME.peCombo->setup("./data/images/stars.pcx", 4, 16, 16, 0);
	GAME.peFire  = new PARTICLE_ENGINE;
	GAME.peFire->setup("./data/images/fire.bmp", 4, 16, 16, 0);

	GAME.bWater = create_bitmap_check(400, 400);
	GAME.iTemp = 200;	
	ticks = 0;

	GAME.lLightning = new LIGHTNING;

	GAME.pPenalty_Screen = new PENALTY;
	GAME.pPenalty_Screen->setup();
	GAME.bDim = create_bitmap_check(buffer->w, buffer->h);
	rectfill(GAME.bDim, 0, 0, GAME.bDim->w, GAME.bDim->h, BLACK);


	
	GAME.audio.setup(GAME.configuration->music_volume, 
					 GAME.configuration->sfx_volume, 
					 GAME.configuration->pan, 
					 GAME.configuration->mspeed);
	GAME.audio.load_sfx(1,BONUS_WAV);
	GAME.audio.load_sfx(2,COMPLETE_WAV);
	GAME.audio.load_sfx(3,DING_WAV);
	GAME.audio.load_sfx(4,HEART_WAV);
	GAME.audio.load_sfx(5,LIGHTNING_WAV);
	GAME.audio.load_sfx(6,TIME_WAV);
	GAME.audio.load_sfx(7,TOGGLE_WAV);
	GAME.audio.load_sfx(9,ULTIMA_WAV);
	GAME.audio.load_sfx(10,BOMB_WAV);
	GAME.audio.load_sfx(11,COMBO1);
	GAME.audio.load_sfx(12,COMBO2_WAV);
	GAME.audio.load_sfx(13,COMBO3_WAV);
	GAME.audio.load_sfx(14,COMBO4_WAV);
	//GAME.audio.load_sfx(2, "./data/sfx/complete.wav");
	/*GAME.audio.load_sfx(3, "./data/sfx/ding.wav");
	GAME.audio.load_sfx(4, "./data/sfx/heart.wav");
	GAME.audio.load_sfx(5, "./data/sfx/lightning.wav");
	GAME.audio.load_sfx(6, "./data/sfx/time!.wav");
	GAME.audio.load_sfx(7, "./data/sfx/toggle.wav");	
	GAME.audio.load_sfx(9, "./data/sfx/ultima.wav");
	GAME.audio.load_sfx(10, "./data/sfx/bomb2.wav");
	GAME.audio.load_sfx(11, "./data/sfx/combo1.wav");
	GAME.audio.load_sfx(12, "./data/sfx/combo2.wav");
	GAME.audio.load_sfx(13, "./data/sfx/combo3.wav");
	GAME.audio.load_sfx(14, "./data/sfx/combo4.wav");*/
	
	for(int m = 0; m < MAX_MESSAGES; m++)
		GAME.cMessages[m] = NULL;
	
	GAME.MainMenu = new TITLE;
	GAME.MainMenu->setup();
	GAME.state = TITLE_SCREEN;
	
	GAME.pCurrent_Penalty = NO_PENALTY;		

	if(GAME.configuration->start_online)
		GAME.view_online = true;
	else
		GAME.view_online = false;
	destroy_bitmap(bTemp);		
}

void game_setup()
{	
	system_time = 0;
	ticks = 0;
	
	GAME.level = 0;
	GAME.iRows_Temp = 5;
	GAME.secs = 25;
	GAME.percent = 0.70;
	GAME.difficulty = 1;	
	GAME.bBoard->set_difficulty(GAME.difficulty);	
	GAME.bBoard->reset_bonuses();
	GAME.gScore->reset();	
	

}

void game_level()
{
	int iClear, iMix;

	if(GAME.configuration->no_water_change == 1 && GAME.level > 1)
	{
		iClear = GAME.configuration->wclear_init;
		iMix = 50;
	}
	else
	{
		iClear = MID(0, GAME.configuration->wclear_init - (GAME.level * 2), 255);
		iMix = MID(50, 50 + (GAME.level * 3), 255);
		GAME.wToggles_Water->Setup(GAME.configuration->wwidth, 
							   GAME.configuration->wheight,
							   GAME.configuration->wdamper, 
							   GAME.configuration->wsmooth, 
							   iClear);
		GAME.wToggles_Water->mixture(iMix);
	}

	
	GAME.pTime_Progress->setup(100, 50, RED, MASK, 1.0, true);
	GAME.pTime_Progress->set_progress(0.0);


	if(++GAME.level % 5 == 0) 
	{
		GAME.iRows_Temp++;
		GAME.secs--;
	}
	if(GAME.iRows_Temp > 30) GAME.iRows_Temp = 30;
	GAME.difficulty++;
	//GAME.bBoard->setup(GAME, GAME.iRows_Temp, 365, 365, 0, GAME.percent, seconds(GAME.secs));	
	GAME.bBoard->resetup(GAME, GAME.iRows_Temp, GAME.percent, seconds(GAME.secs)); 
	GAME.bBoard->set_difficulty(GAME.difficulty);	
	GAME.over = false;
	GAME.next_level = false;
	GAME.pPenalty_Screen->place(-400, 40);
	GAME.bBoard->reset_clock();
}

void level_finish()
{
	GAME.pPenalty_Screen->update();
	if((GAME.pCurrent_Penalty = GAME.pPenalty_Screen->done()) != NO_PENALTY)
	{
		GAME.pPenalty_Screen->move(700, 40);		
		if(GAME.pPenalty_Screen->position() > 640)
		{
			GAME.next_level = true;
			GAME.pPenalty_Screen->unlock();
			//GAME.bBoard->destroy();

			switch(GAME.pCurrent_Penalty)
			{
				case 9: GAME.secs++; break;
				case 10: GAME.percent -= 0.01; break;

				case 1: GAME.secs--; break;
				case 4: GAME.secs -= 2; break;
				case 5: GAME.secs -= 4; break;
				case 3: GAME.percent += 0.01; break;
				case 6: GAME.percent += 0.02; break;
				case 7: GAME.percent += 0.03; break;
				case 2: GAME.iRows_Temp++; break;
				case 8:  GAME.iRows_Temp += 2;
				case 11:	GAME.gScore->add(3000);
				default: break;
			}
			if(GAME.iRows_Temp > 30) GAME.iRows_Temp = 30;			
		}
	}
}

void game_update()
{
	if(GAME.state == TITLE_SCREEN || GAME.state == PAUSED)
	{
		GAME.audio.update(1);
		GAME.MainMenu->update();		
	}
	else
	{
		GAME.audio.update(0);

		//Quits current game...
		if(key[KEY_Q])
		{
			GAME.state = TITLE_SCREEN;
			GAME.audio.stop();
			GAME.MainMenu->change_menu(0);
		}
		
		if(strcmp(GAME.configuration->level, "LOW") != 0) GAME.wToggles_Water->Update();
		if(strcmp(GAME.configuration->level, "LOW") != 0) GAME.peToggle_Stars->update();
		if(strcmp(GAME.configuration->level, "LOW") != 0) GAME.peCombo->update();
		if(strcmp(GAME.configuration->level, "LOW") != 0) GAME.peFire->update();
		GAME.lLightning->update();
		if(strcmp(GAME.configuration->level, "LOW") != 0)GAME.sToggles_Screen->update();			

		for(int m = 0; m < MAX_MESSAGES; m++)
		{
			if(GAME.cMessages[m] != NULL)
			{
				GAME.cMessages[m]->update();
				if(GAME.cMessages[m]->finished)
				{
					delete GAME.cMessages[m];
					GAME.cMessages[m] = NULL;
				}
			}
		}
		if(!GAME.bBoard->complete() && !GAME.bBoard->ultima)
		{	
			level_finish();
			if(GAME.next_level)
				game_level();			
		}
		else
		{
			
			GAME.bBoard->update(GAME);
			GAME.pTime_Progress->set_progress(GAME.bBoard->fTime);
			GAME.pTime_Progress->update();
		}
	}
	
}

void game_draw()
{
	if(GAME.state == TITLE_SCREEN || GAME.state == PAUSED)
	{
		GAME.MainMenu->draw(buffer);
	}
	else
	{
		
		GAME.wToggles_Water->draw(GAME.bWater);
		GAME.bBoard->draw(GAME);		
		GAME.sToggles_Screen->draw_object(1, GAME.bBoard->image(), 0, 0);
		GAME.sToggles_Screen->draw_rectangle(0, 0, 0, 399, 399, DARKGOLDENROD);
		GAME.sToggles_Screen->draw_rectangle(0, 1, 1, 398, 398, LIGHTGOLDENRODYELLOW);
		GAME.sToggles_Screen->draw_rectangle(0, 2, 2, 397, 397, LIGHTGOLDENROD);
		
		// Drawing the Score
		GAME.gScore->draw();
		GAME.sToggles_Screen->draw_object(3, GAME.gScore->image(), 0, 0);
		
		// Drawing the Level
		rectfill(GAME.bLevel, 0, 0, GAME.bLevel->w, GAME.bLevel->h, MASK);
		set_palette((RGB *) GAME.score_palette);
		textprintf_right_ex(GAME.bLevel, GAME.score_font, GAME.bLevel->w - 10, 10, -1, -1, "%d", GAME.level);					
		

		//***************************** NOTE ******************************************
		//This section of code is very Hacky-ish, and I did it when I first started this
		//project.  It could OBVIOUSLY be better.  ;)
		GAME.sToggles_Screen->set_colors(GAME.configuration->R, GAME.configuration->G, GAME.configuration->B);
		GAME.sToggles_Screen->draw_object(4, GAME.bLevel, 0, 0);	
		
		GAME.sToggles_Screen->draw_object(15);
		GAME.sToggles_Screen->draw_object(16);
		
		
		GAME.pTime_Progress->draw();
		GAME.sToggles_Screen->draw_object(5, GAME.pTime_Progress->bDraw(), 0, 0);
		GAME.sToggles_Screen->draw_rectangle(5, 0, 0, 129, 49, LIGHTGOLDENRODYELLOW);
		GAME.sToggles_Screen->draw_rectangle(5, 1, 1, 128, 48, LIGHTGOLDENROD);

		GAME.sToggles_Screen->draw_object(6);

		//**********************************************************************************
		
		
		GAME.sToggles_Screen->draw(buffer);	
		GAME.bBoard->draw_buttons(buffer);		
		GAME.bBoard->draw_bonuses(buffer);		
		if(strcmp(GAME.configuration->level, "LOW") != 0) GAME.peToggle_Stars->draw(buffer);
		
		if(strcmp(GAME.configuration->level, "LOW") != 0) GAME.peCombo->draw(buffer);
		if(strcmp(GAME.configuration->level, "LOW") != 0) GAME.peFire->draw(buffer);
		GAME.lLightning->draw(buffer);
		

		if(!GAME.bBoard->complete() && !GAME.bBoard->ultima)
		{
			set_trans_blender(0,0,0,120);
			draw_trans_sprite(buffer, GAME.bDim, 0,0);
			GAME.pPenalty_Screen->draw(buffer);
		}
	}

	for(int m = 0; m < MAX_MESSAGES; m++)
		if(GAME.cMessages[m] != NULL)
			GAME.cMessages[m]->draw(buffer);
		
	poll_mouse();
	if(GAME.configuration->mouse_icon == 0) draw_sprite(buffer, GAME.bMouse, mouse_x, mouse_y);
	draw_sprite(screen, buffer, 0, 0);	
}

void game_shutdown()
{
	if(GAME.bBoard != NULL) GAME.bBoard->destroy();
	if(GAME.sToggles_Screen != NULL) GAME.sToggles_Screen->destroy(); //delete GAME.sToggles_Screen;
	if(GAME.wToggles_Water != NULL) GAME.wToggles_Water->destroy(); //delete GAME.wToggles_Water;	
	GAME.gHSC->destroy();
	destroy_bitmap(GAME.bDim);
	
	destroy_bitmap(GAME.bLevel);
	unload_datafile(GAME.mydat);			
	unload_datafile(GAME.dat2);	
	unload_datafile(GAME.dat3);	
	unload_datafile(GAME.dat4);	
	
	
}

char *convert_to_backslash(char *ctext)
{ 
  char *n;
  unsigned int i = 0, j = 0;
  bool last_backslash = false;
  
  n = new char[strlen(ctext) + 1];
  strcpy(n, "");
  
  j = 0;
  for(i = 0; i < strlen(ctext); i++)
  { 
    if(ctext[i] == '\\')
    {
      if(!last_backslash)
      {
        n[j++] = '/';
        last_backslash = true;
      }
    }
    else
    {
       last_backslash = false;
       n[j++] = ctext[i];
    }
  }
  n[j] = '\0';

  return n;
}



BITMAP *load_bitmap_check(char *cpath, RGB *pal)
{
	BITMAP *bTest;

        //cnew_path = convert_to_backslash(cpath);
        char *temp = new char[1024];
        ustrcpy(temp, cpath);
        fix_filename_slashes(temp);
	bTest = load_bitmap(temp, pal);
	if(!bTest)
	{
		set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
		
		allegro_message("ERROR:  Could not find/open '%s'", temp);
                delete [] temp;
		exit(0);
	}
        delete [] temp;
	return bTest;
}



BITMAP *create_bitmap_check(int width, int height)
{
	BITMAP *bTest;
	bTest = create_bitmap(width, height);
	if(!bTest)
	{
		set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
		allegro_message("ERROR:  Could not create bitmap.  Memory error.");
		exit(0);
	}

	return bTest;
}

BITMAP *create_sub_bitmap_check(BITMAP *bParent, int x, int y, int width, int height)
{
	BITMAP *bTest;
	bTest = create_sub_bitmap(bParent, x,y, width, height);
	if(!bTest)
	{
		set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
		allegro_message("ERROR:  Could not create bitmap.  Memory error.");
		exit(0);
	}

	return bTest;
}

bool screen_fade_in(int iTime)
{
	bool ret_val = false;
	BITMAP *bTransfer;

	if(gTransparency >= 255) return true;

	if(abs(ticks - gFade_Timer) > iTime)
	{
		gTransparency += 8;
		if(gTransparency > 255) 
		{
			gTransparency = 255;
			ret_val = true;
		}

		gFade_Timer = ticks;
	}
	
	bTransfer = create_bitmap_check(buffer->w, buffer->h);
	clear(bTransfer);
	set_trans_blender(0, 0, 0, gTransparency);	
	draw_trans_sprite(bTransfer, buffer, 0, 0);
	draw_sprite(screen, bTransfer, 0, 0);

	destroy_bitmap(bTransfer);

	return ret_val;
}

bool screen_fade_out(int iTime)
{
	BITMAP *bTransfer;
	bool ret_val = false;	

	if(gTransparency <= 0) return true;

	if(abs(ticks - gFade_Timer) > iTime)
	{
		gTransparency -= 8;
		if(gTransparency < 0) 
		{
			gTransparency = 0;
			ret_val = true;
		}

		gFade_Timer = ticks;
	}

	bTransfer = create_bitmap_check(buffer->w, buffer->h);
	clear(bTransfer);
	set_trans_blender(0, 0, 0, gTransparency);	
	draw_trans_sprite(bTransfer, buffer, 0, 0);
	draw_sprite(screen, bTransfer, 0, 0);

	destroy_bitmap(bTransfer);

	return ret_val;
}

//****Mappy Stuff******
/*int collided(int x, int y)
{
	BLKSTR *blockdata;
	if(y > 0 && y <= mapheight * TILE_H && x > 0 && x <= mapwidth * TILE_W)
		blockdata = MapGetBlock(x/mapblockwidth, y/mapblockheight);
	if(y <= 0 || x <= 0)
		return 1;
	if(y > mapheight * TILE_H || x > mapwidth * TILE_W)
		return 1;

	return blockdata->tl;
}*/

/************************************************************************************************

The following two functions are old code used for a much older version of Toggles.  I kept
the code merely out of nostalgia.  

*************************************************************************************************
void Title_Screen()
{
	bool quit = false;
	int x1, x2, y1, y2;
	int temp = ticks;
	
	BITMAP *bTemp = (BITMAP *) GAME.dat1[title].dat;
	BITMAP *bText = create_bitmap_check(GAME.configuration->w, GAME.configuration->h);
	BITMAP *bGUI = create_bitmap_check(GAME.configuration->w, GAME.configuration->h);
	set_palette((RGB *) GAME.score_palette);
	set_trans_blender(0,0,0, 150);
	while(!quit)
	{
		ticks++;
		if(key[KEY_ESC])
		{
			quit = true;
			GAME.quit = true;
		}
		if(key[KEY_SPACE])
		{
 			GAME.quit = false;
			quit = true;
			game_setup();
			game_level();
		}
		GAME.audio.update(1);

		poll_mouse();
		
		rectfill(bText, 0, 0, bText->w, bText->h, MASK);
		rectfill(bGUI, 0, 0, bGUI->w, bGUI->h, MASK);
		
		x1 = 190;
		x2 = 450;
		y1 = 150;
		y2 = 200;
		if(mouse_x > x1 && mouse_x < x2 && mouse_y > y1 && mouse_y < y2)
		{
			rectfill(bGUI, x1, y1, x2, y2, RED);
			if(mouse_b & 1)
			{
				GAME.quit = false;
				quit = true;
				game_setup();
				game_level();
			}
		}
		else
			rectfill(bGUI, x1, y1, x2, y2, DARKGREEN);		
		textprintf_ex(bText, GAME.score_font, 220, 155, -1, -1, "New Game");					
		rect(bText, x1, y1, x2, y2, LIGHTGOLDENRODYELLOW);
		rect(bText, x1 + 1, y1 + 1, x2 - 1, y2 - 1, LIGHTGOLDENROD);

		x1 = 190;
		x2 = 450;
		y1 = 210;
		y2 = 260;
		if(mouse_x > x1 && mouse_x < x2 && mouse_y > y1 && mouse_y < y2)
		{
			rectfill(bGUI, x1, y1, x2, y2, RED);
			if(mouse_b & 1)
				game_highscores();			
		}
		else
			rectfill(bGUI, x1, y1, x2, y2, DARKGREEN);		
		textprintf_ex(bText, GAME.score_font, 220, 215, -1, -1,"High Scores");					
		rect(bText, x1, y1, x2, y2, LIGHTGOLDENRODYELLOW);
		rect(bText, x1 + 1, y1 + 1, x2 - 1, y2 - 1, LIGHTGOLDENROD);

		x1 = 190;
		x2 = 450;
		y1 = 270;
		y2 = 320;
		if(mouse_x > x1 && mouse_x < x2 && mouse_y > y1 && mouse_y < y2)
			rectfill(bGUI, x1, y1, x2, y2, RED);
		else
			rectfill(bGUI, x1, y1, x2, y2, DARKGREEN);		
		textprintf_ex(bText, GAME.score_font, 220, 275, -1, -1, "Options");					
		rect(bText, x1, y1, x2, y2, LIGHTGOLDENRODYELLOW);
		rect(bText, x1 + 1, y1 + 1, x2 - 1, y2 - 1, LIGHTGOLDENROD);

		x1 = 190;
		x2 = 450;
		y1 = 330;
		y2 = 380;
		if(mouse_x > x1 && mouse_x < x2 && mouse_y > y1 && mouse_y < y2)
			rectfill(bGUI, x1, y1, x2, y2, RED);
		else
			rectfill(bGUI, x1, y1, x2, y2, DARKGREEN);		
		textprintf_ex(bText, GAME.score_font, 220, 335, -1, -1, "Credits");					
		rect(bText, x1, y1, x2, y2, LIGHTGOLDENRODYELLOW);
		rect(bText, x1 + 1, y1 + 1, x2 - 1, y2 - 1, LIGHTGOLDENROD);

		x1 = 190;
		x2 = 450;
		y1 = 390;
		y2 = 440;
		if(mouse_x > x1 && mouse_x < x2 && mouse_y > y1 && mouse_y < y2)
		{
			rectfill(bGUI, x1, y1, x2, y2, RED);
			if(mouse_b & 1)
			{
				quit = true;
				GAME.quit = true;	
			}
		}
		else
			rectfill(bGUI, x1, y1, x2, y2, DARKGREEN);		
		textprintf_ex(bText, GAME.score_font, 220, 395, -1, -1,"Quit");					
		textprintf_ex(bText, GAME.score_font, 550, 450, -1, -1, "V.%f", fVERSION);					
		rect(bText, x1, y1, x2, y2, LIGHTGOLDENRODYELLOW);
		rect(bText, x1 + 1, y1 + 1, x2 - 1, y2 - 1, LIGHTGOLDENROD);


		draw_sprite(buffer, bTemp, 0, 0);
		draw_trans_sprite(buffer, bGUI, 0, 0);
		draw_sprite(buffer, bText, 0, 0);
		draw_sprite(screen, buffer, 0, 0);
		
	}
	
	ticks = temp;	
	destroy_bitmap(bText);
	destroy_bitmap(bGUI);
	
}

void game_highscores()
{
	bool quit = false, lock = false;
	int x1, x2, y1, y2;
	int temp = ticks;
	
	BITMAP *bTemp = (BITMAP *) GAME.dat1[title].dat;
	BITMAP *bText = create_bitmap_check(GAME.configuration->w, GAME.configuration->h);	
	BITMAP *bGUI = create_bitmap_check(GAME.configuration->w, GAME.configuration->h);
	BITMAP *bHigh_Scores = create_bitmap(500, 350);
	set_palette((RGB *) GAME.score_palette);
	set_trans_blender(0,0,0, 155);

	//if(GAME.view_online)	
		GAME.gHSC->get_online();
	//else
		GAME.gHSC->get_local();
	int y = 0;
	while(!quit)
	{
		ticks++;
		if(key[KEY_ESC])
		{
			quit = true;
			GAME.quit = true;
		}

		if(key[KEY_DOWN] && y > -3000)
			y--;
		if(key[KEY_UP] && y < 0)
			y++;

		if(key[KEY_PGUP] && y < 0)
			y += 10;
		if(key[KEY_PGDN] && y > -3000)
			y -= 10;
		poll_mouse();
		
		rectfill(bText, 0, 0, bText->w, bText->h, MASK);
		rectfill(bGUI, 0, 0, bGUI->w, bGUI->h, MASK);
		

		x1 = 0;
		x2 = bHigh_Scores->w;
		y1 = 0;
		y2 = bHigh_Scores->h;
		rectfill(bHigh_Scores, 0, 0, bHigh_Scores->w, bHigh_Scores->h, BLACK);
		rect(bHigh_Scores, x1, y1, x2, y2, LIGHTGOLDENRODYELLOW);
		rect(bHigh_Scores, x1 + 1, y1 + 1, x2 - 1, y2 - 1, LIGHTGOLDENROD);

		x1 = 70;
		x2 = 200;
		y1 = 440;
		y2 = 475;
		if(mouse_x > x1 && mouse_x < x2 && mouse_y > y1 && mouse_y < y2)
		{
			rectfill(bGUI, x1, y1, x2, y2, RED);
			if(mouse_b & 1 && GAME.view_online == false)
				GAME.gHSC->get_local();
			if(mouse_b & 1 && GAME.view_online == true)
				GAME.gHSC->get_online();
		}
		else
			rectfill(bGUI, x1, y1, x2, y2, DARKGREEN);		
		textprintf_ex(bText, GAME.score_font, x1 + 10, y1 + 2, -1, -1, "Update");					
		rect(bText, x1, y1, x2, y2, LIGHTGOLDENRODYELLOW);
		rect(bText, x1 + 1, y1 + 1, x2 - 1, y2 - 1, LIGHTGOLDENROD);

		x1 = 210;
		x2 = 410;
		y1 = 440;
		y2 = 475;
		if(mouse_x > x1 && mouse_x < x2 && mouse_y > y1 && mouse_y < y2)
		{
			rectfill(bGUI, x1, y1, x2, y2, RED);
			if(mouse_b & 1)
				quit = true;
		}
		else
			rectfill(bGUI, x1, y1, x2, y2, DARKGREEN);		
		textprintf_ex(bText, GAME.score_font, x1 + 10, y1 + 2, -1, -1, "Main Menu");					
		rect(bText, x1, y1, x2, y2, LIGHTGOLDENRODYELLOW);
		rect(bText, x1 + 1, y1 + 1, x2 - 1, y2 - 1, LIGHTGOLDENROD);

		x1 = 420;
		x2 = 570;
		y1 = 440;
		y2 = 475;
		if(mouse_x > x1 && mouse_x < x2 && mouse_y > y1 && mouse_y < y2)
		{
			rectfill(bGUI, x1, y1, x2, y2, RED);
			if(mouse_b & 1)
			{
				if(lock == false)
				{
					if(GAME.view_online) GAME.view_online = false;
					else GAME.view_online = true;
					lock = true;
				}
			}
			else
				lock = false;
		}
		else
			rectfill(bGUI, x1, y1, x2, y2, DARKGREEN);		
		if(GAME.view_online)
			textprintf_ex(bText, GAME.score_font, x1 + 10, y1 + 2, -1, -1, "Online");					
		else
			textprintf_ex(bText, GAME.score_font, x1 + 10, y1 + 2, -1, -1, "Local");					
		rect(bText, x1, y1, x2, y2, LIGHTGOLDENRODYELLOW);
		rect(bText, x1 + 1, y1 + 1, x2 - 1, y2 - 1, LIGHTGOLDENROD);

		x1 = 70;
		x2 = 170;
		y1 = 30;
		y2 = 90;
		rectfill(bGUI, x1, y1, x2, y2, DARKGREEN);		
		textprintf_ex(bText, font, x1 + 10, y1 + 2, GREEN, -1, "Press Up");					
		textprintf_ex(bText, font, x1 + 10, y1 + 12, GREEN, -1,"and Down");
		textprintf_ex(bText, font, x1 + 10, y1 + 22, GREEN, -1, "Arrow Keys");
		textprintf_ex(bText, font, x1 + 10, y1 + 32, GREEN, -1,"or");					
		textprintf_ex(bText, font, x1 + 10, y1 + 42, GREEN, -1,"Page UP,");
		textprintf_ex(bText, font, x1 + 10, y1 + 52, GREEN, -1, "Page Down");
		rect(bText, x1, y1, x2, y2, LIGHTGOLDENRODYELLOW);
		rect(bText, x1 + 1, y1 + 1, x2 - 1, y2 - 1, LIGHTGOLDENROD);




		if(GAME.view_online)
			GAME.gHSC->draw_online(bHigh_Scores, y,40);
		else
			GAME.gHSC->draw(bHigh_Scores, y, 40);
				
		draw_sprite(buffer, bTemp, 0, 0);		
		draw_sprite(buffer, bHigh_Scores, 70, 90);		
		draw_trans_sprite(buffer, bGUI, 0, 0);
		draw_sprite(buffer, bText, 0, 0);
		draw_sprite(screen, buffer, 0, 0);
		
	}		
	
	destroy_bitmap(bText);
	destroy_bitmap(bHigh_Scores);
	destroy_bitmap(bGUI);
	
}
*/

