//---------------------------------------------------------------------------------
// STG Screen Functions
//---------------------------------------------------------------------------------

function CenX{ return GetScreenWidth/2; }

function CenY{ return GetScreenHeight/2; }

// Compressed Screen -----------------------------

function MinX{ return 136; }

function MinY{ return 24; }

function MaxX{ return GetScreenWidth-136; }

function MaxY{ return GetScreenHeight-24; }

// Wide Screen -----------------------------------

function AbsMinX{ return 0; }

function AbsMinY{ return 0; }

function AbsMaxX{ return GetScreenWidth; }

function AbsMaxY{ return GetScreenHeight; }

// Current Screen --------------------------------

function NowMinX{ return GetCommonData("STGFrame_L",MinX); }

function NowMinY{ return GetCommonData("STGFrame_T",MinY); }

function NowMaxX{ return GetCommonData("STGFrame_R",MaxX); }

function NowMaxY{ return GetCommonData("STGFrame_B",MaxY); }

function NowLengthX{ return NowMaxX-NowMinX; }

function NowLengthY{ return NowMaxY-NowMinY; }

// Miscellaneous ---------------------------------

function IsWideScreen{
	return GetCommonData("STGFrame_STATE",false); 
}

task SetScreenShake(let maxRadius, let maxTime){
	let cX = Get2DCameraX;
	let cY = Get2DCameraY;
	ascent(let ccTime in 0..maxTime){
		let nAngle = rand_deg;
		let nRadius = (maxTime-ccTime)*(maxRadius/(maxTime-1));
		Set2DCameraFocusX(GetGapX(cX,nRadius,nAngle));
		Set2DCameraFocusY(GetGapY(cY,nRadius,nAngle));
		yield;
	}
	Set2DCameraFocusX(CenX);
	Set2DCameraFocusY(CenY);
}

task SetWideScreen(let transTime){
	let sinRate = 90/transTime;
	SetCommonData("STGFrame_STATE",true);
	ascent(let a in 1..transTime+1){
		let WideMinX = GetGapY(MinX,-MinX+8,a*sinRate);
		let WideMinY = GetGapY(MinY,-MinY+8,a*sinRate);
		let WideMaxX = GetGapY(MaxX,+MinX-8,a*sinRate);
		let WideMaxY = GetGapY(MaxY,+MinY-8,a*sinRate);
		SetCommonData("STGFrame_L",WideMinX);
		SetCommonData("STGFrame_T",WideMinY);
		SetCommonData("STGFrame_R",WideMaxX);
		SetCommonData("STGFrame_B",WideMaxY);
		SetPlayerClip(WideMinX,WideMinY+16,WideMaxX,WideMaxY-8);
		yield;
	}
}

// Flip Camera -----------------------------------

function SetFlipCameraRatioX(let xRatio){
	SetCommonData("CAMERA_FLIP_X",xRatio);
}

function SetFlipCameraRatioY(let yRatio){
	SetCommonData("CAMERA_FLIP_Y",yRatio);
}

function SetFlipCameraAngleZ(let zAngle){
	SetCommonData("CAMERA_FLIP_Z",zAngle);
}

function GetFlipCameraRatioX{
	return GetCommonData("CAMERA_FLIP_X",1.00);
}

function GetFlipCameraRatioY{
	return GetCommonData("CAMERA_FLIP_Y",1.00);
}

function GetFlipCameraAngleZ{
	return GetCommonData("CAMERA_FLIP_Z",0);
}

//---------------------------------------------------------------------------------
// System / Information Functions
//---------------------------------------------------------------------------------

function wait(let wtTime){ loop(wtTime){ yield; } }

function SetProbability(let nChance){
	if(rand(0,100) < nChance){ return true; }
	else{ return false; }
}

function GetRandomIndex(let aLength){ return rand_int(0,aLength-1); }

function GetInverser{
	let rValue = 1;
	if(SetProbability(50)){ rValue = -rValue; } 
	return rValue;
}

function GetRainbowRGB(let sinValue){
	let R = GetGapY(255/2,255/2,sinValue);
	let G = GetGapY(255/2,255/2,sinValue+120);
	let B = GetGapY(255/2,255/2,sinValue+240);
	return [R,G,B];
}

function switch(let boolFlag){
	if(boolFlag){
		boolFlag = false;
	}else if(!boolFlag){
		boolFlag = true;
	}
	return boolFlag;
}

function bound(minValue,numValue,maxValue){
	if(numValue < minValue){ return minValue; }
	if(numValue > maxValue){ return maxValue; }
	return numValue;
}

//---------------------------------------------------------------------------------
// Mathematic Functions
//---------------------------------------------------------------------------------

function e{ return 2.71828182845904523536028747135; }

function sqrt(let nValue){ return nValue^0.5; }

function exp(let nValue){ return e^nValue; }

function GetDistance(let x1, let y1, let x2, let y2){ return absolute(sqrt((x2-x1)^2+(y2-y1)^2)); }

function GetGapX(let x, let gapLength, let gapAngle){ return x+gapLength*cos(gapAngle); }

function GetGapY(let y, let gapLength, let gapAngle){ return y+gapLength*sin(gapAngle); }

function GetGapX2(let x, let xLength, let yLength, let gapAngle, let gapAlign){
	return x+xLength*cos(gapAngle)*cos(gapAlign)-yLength*sin(gapAngle)*sin(gapAlign);
}

function GetGapY2(let y, let xLength, let yLength, let gapAngle, let gapAlign){
	return y+xLength*cos(gapAngle)*sin(gapAlign)+yLength*sin(gapAngle)*cos(gapAlign);
}

function GetAngleToPlayer2(let pX, let pY){ return atan2(GetPlayerY-pY,GetPlayerX-pX); }

function sec(let nAngle){ return 1/cos(nAngle); }
function csc(let nAngle){ return 1/sin(nAngle); }
function cot(let nAngle){ return 1/tan(nAngle); }

function sinh(let nAngle){ return (exp(nAngle)-exp(-1*nAngle))/2; }
function cosh(let nAngle){ return (exp(nAngle)+exp(-1*nAngle))/2; }
function tanh(let nAngle){ return sinh(nAngle)/cosh(nAngle);}

function ToRadian(let degValue){ return (degValue/180)*pi; }

function ToDegree(let radValue){ return (radValue*180)/pi; }

function rand_deg{ return rand(0,359.99999); }

function rand_int(let minLimit, let maxLimit){ return truncate(rand(minLimit,maxLimit+0.99999)); }

function GetPythagorean(let a, let b, let c){
	if(!a){ return sqrt(c^2-b^2); }
	if(!b){ return sqrt(c^2-a^2); }
	if(!c){ return sqrt(a^2+b^2); }
}

function GetOrbit(let nRadius, let nSpeed){ return (nSpeed/nRadius)*180/pi; }

function sgn(let nValue){
	if(nValue == 0){ return 0; }
	return nValue/absolute(nValue);
}