//****************************************************************************************************
// 	Main pack stage script
//	Author: Helepolis
//	Version: 2.0
//
//	This is almost the heart of the game, controlling menu flows, UI, important values and such.
//	I will warn you, it is a maze. I tried keeping it all organized but it is impossible as the game grows.
//	Well, I was also learning a lot in the meanwhile. 
//
//	Library:
// 		initializeStage				- Initializes the stage by retrieving values from previous menus and processing them.
// 		gameStageListener			- Heartbeat task to keep listening to the DanceContestStage whether a CloseStgScene has been called.
//		gameStoryScene				- A detour to in order to keep control of menu order. Kicks off initializeStage task.
//		gameStgPractiseScene		- A detour to in order to keep control of menu order. Kicks off initializeStage task.
//		gameSpellPractiseScene		- A detour to in order to keep control of menu order. Kicks off initializeStage task.
//		gameStgClearScene			-
//		gameClearScene				-
//		gameAllClearScene			-
//		gameEndScene				- Ending menu (menu_end.txt), launched when stage play has been aborted for a specific reason.
// 		pauseGame					- Function to pause the game (menu_pause.txt), launched when the player hits the ESC key during play.
// 		snapshotScreen				- Function to snapshot the screen as still.
//
//****************************************************************************************************

SetCommonData("mainPackID", GetOwnScriptID);			// used for EVENT_USER method

let triggerContinueMenu = false;
let waitForContinueMenu = false;

#include "script/thdcs/functions/function_loaddata.txt"
#include "script/thdcs/menu/menu_title.txt"
#include "script/thdcs/functions/const_sound.txt"

@Initialize {
	SetAutoDeleteObject(true);
	packMain;
	SetScriptResult("");
}

@Event {
	if(GetEventType() == EV_USER+2000) {
        triggerContinueMenu = true;
	}
}

@MainLoop { yield; }
@Finalize { } 

//------------------------------------------------------------------------------------------------------------------------------------------
task packMain {
	if(GetAreaCommonData("game", "menuFlow", 0) == 0) { gameStoryScene; }
	else if(GetAreaCommonData("game", "menuFlow", 0) == 3) { gameStgPractiseScene; }
	else if(GetAreaCommonData("game", "menuFlow", 0) == 4) { gameSpellPractiseScene; }
	else if(GetAreaCommonData("game", "menuFlow", 0) == 5) { gameReplayScene; }
}	

//------------------------------------------------------------------------------------------------------------------------------------------
// Stage initialize task
task initializeStage {
	StopMusic(BGM_TITLE);	
	
	let pathBorder = "script/player/dcs_player/player_border.txt";
	let pathMagic = "script/player/dcs_player/player_magic.txt";

	SetCommonData("remainingContinues", 0);
	SetCommonData("hasUsedContinue", false);
	SetCommonData("hasLostInSpellPractise", false);
	SetCommonData("holdStageHeartBeat", false);

	let TEAM_BORDER = 0;
	let TEAM_MAGIC = 1;	

	InitializeStageScene;
	
	// If this is a replay mode
	if(GetAreaCommonData("game","menuFlow",0) == 5) { 
		SetStageReplayFile(GetCommonData("replayFile", "NULL"));
		let initRepDif = GetCommonData("replayDifficulty", 0);
		let initRepMode = GetCommonData("replayMode", "NULL");
		let stgIndex = 0;

		if(initRepMode == "Spl Prac") { 
			stgIndex = 0; 	
		} 
		else { 
			stgIndex = GetCommonData("replayStgIndex",0); 
		}	
		SetStageIndex(stgIndex);	
	}	
	// If spell practise mode 
	else if(GetAreaCommonData("game", "menuFlow", 0) == 4) {
		let getTeam = GetAreaCommonData("game", "team", 0);

		alternative(getTeam)
		case(TEAM_BORDER) { 
			SetStagePlayerScript(pathBorder);
		}
		case(TEAM_MAGIC) {
			SetStagePlayerScript(pathMagic);
		}	
		SetStageIndex(0);		
	}
	else {
		let getTeam = GetAreaCommonData("game", "team", 0);
		let stgIndex = GetAreaCommonData("game", "stageNum", 1);

		alternative(getTeam)
		case(TEAM_BORDER) { 
			SetStagePlayerScript(pathBorder);
		}
		case(TEAM_MAGIC) {
			SetStagePlayerScript(pathMagic);
		}
		SetStageIndex(stgIndex);					
	}

	SetStageMainScript("script/thdcs/DanceContestStage.txt");		
	StartStageScene;
	gameStageListener();
}

//------------------------------------------------------------------------------------------------------------------------------------------
// Main heart beat for this pack.			
task gameStageListener() {
	loop {
	    if(!IsReplay && triggerContinueMenu) {
	        triggerContinueMenu = false;
            waitForContinueMenu = true;

            StopMusic(GetAreaCommonData("sound","song",0));
            PlaySFX(SFX_MIX01);
            PlayMusic(BGM_PAUSE);
            musicRestartEnable(BGM_PAUSE,1);

            if(GetCommonData("replayMode","NULL") == "Spl Prac") {
                SetAreaCommonData("game","fightHina",false);
                SetAreaCommonData("game","fightIku",false);
                SetAreaCommonData("game","fightTewi",false);
            }

            gameEndSceneWithContinues();

            while(waitForContinueMenu) { yield; }

            let currentRemainingContinues = GetCommonData("remainingContinues", 0);
            currentRemainingContinues--;
            SetCommonData("remainingContinues", currentRemainingContinues);
            SetCommonData("hasUsedContinue", true);
            SetCommonData("holdStageHeartBeat", false);

			musicRestartEnable(GetAreaCommonData("sound", "song",0), 1);
			PlayMusic(GetAreaCommonData("sound", "song", 0));

            waitForContinueMenu = false;
	    }

		if(GetVirtualKeyState(VK_PAUSE) == KEY_PUSH) {
			// If this is a regular mode without replay.
			if(!IsReplay) { 
				let choice = pauseGame();
				alternative(choice) 
				case(RESULT_RETRY) {
					SetCommonData("isDialogue", false);

					musicRestartEnable(GetAreaCommonData("sound", "song", 0), 0);
					StopAllSFX(0);

					TerminateStageScene;
					SetAreaCommonData("game", "stageNum", 1);
					initializeStage;
					return;
				}
				case(RESULT_END) {
					SetCommonData("isDialogue", false);

					musicRestartEnable(GetAreaCommonData("sound", "song", 0), 0);
					StopAllSFX(0);
					PlayMusic(BGM_TITLE);

					TerminateStageScene;
					SetAreaCommonData("game", "stageNum",1);
					if(GetAreaCommonData("game", "menuFlow", 0) == 0) {
						SetScriptResult("ENDSTORY"); 
						CloseScript(GetOwnScriptID); 	
					}
					if(GetAreaCommonData("game", "menuFlow", 0) == 3) {
						SetScriptResult("ENDSTGPRACTISE"); 
						CloseScript(GetOwnScriptID); 					
					}
					if(GetAreaCommonData("game", "menuFlow", 0) == 4) {
						SetScriptResult("ENDSPELLPRACTISE"); 
						CloseScript(GetOwnScriptID); 
					}
					break;
				}		
			}
			// If this is a replay mode.
			else {		
				let choice = pauseGameReplay();
				alternative(choice) 
				case(RESULT_CANCEL) {
					musicRestartEnable(GetAreaCommonData("sound", "song", 0), 1);
				}
				case(RESULT_END) {			
					SetCommonData("isDialogue",false);
					StopMusic(GetAreaCommonData("sound", "song", 0));
					musicRestartEnable(GetAreaCommonData("sound", "song", 0), 0);
					StopAllMusic(0);
					StopAllSFX(0);
					TerminateStageScene;
					PlayMusic(BGM_TITLE);	
					SetAreaCommonData("game", "fightHina", false);
					SetAreaCommonData("game", "fightIku", false);
					SetAreaCommonData("game", "fightTewi", false);
					SetScriptResult("ENDREPLAYPLAY"); 
					CloseScript(GetOwnScriptID); 
					break;
				}
			}
		}

		// keep checking the current stage state
		let stageSceneState = GetStageSceneState;
		if(stageSceneState == STAGE_STATE_FINISHED) { 
			let stageSceneResult = GetStageSceneResult;
			
			alternative(stageSceneResult)
			case(STAGE_RESULT_CLEARED) {
				musicRestartEnable(GetAreaCommonData("sound","song",0),0);
				StopMusic(GetAreaCommonData("sound","song",0));
				StopAllSFX(0);
				if(GetAreaCommonData("game","menuFlow",0) == 0) { 			
					gameAllClearScene; 
				}
				if(GetAreaCommonData("game","menuFlow",0) == 3) { 				
					gameClearScene; 
				}		
				if(GetAreaCommonData("game","menuFlow",0) == 4)	{ 				
					gameClearScene; 
				} 
				if(GetAreaCommonData("game","menuFlow",0) == 5)	{ 	
					if(GetCommonData("replayMode","NULL") == "Spl Prac") {
						SetAreaCommonData("game","fightHina",false);
						SetAreaCommonData("game","fightIku",false);			
						SetAreaCommonData("game","fightTewi",false);					
					}
					SetScriptResult("ENDREPLAYPLAY"); 
					CloseScript(GetOwnScriptID); 
				} 				
				break;
			}
			case(STAGE_RESULT_PLAYER_DOWN) {
				if(GetCommonData("replayMode","NULL") == "Spl Prac") {
					SetAreaCommonData("game","fightHina",false);
					SetAreaCommonData("game","fightIku",false);			
					SetAreaCommonData("game","fightTewi",false);					
				}
				StopAllSFX(0);
				TerminateStageScene;
				gameEndScene;
				break;
			}
			case(STAGE_RESULT_BREAK_OFF) {
				StopMusic(GetAreaCommonData("sound","song",0));
				StopAllSFX(0);
                TerminateStageScene;
				break;
			}
		}
		yield;
	}
}	

//------------------------------------------------------------------------------------------------------------------------------------------
// STORY MODE 
task gameStoryScene() { 	
	initializeStage; 		
}

//------------------------------------------------------------------------------------------------------------------------------------------
// STAGE PRACTISE 
task gameStgPractiseScene() {
	initializeStage; 								
}

//------------------------------------------------------------------------------------------------------------------------------------------
// SPELL PRACTISE
task gameSpellPractiseScene() {
	initializeStage;
}

//------------------------------------------------------------------------------------------------------------------------------------------
// STAGE clear scene 
task gameStgClearScene() {
	// Prepare stage jump or all clear
	let stgIndex = GetAreaCommonData("game","stageNum",1);
	if(stgIndex == 3) { 
		SetAreaCommonData("game","stageNum",1); 
		SaveCommonDataAreaA1("game");		
		gameAllClearScene; 
	} 	
	if(stgIndex < 3) { 
		initializeStage;
	} 
}

//------------------------------------------------------------------------------------------------------------------------------------------
// PRACTISE STAGE or SPELL PRACTISE clear scene. 
task gameClearScene() {
	let path = "";
	FinalizeStageScene;
	
	// Regardless, allow the player to save replay
	let rootDir = GetModuleDirectory;
	path = rootDir ~ "script/thdcs/menu/menu_end.txt";
	let id = LoadScript(path);
	StartScript(id);

	// Hold this function while the menu_end.txt is running.
	while(!IsCloseScript(id)) {
		yield;
	}	
	
	// Get the result from the menu_end.txt and return in this function
	let value = GetScriptResult(id);
	alternative(value)
	case(RESULT_SAVE_REPLAY) {
		path = rootDir ~ "script/thdcs/menu/menu_replaysave.txt";
		let id = LoadScript(path);
		StartScript(id);

		// Hold this case while the menu_replaysave.txt is running.
		while(!IsCloseScript(id)) {
			yield;
		}
		if(GetAreaCommonData("game","menuFlow",0) == 0) { 
			SetScriptResult("ENDSTORY"); 
			CloseScript(GetOwnScriptID); 
		}		
		if(GetAreaCommonData("game","menuFlow",0) == 3) { 	
			SetScriptResult("ENDSTGPRACTISE"); 
			CloseScript(GetOwnScriptID); 	
		}
		if(GetAreaCommonData("game","menuFlow",0) == 4) { 		
			SetScriptResult("ENDSPELLPRACTISE"); 
			CloseScript(GetOwnScriptID); 
		}
	}
	case(RESULT_END) {
		PlayMusic(BGM_TITLE);	
		TerminateStageScene;	
		if(GetAreaCommonData("game","menuFlow",0) == 0) { 
			SetScriptResult("ENDSTORY"); 
			CloseScript(GetOwnScriptID); 
		}
		if(GetAreaCommonData("game","menuFlow",0) == 3) { 	
			SetScriptResult("ENDSTGPRACTISE"); 
			CloseScript(GetOwnScriptID); 	
		}
		if(GetAreaCommonData("game","menuFlow",0) == 4) { 		
			SetScriptResult("ENDSPELLPRACTISE"); 
			CloseScript(GetOwnScriptID); 
		}
	}
	case(RESULT_RETRY) {	
		initializeStage;
	}
}

//------------------------------------------------------------------------------------------------------------------------------------------
// ALL CLEAR scene which is only launched if the game is in Story Mode and fully cleared. 
// Will launch a special ending dialogue script first then the regular game over screen.
task gameAllClearScene() {
	StopAllSFX(0);
	SetCommonData("allClear",true);
	let path = "";
	FinalizeStageScene;
	PlayMusic(BGM_END);
	
	let rootDir = GetModuleDirectory;
	path = rootDir ~ "script/thdcs/menu/menu_clear.txt";
	let id = LoadScript(path);
	StartScript(id);

	// Hold this function while the menu_end.txt is running.
	while(!IsCloseScript(id)) {
		yield;
	}	
	
	StopMusic(BGM_END);
	path = rootDir ~ "script/thdcs/menu/menu_replaysave.txt";
	id = LoadScript(path);
	StartScript(id);

	// Hold this case while the menu_replaysave.txt is running.
	while(!IsCloseScript(id)) {
		yield;
	}		

	SetCommonData("allClear",false);

	// Return to the main title screen
	titleScreenHandler();
}

//------------------------------------------------------------------------------------------------------------------------------------------
// Ending task when player is dead but HAS remaining continues. launches the menu_end to decide what to do.
task gameEndSceneWithContinues() {
    snapshotScreen();

	// Pause the stage screen
	PauseStageScene(true);

	let path = "";

	// If this is a replay playing and it 'ended' then make sure to return instantly to the replay screen again.
	if(IsReplay) {
	    PauseStageScene(false);
	    musicRestartEnable(GetAreaCommonData("sound", "song", 0), 0);
        StopAllMusic(0);
        StopAllSFX(0);
	    SetCommonData("stopStageHeartBeat", true);
	    loop(180) { yield; }
		SetScriptResult("ENDREPLAYPLAY");
		CloseScript(GetOwnScriptID);
		break;
	}

	// Get the absolute rootdir where the exe is located then path towards the menu.
	let rootDir = GetModuleDirectory;
	path = rootDir ~ "script/thdcs/menu/menu_end.txt";
	let id = LoadScript(path);
	StartScript(id);

	// Hold this function while the menu_end.txt is running.
	while(!IsCloseScript(id)) {
		yield;
	}

	// Get the result from the menu_end.txt and return in this function
	let value = GetScriptResult(id);
	alternative(value)
	case(RESULT_CANCEL) {
	    waitForContinueMenu = false;
		PauseStageScene(false);
	}
	case(RESULT_SAVE_REPLAY) {
	    PauseStageScene(false);
	    SetCommonData("stopStageHeartBeat", true);
	    yield;
        TerminateStageScene;
	    FinalizeStageScene;

		path = rootDir ~ "script/thdcs/menu/menu_replaysave.txt";
		let id = LoadScript(path);
		StartScript(id);

		// Hold this case while the menu_replaysave.txt is running.
		while(!IsCloseScript(id)) {
			yield;
		}
		PlayMusic(BGM_TITLE);
		SetAreaCommonData("game","stageNum",1);

		if(GetAreaCommonData("game","menuFlow",0) == 0) {
			SetScriptResult("ENDSTORY");
			CloseScript(GetOwnScriptID);
		}
		if(GetAreaCommonData("game","menuFlow",0) == 3) {
			SetScriptResult("ENDSTGPRACTISE");
			CloseScript(GetOwnScriptID);
		}
		if(GetAreaCommonData("game","menuFlow",0) == 4) {
			SetScriptResult("ENDSPELLPRACTISE");
			CloseScript(GetOwnScriptID);
		}
	}
	case(RESULT_END) {
	    PauseStageScene(false);
	    SetCommonData("stopStageHeartBeat", true);
	    musicRestartEnable(GetAreaCommonData("sound", "song", 0), 0);
        StopAllMusic(0);
        StopAllSFX(0);
        yield;
	    TerminateStageScene;
        FinalizeStageScene;

		PlayMusic(BGM_TITLE);
		SetAreaCommonData("game","stageNum",1);
		//SaveCommonDataAreaA1("game");
		if(GetAreaCommonData("game","menuFlow",0) == 0) {
			SetScriptResult("ENDSTORY");
			CloseScript(GetOwnScriptID);
		}
		if(GetAreaCommonData("game","menuFlow",0) == 3) {
			SetScriptResult("ENDSTGPRACTISE");
			CloseScript(GetOwnScriptID);
		}
		if(GetAreaCommonData("game","menuFlow",0) == 4) {
			SetScriptResult("ENDSPELLPRACTISE");
			CloseScript(GetOwnScriptID);
		}
	}
	case(RESULT_RETRY) {
	    PauseStageScene(false);
	    SetCommonData("stopStageHeartBeat", true);
	    yield;

	    SetCommonData("remainingContinues", 2);
        StopMusic(GetAreaCommonData("sound","song",0));
        if(GetAreaCommonData("game", "menuFlow", 0) == 4) {
            musicRestartEnable(GetAreaCommonData("sound", "song", 0), 1);
        } else {
            musicRestartEnable(GetAreaCommonData("sound", "song", 0), 0);
        }
        initializeStage;
	}
}

//------------------------------------------------------------------------------------------------------------------------------------------
// Ending task when player is dead which launches the menu_end to decide what to do.
task gameEndScene() {

	let path = "";
	
	// If this is a replay playing and it 'ended' then make sure to return instantly to the replay screen again.
	if(IsReplay) {	
		SetScriptResult("ENDREPLAYPLAY"); 
		CloseScript(GetOwnScriptID); 
		break;
	}
		
	FinalizeStageScene;
	
	// Get the absolute rootdir where the exe is located then path towards the menu.
	let rootDir = GetModuleDirectory;
	path = rootDir ~ "script/thdcs/menu/menu_end.txt";
	let id = LoadScript(path);
	StartScript(id);	
	
	// Hold this function while the menu_end.txt is running.
	while(!IsCloseScript(id)) {
		yield;
	}	
	
	// Get the result from the menu_end.txt and return in this function
	let value = GetScriptResult(id);
	alternative(value)
	case(RESULT_CANCEL) {
		PauseStageScene(false);	
	}
	case(RESULT_SAVE_REPLAY) {
	    StopMusic(GetAreaCommonData("sound","song",0));

		path = rootDir ~ "script/thdcs/menu/menu_replaysave.txt";
		let id = LoadScript(path);
		StartScript(id);

		// Hold this case while the menu_replaysave.txt is running.
		while(!IsCloseScript(id)) {
			yield;
		}		
		PlayMusic(BGM_TITLE);	
		SetAreaCommonData("game", "stageNum", 1);

		if(GetAreaCommonData("game", "menuFlow", 0) == 0) {
			SetScriptResult("ENDSTORY"); 
			CloseScript(GetOwnScriptID); 
		}
		if(GetAreaCommonData("game","menuFlow", 0) == 3) {
			SetScriptResult("ENDSTGPRACTISE"); 
			CloseScript(GetOwnScriptID); 
		}
		if(GetAreaCommonData("game", "menuFlow", 0) == 4) {
			SetScriptResult("ENDSPELLPRACTISE"); 
			CloseScript(GetOwnScriptID); 
		}	
	}
	case(RESULT_END) {
	    StopMusic(GetAreaCommonData("sound","song",0));
		PlayMusic(BGM_TITLE);	
		SetAreaCommonData("game", "stageNum", 1);
		//SaveCommonDataAreaA1("game");
		if(GetAreaCommonData("game", "menuFlow", 0) == 0) {
			SetScriptResult("ENDSTORY"); 
			CloseScript(GetOwnScriptID); 
		}
		if(GetAreaCommonData("game", "menuFlow", 0) == 3) {
			SetScriptResult("ENDSTGPRACTISE"); 
			CloseScript(GetOwnScriptID); 
		}
		if(GetAreaCommonData("game", "menuFlow", 0) == 4) {
			SetScriptResult("ENDSPELLPRACTISE"); 
			CloseScript(GetOwnScriptID); 
		}
	}
	case(RESULT_RETRY) {
        StopMusic(GetAreaCommonData("sound","song",0));
        if(GetAreaCommonData("game", "menuFlow", 0) == 4) {
            musicRestartEnable(GetAreaCommonData("sound", "song", 0), 1);
        } else {
            musicRestartEnable(GetAreaCommonData("sound", "song", 0), 0);
        }
        initializeStage;
	}
}

//------------------------------------------------------------------------------------------------------------------------------------------
// Function for pausing
function pauseGame() {
	snapshotScreen();
	
	// Pause the stage screen
	PauseStageScene(true);	
	
	// Get the absolute rootdir where the exe is located then path towards the menu.
	let rootDir = GetModuleDirectory;
	let path = rootDir ~ "script/thdcs/menu/menu_pause.txt";
	let id = LoadScript(path);
	StartScript(id);

	// Hold this function while the menu_pause.txt is running.
	while(!IsCloseScript(id)) {
		yield;
	}

	// Pausing is over, engine continues
	PauseStageScene(false);
	
	// Get the result from the menu_pause.txt and return in this function
	let value = GetScriptResult(id);
	return value;	
}	

// Function for pausing
function pauseGameReplay() {	
	snapshotScreen();
	
	// Pause the stage screen
	PauseStageScene(true);	
	
	// Get the absolute rootdir where the exe is located then path towards the menu.
	let rootDir = GetModuleDirectory;
	let path = rootDir ~ "script/thdcs/menu/menu_pausereplay.txt";
	let id = LoadScript(path);
	StartScript(id);

	// Hold this function while the menu_pause.txt is running.
	while(!IsCloseScript(id)) {
		yield;
	}

	// Pausing is over, engine continues
	PauseStageScene(false);
	
	// Get the result from the menu_pause.txt and return in this function
	let value = GetScriptResult(id);
	return value;	
}	

//------------------------------------------------------------------------------------------------------------------------------------------
// Replay select scene. Only if menuFlow is 5 (replay) you end up here. 
task gameReplayScene() {
	initializeStage; 
}

// Replay save scene. Only if you're not viewing replays. 
task gameReplaySaveScene() {
	FinalizeStageScene;
	
	// Regardless, allow the player to save replay
	let rootDir = GetModuleDirectory;
	let path = rootDir ~ "script/thdcs/menu/menu_replaysave.txt";
	let id = LoadScript(path);
	StartScript(id);

	// Hold this function while the menu_replaysave.txt is running.
	while(!IsCloseScript(id)) {
		yield;
	}
	titleScreenHandler();
} 

//------------------------------------------------------------------------------------------------------------------------------------------
// Snapshot the screen as a still image and render it as a texture.
function snapshotScreen() {
	let tex = GetTransitionRenderTargetName;
	RenderToTextureA1(tex, 0, 100, true);
}	