let MD = GetModuleDirectory;

@Initialize {
	SetAutoDeleteObject(true);
	LoadReplayList;
	TBackground;
	TReplayIndexSelection;
	
}

@MainLoop {
	yield;
}

@Finalize {
}

let MENU_INDEX_SELECTION = 1;
let MENU_NAME_ENTRY = 2;
let menuMode = MENU_INDEX_SELECTION;


function CreateTextObject(mx, my, size, text, r, g, b){
	let obj = ObjText_Create;
	ObjText_SetText(obj, text);
	ObjText_SetFontSize(obj, size);
	ObjText_SetFontType(obj, "Lekton");
	ObjText_SetFontBold(obj, true);
	ObjText_SetFontColorTop(obj, r, g, b);
	ObjText_SetFontColorBottom(obj, r, g, b);
	ObjText_SetFontBorderColor(obj, 0, 0, 0);
	ObjText_SetFontBorderType(obj, BORDER_FULL);
	ObjText_SetFontBorderWidth(obj, 2);
	Obj_SetRenderPriorityI(obj, 10);
	ObjRender_SetX(obj, mx);
	ObjRender_SetY(obj, my);
	return obj;
}
function CreateCenterTextObject(mx, my, size, text, r, g, b){
	let obj = ObjText_Create;
	ObjText_SetText(obj, text);
	ObjText_SetFontSize(obj, size);
	ObjText_SetFontType(obj, "Lekton");
	ObjText_SetFontBold(obj, true);
	ObjText_SetFontColorTop(obj, r, g, b);
	ObjText_SetFontColorBottom(obj, r, g, b);
	ObjText_SetFontBorderColor(obj, 0, 0, 0);
	ObjText_SetFontBorderType(obj, BORDER_FULL);
	ObjText_SetHorizontalAlignment(obj,ALIGNMENT_CENTER);
	ObjText_SetMaxWidth(obj,400);
	ObjText_SetFontBorderWidth(obj, 2);
	Obj_SetRenderPriorityI(obj, 10);
	ObjRender_SetX(obj, mx);
	ObjRender_SetY(obj, my);
	return obj;
}

task TBackground {
	let target = GetTransitionRenderTargetName();
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjPrim_SetTexture(obj, target);
	Obj_SetRenderPriority(obj, 0.1);
	ObjSprite2D_SetSourceRect(obj, 0, 0, 640, 480);
	ObjSprite2D_SetDestCenter(obj);
	ObjRender_SetPosition(obj, 320, 240, 0);
	ObjRender_SetAlpha(obj, 64);
}

task TReplayIndexSelection {
	let cursorY = 0;
	let page = 0;
	let countMaxItem = REPLAY_INDEX_DIGIT_MAX - REPLAY_INDEX_DIGIT_MIN + 1;
	let countItemPerPage = 10;
	let pageMax = trunc((countMaxItem - 1) / countItemPerPage);
	pageMax = max(pageMax, 1);
	let lastPageMaxCursorY = trunc(countMaxItem / countItemPerPage);

	task TMenuItem(mx, my, mod){
		let omx = mx;
		let mspd = 5;
		let oldPage = -1;
		let text = "";
		function CreateTextObject(mx, my, text, r, g, b){
			let obj = ObjText_Create;
			ObjText_SetText(obj, text);
			ObjText_SetFontSize(obj, 28);
			ObjText_SetFontType(obj, "Lekton");
			//ObjText_SetFontBold(obj, true);
			ObjText_SetFontColorTop(obj, r, g, b);
			ObjText_SetFontColorBottom(obj, r, g, b);
			ObjText_SetFontBorderColor(obj, 0, 0, 0);
			ObjText_SetFontBorderType(obj, BORDER_FULL);
			ObjText_SetFontBorderWidth(obj, 2);
			Obj_SetRenderPriorityI(obj, 10);
			ObjRender_SetX(obj, mx);
			ObjRender_SetY(obj, my);
			return obj;
		}

		let objText = CreateTextObject(mx, my, text, 255, 255, 255);
		let objSelect = CreateTextObject(mx, my, text, 255, 80, 255);
		ObjRender_SetBlendType(objSelect, BLEND_ALPHA);
		let color = 100;
		let colorset = 0;
		let selection = 0;
		let move = 0;
		
		while(menuMode == MENU_INDEX_SELECTION) {
			if(page != oldPage) {
				let index = page * countItemPerPage + my + 1;
				let text = rtos("00", index) ~ " ";
				if(IsValidReplayIndex(index)) {
					text = text ~ vtos("-8s", GetReplayInfo(index, REPLAY_USER_NAME)) ~ " ";
					text = text ~ GetReplayInfo(index, REPLAY_DATE_TIME) ~ " ";
					text = text ~ rtos("000000000000", GetReplayInfo(index, REPLAY_TOTAL_SCORE)) ~ " ";
				}
				else {
					text = text ~ "No Data";
				}
				ObjText_SetText(objText, text);
				ObjText_SetText(objSelect, text);
				oldPage = page;
			}
			
			if(my != cursorY){
				colorset = 0;
				color = 125;
				move = 16;
			}
			
			if(page == pageMax && my >= lastPageMaxCursorY) {
				Obj_SetVisible(objText, false);
				Obj_SetVisible(objSelect, false);
			}
			
			if(move>0 && my == cursorY){
				let randx = mx + rand(-move/4, move/4);
				let randy = 64+my*30 + rand(-move/4, move/4);
				ObjRender_SetPosition(objText, randx, randy, 0);
				ObjRender_SetPosition(objSelect, randx, randy, 0);
				move--;
			}
			else {
				ObjRender_SetPosition(objText, mx, 64+my*30, 0);
				ObjRender_SetPosition(objSelect, mx, 64+my*30, 0);
			}
			
			if(colorset == 0){ color+=8 }
			if(colorset == 1){ color-=8 }
			if(color>=255){ colorset = 1; }
			if(color<=15){ colorset = 0; }
			ObjRender_SetAlpha(objSelect, color-color*(absolute(omx-mx)/omx));
			ObjRender_SetAlpha(objText, 255-255*(absolute(omx-mx)/omx));
			Obj_SetVisible(objSelect, my == cursorY);
			if(mx>omx){ mx = max(mx-mspd, omx); }
			if(mx<omx){ mx = min(mx+mspd, omx); }
			yield;
		}
		colorset = 0;
		color = 255;
		loop(15) {
			if(colorset == 0){ color+=130 }
			if(colorset == 1){ color-=130 }
			if(color>=255){ colorset = 1; }
			if(color<=15){ colorset = 0; }
			ObjRender_SetAlpha(objSelect, color-color*(absolute(omx-mx)/omx));
			yield;
		}
		Obj_Delete(objText);
		Obj_Delete(objSelect);
	}

	ascent(let iItem in 0 .. countItemPerPage) {
		TMenuItem(64,iItem,1);
	}

	while(GetVirtualKeyState(VK_OK) != KEY_FREE){ yield; }

	let frameKeyHold = 0;
	while(menuMode == MENU_INDEX_SELECTION) {
		if(GetVirtualKeyState(VK_OK) == KEY_PULL) {
			PlaySoundEffect("confirm",100);
			menuMode = MENU_NAME_ENTRY;
			loop(15) { yield; }
			let index = page * countItemPerPage + cursorY + 1;
			TNameEntry(index);
			break;
		}

		if(GetVirtualKeyState(VK_UP) == KEY_PUSH || GetVirtualKeyState(VK_UP) == KEY_HOLD) {
			frameKeyHold++;
			if(GetVirtualKeyState(VK_UP) == KEY_PUSH ||
				frameKeyHold == 20 ||
				 (frameKeyHold > 20 && (frameKeyHold % 10 == 0))) {
				PlaySoundEffect("select",100);
				cursorY--;
			}
		}
		else if(GetVirtualKeyState(VK_DOWN) == KEY_PUSH || GetVirtualKeyState(VK_DOWN) == KEY_HOLD) {
			frameKeyHold++;
			if(GetVirtualKeyState(VK_DOWN) == KEY_PUSH ||
				frameKeyHold == 20 ||
				 (frameKeyHold > 20 && (frameKeyHold % 10 == 0))) {
				PlaySoundEffect("select",100);
				cursorY++;
			}
		}
		else if(GetVirtualKeyState(VK_LEFT) == KEY_PUSH || GetVirtualKeyState(VK_LEFT) == KEY_HOLD) {
			frameKeyHold++;
			if(GetVirtualKeyState(VK_LEFT) == KEY_PUSH ||
				frameKeyHold == 20 ||
				 (frameKeyHold > 20 && (frameKeyHold % 10 == 0))) {
				PlaySoundEffect("select",100);
				page--;
			}
		}
		else if(GetVirtualKeyState(VK_RIGHT) == KEY_PUSH || GetVirtualKeyState(VK_RIGHT) == KEY_HOLD) {
			frameKeyHold++;
			if(GetVirtualKeyState(VK_RIGHT) == KEY_PUSH ||
				frameKeyHold == 20 ||
				 (frameKeyHold > 20 && (frameKeyHold % 10 == 0))) {
				PlaySoundEffect("select",100);
				page++;
			}
		}
		else {
			frameKeyHold = 0;
		}

		if(page < 0) {
			page = pageMax;
		}
		else if(page > pageMax) {
			page = 0;
		}

		if(page != pageMax)	{
			if(cursorY < 0)	{
				cursorY = countItemPerPage - 1;
			}
			else if(cursorY >= countItemPerPage) {
				cursorY = 0;
			}
		}
		else {
			if(cursorY < 0)	{
				cursorY = lastPageMaxCursorY - 1;
			}
			else if(cursorY >= lastPageMaxCursorY)	{
				cursorY = 0;
			}
		}
		yield;
	}
}


task TNameEntry(let replayIndex) {
	while(GetVirtualKeyState(VK_OK) != KEY_FREE){yield;}

	CreateCenterTextObject(50, 90, 28, "Type replay name here", 255, 255, 255);
	CreateCenterTextObject(50, 165, 28, "Press ENTER when finished", 255, 255, 255);
	CreateCenterTextObject(50, 185, 28, "Press ESC to cancel", 255, 255, 255);

	let userName = "_";
	let objName = CreateCenterTextObject(50, 116, 56, "", 255, 80, 255);
	ObjText_SetSyntacticAnalysis(objName,false);

	let frameKeyHold = 0;
	let nameLength = 0;
	let arrayDiff = ["Easy","Normal","Hard","Lunatic","Extra"];
	let indexDiff = GetAreaCommonData("PlayState","Difficulty",1);
	while(menuMode == MENU_NAME_ENTRY) {
		nameLength = length(userName);
		if(nameLength < 13) {
			if(CheckKeyboard != "") { PlaySoundEffect("select",100); }
			userName = userName[0..nameLength-1] ~ CheckKeyboard ~ "_";
		}
		if(GetKeyState(KEY_RETURN)==KEY_PUSH) {
			PlaySoundEffect("confirm",100);
				if(nameLength == 0) {
					userName = "LAZY_";
				}
				else {
					let stringStageFrames = ToString(GetCommonData("StageTime_1",180)) ~ "," ~ ToString(GetCommonData("StageTime_2",180)) ~ "," ~ ToString(GetCommonData("StageTime_3",180)) ~ "," ~ ToString(GetCommonData("StageTime_4",180))~ "," ~ ToString(GetCommonData("StageTime_5",180))~ "," ~ ToString(GetCommonData("StageTime_6",180));
					SetReplayInfo(REPLAY_COMMENT,stringStageFrames ~ "/" ~ arrayDiff[indexDiff] ~ "/"~ GetAreaCommonData("PlayState","Mode","Main") ~ "/"~ ToString(GetAreaCommonData("Options","Lives",2)));
					SaveReplay(replayIndex, userName[0..nameLength-1]);
					SetScriptResult(RESULT_END);
					CloseScript(GetOwnScriptID);
					return;
				}
		}
		if(GetVirtualKeyState(VK_PAUSE)==KEY_PUSH) {
			SetScriptResult(RESULT_END);
			CloseScript(GetOwnScriptID);
			return;
		}
		if(GetKeyState(KEY_BACK)==KEY_PUSH) {
			PlaySoundEffect("cancel",100);
			nameLength = length(userName);
			if(nameLength > 1) {
				userName = userName[0..nameLength-2] ~ "_";
			}	
		}
		nameLength = length(userName);
		let displayLength = min(nameLength,12);
		ObjText_SetText(objName, userName[0..displayLength]);
		yield;
	}
}
function CheckKeyboard {
	let output = "";
	let keyList = [KEY_0,KEY_1,KEY_2,KEY_3,KEY_4,KEY_5,KEY_6,KEY_7,KEY_8,KEY_9,
				   KEY_A,KEY_B,KEY_C,KEY_D,KEY_E,KEY_F,KEY_G,KEY_H,KEY_I,KEY_J,KEY_K,KEY_L,KEY_M,
				   KEY_N,KEY_O,KEY_P,KEY_Q,KEY_R,KEY_S,KEY_T,KEY_U,KEY_V,KEY_W,KEY_X,KEY_Y,KEY_Z,
				   KEY_MINUS,KEY_EQUALS,KEY_LBRACKET,KEY_RBRACKET,KEY_SEMICOLON,KEY_APOSTROPHE,KEY_GRAVE,KEY_AT,KEY_COLON,KEY_UNDERLINE,KEY_CIRCUMFLEX,
				   KEY_COMMA,KEY_PERIOD,KEY_ADD,KEY_SUBTRACT,KEY_MULTIPLY,KEY_DECIMAL,KEY_NUMPADEQUALS,KEY_SPACE,
				   KEY_NUMPAD0,KEY_NUMPAD1,KEY_NUMPAD2,KEY_NUMPAD3,KEY_NUMPAD4,KEY_NUMPAD5,KEY_NUMPAD6,KEY_NUMPAD7,KEY_NUMPAD8,KEY_NUMPAD9];

	let charList = ["0","1","2","3","4","5","6","7","8","9",
				    "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z",
				    "-","=","[","]",";","'","`","@",":","_","^",",",".","+","-","*",".","="," ",
				    "0","1","2","3","4","5","6","7","8","9"];
	ascent(i in 0..length(keyList)) {
		if(GetKeyState(keyList[i])==KEY_PUSH) {
			output = charList[i];
		}
	}
	return output;
}
function PlaySoundEffect(name,volume) {
	let obj = ObjSound_Create;
	ObjSound_SetSoundDivision(obj,SOUND_SE);
	ObjSound_Load(obj,GetModuleDirectory ~ "SE/" ~name~ ".wav");
	ObjSound_SetRestartEnable(obj, true);
	ObjSound_SetVolumeRate(obj,volume*GetAreaCommonData("Options","SFX",1));
	ObjSound_Play(obj);
}