//************************************************************************************************************
//	Global library of useful functions/tasks
//	Version: 1.0
//  Library:
//		GetCenterX/Y			- Gets the centre of the field.
//		GetClipMaxX/Y			- Gets the maximum X/Y coordinates of the field.
//		GetClipMinX/Y			- Gets the minimum X/Y coordinates of the field. 
//		ObjMove_Special			- Special move code to move 2D sprites. Similar to moving object lasers.
//		rand_int				- Truncates a value between min and max value into an integer with no decimals.
//
//************************************************************************************************************

#include "script/thdcs/functions/function_loaddata.txt"

// super friend
function waitTitle(w) { loop(w) { yield; } }

// Gets the centre X of stage field
function GetCenterX() {
	let calc = GetStgFrameWidth / 2;
	return calc;
}

// Gets the centre of stage field
function GetCenterY() {
	let calc = GetStgFrameHeight / 2;
	return calc;
}

// Gets minimum X of stage field ( x = 0 )
function GetClipMinX() {
	let calc = GetStgFrameWidth - GetStgFrameWidth;
	return calc;
}

// Gets maximum X of stage field
function GetClipMaxX() {
	let calc = GetStgFrameWidth;
	return calc;
}

// Gets minimum Y of stage field
function GetClipMinY() {
	let calc = GetStgFrameHeight - GetStgFrameHeight;
	return calc;
}

// Gets minimum Y of stage field
function GetClipMaxY() {
	let calc = GetStgFrameHeight;
	return calc;
}

// Because ObjMove_SetSpeed does not work with Primitive 2D Sprites, I decided to make my own move code.
task ObjMove_Special(obj,x,y,v,dir) {
	let vx = v * cos(dir);
	let vy = v * sin(dir);

	while(!Obj_IsDeleted(obj)) {
		ObjRender_SetPosition(obj,x,y,0);
		yield;
		x += vx;
		y += vy;
	}
}

// 0.12m personal transition for rand_int.
function rand_int(min,max) {
	let rand_int_result;
	rand_int_result = truncate(rand(min,max));
	return rand_int_result;
}

// Menu item piece
function menuItem(x,y,scale,alpha,left,top,right,bottom) {
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);

	ObjPrim_SetTexture(obj, menuitems);
	ObjRender_SetBlendType(obj, BLEND_ALPHA);
	ObjRender_SetAlpha(obj, alpha);
	Obj_SetRenderPriorityI(obj, 80);
	ObjRender_SetScaleXYZ(obj, scale, scale, 0);
	ObjSprite2D_SetSourceRect(obj, left, top, right, bottom);
	ObjSprite2D_SetDestCenter(obj);
	ObjRender_SetPosition(obj, x, y, 0);

	return obj;
}

// Menu blinking effect. Due to it being a function, it will 'hold' the script for a while, just like in original game.
// This avoids people rushing through the menus. Of course the 'pause' should be subtle.
function menSelectAnim(obj) {
	loop(6) {
		ObjRender_SetColor(obj,255,32,32);
		loop(2) { yield; }
		ObjRender_SetColor(obj,255,255,255);
		loop(2) { yield; }
	}
}

// ちんちん～♪
task chinchin(obj) {
	// red, green, blue, cyan, purple, yellow, orange
	let colourSet = [[255, 16, 16], [16,255,16], [16,16,255], [16,255,255], [255,16,255], [255,255,16], [255,128,16]];
	let selectedColour = 0;
	let dir = 0;

	while(true) {
		selectedColour = rand_int(0, 7);
		musicnoteSprite(ObjRender_GetX(obj)+24, ObjRender_GetY(obj)-96, rand(0.3,1.2), rand_int(270,360), rand(0.3,1.2), 255, colourSet[selectedColour][0], colourSet[selectedColour][1], colourSet[selectedColour][2]);
		loop(rand_int(30, 60)) { yield; }
	}
}

// Handles the gentle birdy swaying animation
task birdyAnimation(obj) {
	let frameCounter = 0;
	let angleZ = 0;

	while(true) {
		ObjRender_SetAngleZ(obj, angleZ);
		angleZ += cos(frameCounter) / 24;
		frameCounter++;
		yield;
	}
}

// Sprite object for the music note emitted by the birdy
task musicnoteSprite(x,y,v,dir,parts,alphaValue,red,green,blue) {
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	let frameCounter = 0;

	ObjPrim_SetTexture(obj, menuitems);
	ObjRender_SetBlendType(obj, BLEND_ALPHA);
	Obj_SetRenderPriorityI(obj, 90);
	ObjRender_SetPosition(obj, x, y, 0);
	ObjRender_SetScaleXYZ(obj, parts, parts, 0);
	ObjSprite2D_SetSourceRect(obj, 440, 320, 460, 352);
	ObjSprite2D_SetDestCenter(obj);

	ObjMove_Special(obj,x,y,v,dir);

	while(!Obj_IsDeleted(obj)) {
		ObjRender_SetColor(obj, red, green, blue);
		ObjRender_SetAlpha(obj, alphaValue);
		ObjRender_SetScaleXYZ(obj, parts, parts, 0);

		parts += sin(frameCounter) / 220;
		frameCounter += 4;
		alphaValue -= 2;

		if(alphaValue <= 0) {
		    Obj_Delete(obj);
		    break;
        }
		yield;
	}
}

// Hud glitter task
task hudGlitterA(x,y,v,dir,parts,alphaValue,red,green,blue) {
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	let frameCounter = 0;
	let partSizeScale = parts;

	ObjPrim_SetTexture(obj,circglit);
	ObjRender_SetBlendType(obj,BLEND_ADD_RGB);
	Obj_SetRenderPriorityI(obj,90);
	ObjRender_SetPosition(obj,x,y,0);
	ObjRender_SetScaleXYZ(obj,parts,parts,0);
	ObjSprite2D_SetSourceRect(obj,0,0,64,64);
	ObjSprite2D_SetDestCenter(obj);

	ObjMove_Special(obj,x,y,v,dir);

	while(! Obj_IsDeleted(obj)) {
		ObjRender_SetColor(obj,red,green,blue);
		ObjRender_SetAlpha(obj,alphaValue);
		ObjRender_SetScaleXYZ(obj,parts,parts,0);

		// glittering effect
		parts = rand(partSizeScale,partSizeScale+0.5)*sin(frameCounter*round(rand(10,20)));
		frameCounter++;

		// remove timer
		if(frameCounter > round(rand(90,180))){ Obj_Delete(obj); }

		yield;
	}
}

// Blurs the background during a pause. Original ph3 Rumia code
task bgBlur {
	task TVertex(var index, var left, var top, var right, var bottom)
	{
		ObjPrim_SetVertexPosition(obj, index + 0, left, top, 0);
		ObjPrim_SetVertexPosition(obj, index + 1, left, bottom, 0);
		ObjPrim_SetVertexPosition(obj, index + 2, right, top, 0);
		ObjPrim_SetVertexPosition(obj, index + 3, right, top, 0);
		ObjPrim_SetVertexPosition(obj, index + 4, left, bottom, 0);
		ObjPrim_SetVertexPosition(obj, index + 5, right, bottom, 0);

		ObjPrim_SetVertexUVT(obj, index + 0, left, top);
		ObjPrim_SetVertexUVT(obj, index + 1, left, bottom);
		ObjPrim_SetVertexUVT(obj, index + 2, right, top);
		ObjPrim_SetVertexUVT(obj, index + 3, right, top);
		ObjPrim_SetVertexUVT(obj, index + 4, left, bottom);
		ObjPrim_SetVertexUVT(obj, index + 5, right, bottom);

		if(left >= 32 && right <= 416 && top >=16 && bottom <= 464)
		{
			let alpha = 255;
			while(alpha >= 128)
			{
				ObjPrim_SetVertexAlpha(obj, index + 0, alpha/3);
				ObjPrim_SetVertexAlpha(obj, index + 1, alpha/3);
				ObjPrim_SetVertexAlpha(obj, index + 2, alpha/3);
				ObjPrim_SetVertexAlpha(obj, index + 3, alpha/3);
				ObjPrim_SetVertexAlpha(obj, index + 4, alpha/3);
				ObjPrim_SetVertexAlpha(obj, index + 5, alpha/3);
				alpha -= 255 / frame;

				yield;
			}
		}
	}

	let frame = 30;
	let countH = 20;
	let countV = 30;
	let width = 640 / countH;
	let height = 480 / countV;
	let target = GetTransitionRenderTargetName();
	let obj = ObjPrim_Create(OBJ_PRIMITIVE_2D);
	ObjPrim_SetPrimitiveType(obj, PRIMITIVE_TRIANGLELIST);
	ObjPrim_SetVertexCount(obj, countH * countV * 6);
	Obj_SetRenderPriorityI(obj, 0);
	ObjPrim_SetTexture(obj, target);

	ascent(ix in 0.. countH)
	{
		ascent(iy in 0.. countV)
		{
			let index = (ix + iy * countH) * 6;
			let left = ix * width;
			let right = left + width;
			let top = iy * height;
			let bottom = top + height;
			TVertex(index, left, top, right, bottom);
		}
	}
}