/*********************************************************************************************/
/*                                                                                           */
/* Main Game Code                                                                            */
/*                                                                                           */
/*********************************************************************************************/

#include "standard.h"
#include "global.h"
#include "winmain.h"
#include "init.h"
#include "file.h"
#include "hwrender.h"
#include "input.h"
#include "smain.h"
#include "utils.h"
#include "picture.h"
#include "output.h"

#include "../game/cinema.h"
#include "../game/gameflow.h"
#include "../game/sound.h"
#include "../game/savegame.h"
#include "../game/title.h"
#include "../game/demo.h"
#include "../game/inventry.h"
#include "../game/control.h"
#include "../game/setup.h"
#include "../game/objects.h"
#include "../game/invfunc.h"
#include "../game/lara.h"
#include "../game/laraanim.h"

/********************************* GLOBAL VARIABLES ******************************************/

char exit_message[128] = "";

#define TITLE_DEMO_WAIT	30*30
int title_loaded=0;

/*** locals ***/

void		S_SaveSettings			(void);
void		S_LoadSettings			(void);

/*********************************** FUNCTION CODE *******************************************/
int GameMain(void)
{
	
	
	// Called by WinMain and only returns when game wants to shut down
	sint32 option, level_number, ok;
	
	game_hires = hires_flag = 0;
	game_sizer = screen_sizer = 1.0;
	
	if (!S_InitialiseSystem())
		return (0);

#ifdef DEMO
	if (!GF_LoadScriptFile("data\\demoPC.dat"))
//	if (!GF_LoadScriptFile("data\\2levtest.dat"))
//	if (!GF_LoadScriptFile("data\\1levtest.dat"))
#else
	if (!GF_LoadScriptFile("data\\tombPC.dat"))
#endif
		S_ExitSystem("GameMain: could not load script file");

	
	SOUND_Init();
		
	InitialiseStartInfo();
	
	S_FrontEndCheck(&savegame, sizeof(SAVEGAME_INFO));

	S_LoadSettings();
	
	/* Allocate our game memory now */
	hires_flag = -1;
	malloc_buffer = (char *)GlobalAlloc(GMEM_FIXED, MALLOC_SIZE);
	if (!malloc_buffer)
	{
		lstrcpy(exit_message, "GameMain: could not allocate malloc_buffer");
		return (0);
	}
	
	hires_flag = 0;
	TempVideoAdjust(1, 1.0);

	Log(LT_Info,"Entering frontend sequence...");

#ifndef DUDE_DEMO
#ifndef DEMO
	// display legal shit to keep lawyers happy
/*
	S_UpdateInput();
	GtDisableFullScreenWindowedToggle=true;
	S_DisplayPicture("data\\legal.pcx",false);
	S_InitialisePolyList(SIPL_DONT_CLEAR_SCREEN);
	S_CopyBufferToScreen();
	S_OutputPolyList();
	S_DumpScreen();
	FadeToPal(30, game_palette);
	S_Wait(6*30, true); // any game key override
	S_FadeToBlack();
	S_DontDisplayPicture();
	GtDisableFullScreenWindowedToggle=false;
*/
#endif
#endif

	int n=GF_DoFrontEndSequence();
	if (GtWindowClosed)
		return 1;
	if (n==1)
	{
		lstrcpy(exit_message, "GameMain: failed in GF_DoFrontEndSequence()");
		return (0);
	}
//	S_FadeToBlack();
	
	title_loaded = 0;

#ifdef GAMEDEBUG
	if ( cutscene_play>=0 )
	{
		option = StartCinematic(cutscene_play);
		return (0);
	}
#endif

	option = gameflow.firstOption;
	
	ok = 1;
	while (ok)
	{
		level_number = option & 0xff;
		option &= ~0xff;
		
		switch(option)
		{
		case EXIT_TO_OPTION:
		case EXIT_TO_TITLE:
			if ( !gameflow.title_disabled )
			{
				Log(LT_Info,"Entering TitleSequence");
				option = TitleSequence();
				GF_StartGame = 1;
			}
			else if (gameflow.title_replace>=0 &&
				     gameflow.title_replace!=EXIT_TO_TITLE)
			{
				option = gameflow.title_replace;
			}
			else
			{
				lstrcpy(exit_message, "GameMain Failed: Title disabled & no replacement");
				return (0);
			}
			break;
		case STARTGAME:
#ifdef GAMEDEBUG
			if (0)
			{
				GF_DoStorySoFar(level_number);
				option = EXIT_TO_TITLE;
			}
			else 
#endif
				if ( gameflow.singlelevel>=0 )
				option = GF_DoLevelSequence(gameflow.singlelevel, IL_NORMAL);
			else
			{
				if (level_number <= gameflow.num_levels)
				{
#ifdef GAMEDEBUG
					if (UT_FindArg("record"))
						option = StartSaveDemo(level_number);
					else if (UT_FindArg("demo"))
						option = StartDemo(level_number);
					else
#endif
					 	option = GF_DoLevelSequence(level_number, IL_NORMAL);
					break;
				}
				else
				{
					wsprintf(exit_message, "GameMain: STARTGAME with invalid level number (%d)",level_number);
					return (0);
				}
			}
			break;

		case STARTSAVEDGAME:
			S_LoadGame(&savegame, sizeof(SAVEGAME_INFO),level_number);
			level_number = savegame.current_level;
			if ( level_number <= gameflow.num_levels )
				option = GF_DoLevelSequence(level_number, IL_SAVED);
			else
			{
				wsprintf(exit_message, "GameMain: STARTSAVEDGAME with invalid level number (%d)",level_number);
				return (0);
			}
			break;
		case STARTCINE:
			StartCinematic(level_number);
			option = EXIT_TO_TITLE;
			break;
		case STARTDEMO:
			/* -1 as demo level means do the next one in the demo playback list */
			option = DoDemoSequence( -1 );
//			option = StartDemo(-1);
			break;
		case LEVELCOMPLETE:
			option = LevelCompleteSequence(level_number);
			break;
		case EXITGAME:
			ok = 0;
			break;
		default:
			ok = 0;
			break;
		}
	}
//#ifdef GAMEDEBUG	
//	wsprintf(exit_message, "EXITGAME");
//#endif

	S_SaveSettings();

	ShutdownGame();
	
	return 1;
}



extern "C" void DoInventoryPicture()
{
//	App.lpBackBuffer->Blt(NULL,App.lpPictureBuffer,NULL,NULL,NULL);
	
	DrawPicture();
	
	HWR_EnableZBuffer(true,true);
}



sint32 TitleSequence(void)
{
	T_InitPrint();
	
	TempVideoAdjust(1, 1.0);

	noinput_count = 0;
	if (!title_loaded)
	{
		if (!InitialiseLevel(0,IL_TITLE))
			return(EXITGAME);
		title_loaded = 1;
	}

	LoadPicture(GF_titlefilenames[GFT_TITLEPIC],App.lpPictureBuffer,1);
	FadePictureUp();

	// Start CD track (after piccy loaded)
	if (gameflow.title_track)
		S_CDPlay(gameflow.title_track,1);

	Log(LT_Info,"TitleSequence Loaded");

	Display_Inventory(INV_TITLE_MODE);
	
	FadePictureDown();
	
	S_CDStop();
	
	if (reset_flag)
	{
		reset_flag = 0;
		return(STARTDEMO);
	}
	
	if (Inventory_Chosen==PHOTO_OPTION)
		return(STARTGAME|LV_GYM);
	
	if (Inventory_Chosen==PASSPORT_OPTION)
	{
		if (Inventory_ExtraData[0]==0)	// First Page (LOAD)
		{
//			LoadPicture(GF_picfilenames[GF_LoadingPic],App.lpPictureBuffer,1);
//			DoInventoryPicture();
//			FadePictureUp();

			Inv_RemoveAllItems();
			S_LoadGame(&savegame, sizeof(SAVEGAME_INFO), Inventory_ExtraData[1]);

			return(STARTSAVEDGAME|Inventory_ExtraData[1]);
		}
		else if ( Inventory_ExtraData[0]==1)            // Middle page (START)
		{
	

		
//			LoadPicture(GF_picfilenames[GF_LoadingPic],App.lpPictureBuffer,1);
//			DoInventoryPicture();
//			FadePictureUp();


			InitialiseStartInfo();
		
			if (gameflow.play_any_level)
				return(STARTGAME|Inventory_ExtraData[1]+1);
			else
				return(STARTGAME|LV_FIRSTLEVEL);
		}
	}
	return(EXITGAME);
}


void CheckCheatMode(void)
{
	static int cheat_mode = 0, cheat_flare, cheat_turn;
	static sint16 as, cheat_angle;

	if (CurrentLevel==LV_GYM || CurrentLevel==(uint32)(gameflow.num_levels-gameflow.num_demos-1))
			return;

	/* Cheat mode enable */
	as = lara_item->current_anim_state;
	switch (cheat_mode)
	{
	case 0:
		// one step forward...
		if (as == AS_WALK)
			cheat_mode = 1;
		break;
	case 1:
		// check for flare; if none ready, then better not to continue
		cheat_flare = (lara.gun_type == LG_FLARE);

		if (as != AS_WALK)
			cheat_mode = (as == AS_STOP)? 2 : 0;
		break;
	case 2:
		// one step back...
		if (as != AS_STOP)
			cheat_mode = (as == AS_BACK)? 3 : 0;
		break;
	case 3:
		if (as != AS_BACK)
			cheat_mode = (as == AS_STOP)? 4 : 0;
		break;
	case 4:
		if (as != AS_STOP)
		{
			cheat_angle = lara_item->pos.y_rot;
			cheat_turn = 0;
			if (as == AS_TURN_L)
				cheat_mode = 5;
			else if (as == AS_TURN_R)
				cheat_mode = 6;
			else
				cheat_mode = 0;
		}
		break;
	case 5:
		// turn on the spot (thrice)...
		if (as != AS_TURN_L && as != AS_FASTTURN)
			cheat_mode = (cheat_turn < -0x17000)? 7 : 0;
		else
		{
			cheat_turn += (sint16)(lara_item->pos.y_rot - cheat_angle);
			cheat_angle = lara_item->pos.y_rot;
		}
		break;
	case 6:
		if (as != AS_TURN_R && as != AS_FASTTURN)
			cheat_mode = (cheat_turn > 0x17000)? 7 : 0;
		else
		{
			cheat_turn += (sint16)(lara_item->pos.y_rot - cheat_angle);
			cheat_angle = lara_item->pos.y_rot;
		}
		break;
	case 7:
		// and jump!
		if (as != AS_STOP)
		{
			if (as == AS_COMPRESS)
			{
				cheat_mode = 8;
			}
			else
				cheat_mode = 0;
		}
		break;
	case 8:
		// forward to complete level, back to get all weapons
		if (lara_item->fallspeed > 0)
		{	
			// check for flare again, else there'll be trouble
			if (cheat_flare)
				cheat_flare = (lara.gun_type == LG_FLARE);

			if (as == AS_FORWARDJUMP && cheat_flare)
			{
				level_complete = 1;
				cheat_mode = 0;
			}
			else if (as == AS_BACKJUMP && cheat_flare)
			{
				int i;
				Inv_AddItem(HARPOON_ITEM);
				Inv_AddItem(ROCKET_GUN_ITEM);
				Inv_AddItem(M16_ITEM);
				Inv_AddItem(SHOTGUN_ITEM);
				Inv_AddItem(MAGNUM_ITEM);
				Inv_AddItem(UZI_ITEM);
				lara.shotgun.ammo = 500;
				lara.magnums.ammo = 500;
				lara.uzis.ammo = 5000;
				lara.rocket.ammo = 5000;
				lara.m16.ammo = 5000;
				lara.harpoon.ammo = 5000;
				for (i=0; i<50; i++)
				{
					Inv_AddItem(MEDI_ITEM);
					Inv_AddItem(BIGMEDI_ITEM);
					Inv_AddItem(FLARE_ITEM);
				}
				SoundEffect(7, NULL, SFX_ALWAYS);
			}
			else if (as == AS_FORWARDJUMP || as == AS_BACKJUMP)
			{
				// no flare, no joy at all
				ExplodingDeath(lara.item_number, 0xffffffff, 1);
				lara_item->hit_points = 0;
				lara_item->flags |= ONESHOT; // flag Lara as invisible
			}
			cheat_mode = 0;
		}
		break;
	default:
		cheat_mode = 0;
	}
}

/*
DefLocalString(GameSubKey,"Game");
DefValueName(MusicVolume);
DefValueName(SoundFXVolume);
DefValueName(Layout);
DefValueName(DetailLevel);
DefValueName(Hires);
DefValueName(Sizer);
*/

void S_SaveSettings(void)
{
/*
	SE_OpenRegistry(LocalString(GameSubKey));
	REG_WriteValue(ValueName(MusicVolume),int(Option_Music_Volume));
	REG_WriteValue(ValueName(SoundFXVolume),int(Option_SoundFX_Volume));
	REG_WriteValue(ValueName(DetailLevel),int(detail_level));
//	REG_WriteValue(ValueName(Hires),int(game_hires));
	REG_WriteValue(ValueName(Sizer),game_sizer);
	REG_WriteValue(ValueName(Layout),(void*)(layout+1),sizeof(sint16)*14);
	SE_CloseRegistry();
*/
	FILE* fp;

	fp = fopen("config.dat","wb+");
	if(fp != NULL)
	{
		fwrite( (void*) (layout+1), sizeof(sint16),15,fp);	
		fclose(fp);
	}
}


void S_LoadSettings(void)
{
	FILE* fp;
	fp = fopen("config.dat","rb");
	if(fp!= NULL)
	{
		fread((void*) (layout+1),sizeof(sint16),15,fp);
		fclose(fp);
	}

/*
	SE_OpenRegistry(LocalString(GameSubKey));
	int nValue;
	REG_ReadValue(ValueName(MusicVolume),nValue,165);
	Option_Music_Volume=(sint16)nValue;
	REG_ReadValue(ValueName(SoundFXVolume),nValue,10);
	Option_SoundFX_Volume=(sint16)nValue;
	REG_ReadValue(ValueName(DetailLevel),detail_level,1);
//	REG_ReadValue(ValueName(Hires),game_hires,0);
	REG_ReadValue(ValueName(Sizer),game_sizer,1.0);
	REG_ReadValue(ValueName(Layout),(void*)(layout+1),sizeof(sint16)*14);
	SE_CloseRegistry();
	
	S_SoundSetMasterVolume(Option_SoundFX_Volume*6 + 4);
//#ifdef THE_REST
	if (Option_Music_Volume)
		S_CDVolume(Option_Music_Volume * 25 + 5);
	else
		S_CDVolume(0);
//#endif

*/  
}
