//Main Script Function library
//
////I. Basic Functions
//1. InField(x, y) - Returns true if (x, y) is on the screen
//2. AngleFromPlayer(x, y) - Returns the angle from the player to (x, y)
//3. AngleToPlayer(x, y) - Returns the angle to the player from (x, y)
//4. Distance(x1, y1, x2, y2) - Returns the distance from (x1, y1) to (x2, y2)
//5. DistanceFromPlayer(x, y) - Returns the distance from the player to (x, y)
//6. NormalizeAngle(angle) - Returns an angle between 0° and 359°
//7. IsSameAngle(angle1, angle2) - Returns true if the 2 given angles are equal
//8. AngularDistance(angle1, angle2) - Returns the difference between angle1 and angle2
//
//
////II. Stage Functions
//1. StageInit - Starts a stage (MUST BE PLACED AT THE START OF EVERY STAGE)
//2. StageClear - Ends a stage (MUST BE PLACED AT THE END OF EVERY STAGE)
//
////III. Effect Objects
//1. CreateRObjEffect(texture, layer) - Creates a rectangular effect object and returns its ID
//2. ObjEffect_SetXYRect(id, left, top, right, bottom) - Sets the XY-coordinates of a rectangular effect object
//3. ObjEffect_SetUVRect(id, left, top, right, bottom) - Sets the UV-coordinates of a rectangular effect object
//4. ObjEffect_SetColor(id, vertices, a, r, g, b) - Sets the color of an effect object
//
////IV. System Functions
//1. CreateTimer(frames, x, y) - Creates a timer at (x, y) that lasts for x frames, then self-deletes
//2. DrawTextCustom(string, left, top, right, a, r, g, b, z, x, mov, movb) - Displays string at (left, top) until (right, top) with alpha a and colors (r, g, b) and self-deletes when z is pressed (if z=1), x is pressed (if x=1), up/down is pressed (if mov=1), left/right is pressed (if movb=1)
//3. DrawImageCustom(string, left, top, right, bottom, posx, posy, a, r, g, b, z, x, mov, movb) - Same as DrawTextCustom but displays an image with UV rect at (left, top, right, bottom) at (posx, posy)
//4. NumberToString(number) - Returns a string with the value given (removes decimals)
//5. StringToNumber(string) - Returns a value with the string given (Does not work properly with decimals)
//6. DrawTextReturn(string, left, top, right, a, r, g, b) - Displays string at (left, top) until (right, top) with alpha a and colors(r, g, b) and returns an array containing the ids
//

///////////////////////////////BASIC FUNCTIONS//////////////////////////////

function InField(x, y)
{
	if(x<GetClipMaxX && x>GetClipMinX && y<GetClipMaxY && y>GetClipMinY)
	{
	return true;
	}else{
	return false;
	}
}

function AngleFromPlayer(x, y)
{
	return atan2(y-GetPlayerY, x-GetPlayerX);
}

function AngleToPlayer(x, y)
{
	return atan2(GetPlayerY-y, GetPlayerX-x);
}

function Distance(x1, y1, x2, y2)
{
	return ((x1-x2)^2 + (y1-y2)^2)^0.5;
}

function DistanceFromPlayer(x, y)
{
	return Distance(x, y, GetPlayerX, GetPlayerY);
}

function NormalizeAngle(angle)
{
  angle%=360;
  if(angle<0){angle+=360;}
  return angle;
}

function IsSameAngle(angle1, angle2)
{
  angle1=NormalizeAngle(angle1);
  angle2=NormalizeAngle(angle2);
  return angle1==angle2;
}

function AngularDistance(angle1, angle2)
{
  let distance=NormalizeAngle(angle2 - angle1);
  if(distance>180){distance-=360;}
  return distance;
}

///////////////////////////////STAGE FUNCTIONS//////////////////////////////

sub StageInit
{
	SetPlayerX(GetCenterX);
	SetPlayerY(GetClipMaxY-60);
	SetCommonData("STAGESTART", "TRUE");
	SetCommonData("MONEYGET", 0);
	SetCommonData("DAMAGE", 0);
	while(GetCommonData("STAGESTART")!="DONE"){yield;}
}

sub StageClear
{
	SetCommonData("STAGESTART", "END");
	StatusScreen;
}

///////////////////////////////EFFECT OBJECTS///////////////////////////////

function CreateRObjEffect(texture, layer)
{
	let obj = Obj_Create(OBJ_EFFECT);
	ObjEffect_SetTexture(obj, texture);
	ObjEffect_SetLayer(obj, layer);
	ObjEffect_SetPrimitiveType(obj, PRIMITIVE_TRIANGLESTRIP);
	ObjEffect_CreateVertex(obj, 4);
	return obj;
}

function ObjEffect_SetXYRect(id, left, top, right, bottom)
{
	ObjEffect_SetVertexXY(id, 0, left, top);
	ObjEffect_SetVertexXY(id, 1, right, top);
	ObjEffect_SetVertexXY(id, 2, left, bottom);
	ObjEffect_SetVertexXY(id, 3, right, bottom);
}

function ObjEffect_SetUVRect(id, left, top, right, bottom)
{
	ObjEffect_SetVertexUV(id, 0, left, top);
	ObjEffect_SetVertexUV(id, 1, right, top);
	ObjEffect_SetVertexUV(id, 2, left, bottom);
	ObjEffect_SetVertexUV(id, 3, right, bottom);
}

function ObjEffect_SetColor(id, vertices, a, r, g, b)
{
	ascent(i in 0..vertices){ObjEffect_SetVertexColor(id, i, a, r, g, b);}
}

///////////////////////////////SYSTEM FUNCTIONS///////////////////////////////

task CreateTimer(frames, x, y)
{
	yield;
	let secondcount=0;
	let msecondcount=0;
	let timercountb=0;
	let timers=[CreateRObjEffect(numimg, 8), CreateRObjEffect(numimg, 8), CreateRObjEffect(numimg, 8), 
				CreateRObjEffect(numimg, 8), CreateRObjEffect(numimg, 8), CreateRObjEffect(numimg, 8)];
	ascent(i in 0..3){ObjEffect_SetXYRect(timers[i], x+i*15, y, x+i*15+14, y+24);}
	ObjEffect_SetXYRect(timers[3], x+42, y, x+57, y+24);
	ascent(i in 4..6){ObjEffect_SetXYRect(timers[i], x+15+i*9, y+6, x+27+i*9, y+24);}
	
	while(Obj_BeDeleted(timers[0])==false){
		if(frames>600)
		{
			ascent(i in 0..6){ObjEffect_SetColor(timers[i], 4, 255, 255, 255, 255);}
			frames--;
		}else if(frames>0){
			ascent(i in 0..6){ObjEffect_SetColor(timers[i], 4, 255, 255, 64, 64);}
			frames--;
		}else{
			ascent(i in 0..6){Obj_Delete(timers[i])};
		}
		timercountb=frames;
		secondcount=truncate(timercountb/60);
		msecondcount=((timercountb-(secondcount*60))/60)*100;
		updatetimer(secondcount, msecondcount);
		yield;
	}
	
	function Set_System_UV(id, num)
	{
		ObjEffect_SetUVRect(id, num*16, 0, num*16+16, 19);
	}
	
	function updatetimer(sc, msc)
	{
		let stimenum1=sc;
		let stimenum2=truncate(stimenum1/100);
		if(stimenum2==0){Set_System_UV(timers[0], 10);}else{Set_System_UV(timers[0], stimenum2);}
		stimenum1-=stimenum2*100;
		stimenum2=truncate(stimenum1/10);
		Set_System_UV(timers[1], stimenum2);
		stimenum1-=stimenum2*10;
		stimenum2=truncate(stimenum1);
		Set_System_UV(timers[2], stimenum2);
		let mstimenum1=msc;
		let mstimenum2=truncate(mstimenum1/10);
		Set_System_UV(timers[4], mstimenum2);
		mstimenum1-=mstimenum2*10;
		mstimenum2=truncate(mstimenum1);
		Set_System_UV(timers[5], mstimenum2);
		Set_System_UV(timers[3], 11);
	}
}

task DrawTextCustom(string, left, top, right, a, r, g, b, z, x, mov, movb)
{
	let stringarray=string~" ";
	let drawnarray=[];
	let xdist=right-left;
	let curdistx=0;
	let curdisty=0;
	let curdistxb=0;
	let num=0;
	let numb=0;
	let numc=0;
	ascent(i in 0..length(stringarray))
	{
	drawnarray=drawnarray~[CreateRObjEffect(textimg, 8)];
	}
	while(num<length(drawnarray)){
		while(curdistx+14<xdist && num<length(drawnarray)){
			SetLetter(drawnarray[num], stringarray[num], 0, 1);
			curdistx+=curdistxb;
			curdistxb=0;
			if(stringarray[num]==' ' || num==length(drawnarray)-1){
				numc=num;
			}
			num++;
		}
		curdistx=0;
		curdistxb=0;
		ascent(i in numb..numc){
			SetLetter(drawnarray[i], stringarray[i], 1, 1);
			ObjEffect_SetColor(drawnarray[i], 4, a, r, g, b);
			ObjEffect_SetXYRect(drawnarray[i], left+curdistx, top+curdisty, left+curdistx+14, top+curdisty+14);
			curdistx+=curdistxb;
			curdistxb=0;
		}
		numb=numc;
		num=numb;
		if(numc==length(drawnarray)-1){break;}
		curdisty+=7;
	}
	
	yield;
	while(Obj_BeDeleted(drawnarray[0])==false){
		if(GetKeyState(VK_SHOT)==KEY_PUSH && z==1){
			ascent(i in 0..length(drawnarray)){Obj_Delete(drawnarray[i]);}
		}
		if(GetKeyState(VK_BOMB)==KEY_PUSH && x==1){
			ascent(i in 0..length(drawnarray)){Obj_Delete(drawnarray[i]);}
		}
		if(GetKeyState(VK_UP)==KEY_PUSH || GetKeyState(VK_DOWN)==KEY_PUSH){
			if(mov==1){ascent(i in 0..length(drawnarray)){Obj_Delete(drawnarray[i]);}}
		}
		if(GetKeyState(VK_LEFT)==KEY_PUSH || GetKeyState(VK_RIGHT)==KEY_PUSH){
			if(movb==1){ascent(i in 0..length(drawnarray)){Obj_Delete(drawnarray[i]);}}
		}
		yield;
	}
	
	function SetLetter(obj, character, UV, mov){
		let characterarray=['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', '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(characterarray)){
			if(character==characterarray[i]){
				if(UV==1){
					if(i<=2){ObjEffect_SetUVRect(obj, (15+i)*14, 14, (16+i)*14, 28);}
					if(i>=3 && i<=20){ObjEffect_SetUVRect(obj, (i-3)*14, 28, (i-2)*14, 42);}
					if(i>=21 && i<=25){ObjEffect_SetUVRect(obj, (i-21)*14, 42, (i-20)*14, 56);}
					if(i>=26 && i<=32){ObjEffect_SetUVRect(obj, (i-15)*14, 42, (i-14)*14, 56);}
					if(i>=33 && i<=50){ObjEffect_SetUVRect(obj, (i-33)*14, 56, (i-32)*14, 70);}
					if(i==51){ObjEffect_SetUVRect(obj, (i-51)*14, 70, (i-50)*14, 84);}
					if(i==52){ObjEffect_SetUVRect(obj, (i-38)*14, 0, (i-37)*14, 14);}
					if(i==53){ObjEffect_SetUVRect(obj, (i-52)*14, 0, (i-51)*14, 14);}
					if(i==54){ObjEffect_SetUVRect(obj, (i-41)*14, 14, (i-40)*14, 28);}
					if(i==55){ObjEffect_SetUVRect(obj, (i-43)*14, 0, (i-42)*14, 14);}
					if(i==56 || i==57){ObjEffect_SetUVRect(obj, (i-40)*14, 0, (i-39)*14, 14);}
					if(i>=58 && i <=65){ObjEffect_SetUVRect(obj, (i-58)*14, 14, (i-57)*14, 28);}
					if(i==67){ObjEffect_SetUVRect(obj, 8*14, 0, 9*14, 14);}
					if(i==68){ObjEffect_SetUVRect(obj, 9*14, 0, 10*14, 14);}
					if(i==69){ObjEffect_SetUVRect(obj, 8*14, 14, 9*14, 28);}
					if(i==70){ObjEffect_SetUVRect(obj, 15*14, 0, 16*14, 14);}
					if(i==71){ObjEffect_SetUVRect(obj, 5*14, 0, 6*14, 14);}
				}
				if(mov==1){
					if(i<=11 || (i>=13 && i<=21) || (i>=23 && i<=25)){curdistx+=10;}
					if(i==8){curdistxb-=2;}
					if(i==12 || i==22){curdistx+=12; curdistxb+=2;}
					if( (i>=26 && i<=33) || i==36 || (i>=38 && i<=44) || (i>=46 && i<=51)){curdistx+=9; curdistxb-=1;}
					if(i==34 || i==35 || i==37 || i==45){curdistx+=9; curdistxb-=2;}
					if(i==38 || i==48){curdistx+=2; curdistxb+=2;}
					if(i==52 || i==55){curdistx+=12; curdistxb-=8;}
					if(i==53){curdistx+=8; curdistxb-=2;}
					if(i==54 || (i>=56 && i<=65) ){curdistx+=10; curdistxb-=1;}
					if(i==66){curdistx+=5;}
					if(i==67){curdistx+=6; curdistxb-=0;}
					if(i==68){curdistx+=12; curdistxb-=4;}
					if(i==69){curdistx+=6; curdistxb-=4;}
					if(i==70){curdistx+=12; curdistxb-=2;}
					if(i==71){curdistx+=12; curdistxb-=2;}
				}
			}
		}
	}
	
}

task DrawImageCustom(string, left, top, right, bottom, posx, posy, a, r, g, b, z, x, mov, movb)
{
	let drawnpic=CreateRObjEffect(string, 8);
	ObjEffect_SetUVRect(drawnpic, left, top, right, bottom);
	ObjEffect_SetXYRect(drawnpic, -(right-left)/2, -(bottom-top)/2, (right-left)/2, (bottom-top)/2);
	Obj_SetPosition(drawnpic, posx, posy);
	ObjEffect_SetColor(drawnpic, 4, a, r, g, b);
	yield;
	while(Obj_BeDeleted(drawnpic)==false){
		if(GetKeyState(VK_SHOT)==KEY_PUSH && z==1){
			Obj_Delete(drawnpic);
		}
		if(GetKeyState(VK_BOMB)==KEY_PUSH && x==1){
			Obj_Delete(drawnpic);
		}
		if(GetKeyState(VK_UP)==KEY_PUSH || GetKeyState(VK_DOWN)==KEY_PUSH){
			if(mov==1){Obj_Delete(drawnpic);}
		}
		if(GetKeyState(VK_LEFT)==KEY_PUSH || GetKeyState(VK_RIGHT)==KEY_PUSH){
			if(movb==1){Obj_Delete(drawnpic);}
		}
		yield;
	}
}

function NumberToString(number){
	let string=ToString(number);
	let stringb="";
	ascent(i in 0..length(string)){
		if(string[i]=='.'){
			break;
		}else{
			stringb=stringb~ToString(string[i]);
		}
	}
	return stringb;
}

function StringToNumber(string){
	let number=0;
	let numarray=['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
	ascent(i in 0..length(string)){
		ascent(j in 0..length(numarray)){
			if(string[i]==numarray[j]){
				number+=10^(length(string)-i-1)*j;
			}
		}
	}
	return number;
}

function DrawTextReturn(string, left, top, right, a, r, g, b)
{
	let stringarray=string~" ";
	let drawnarray=[];
	let xdist=right-left;
	let curdistx=0;
	let curdisty=0;
	let curdistxb=0;
	let num=0;
	let numb=0;
	let numc=0;
	ascent(i in 0..length(stringarray))
	{
	drawnarray=drawnarray~[CreateRObjEffect(textimg, 8)];
	}
	while(num<length(drawnarray)){
		while(curdistx+14<xdist && num<length(drawnarray)){
			SetLetter(drawnarray[num], stringarray[num], 0, 1);
			curdistx+=curdistxb;
			curdistxb=0;
			if(stringarray[num]==' ' || num==length(drawnarray)-1){
				numc=num;
			}
			num++;
		}
		curdistx=0;
		curdistxb=0;
		ascent(i in numb..numc){
			SetLetter(drawnarray[i], stringarray[i], 1, 1);
			ObjEffect_SetColor(drawnarray[i], 4, a, r, g, b);
			ObjEffect_SetXYRect(drawnarray[i], left+curdistx, top+curdisty, left+curdistx+14, top+curdisty+14);
			curdistx+=curdistxb;
			curdistxb=0;
		}
		numb=numc;
		num=numb;
		if(numc==length(drawnarray)-1){break;}
		curdisty+=7;
	}
	
	function SetLetter(obj, character, UV, mov){
		let characterarray=['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', '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(characterarray)){
			if(character==characterarray[i]){
				if(UV==1){
					if(i<=2){ObjEffect_SetUVRect(obj, (15+i)*14, 14, (16+i)*14, 28);}
					if(i>=3 && i<=20){ObjEffect_SetUVRect(obj, (i-3)*14, 28, (i-2)*14, 42);}
					if(i>=21 && i<=25){ObjEffect_SetUVRect(obj, (i-21)*14, 42, (i-20)*14, 56);}
					if(i>=26 && i<=32){ObjEffect_SetUVRect(obj, (i-15)*14, 42, (i-14)*14, 56);}
					if(i>=33 && i<=50){ObjEffect_SetUVRect(obj, (i-33)*14, 56, (i-32)*14, 70);}
					if(i==51){ObjEffect_SetUVRect(obj, (i-51)*14, 70, (i-50)*14, 84);}
					if(i==52){ObjEffect_SetUVRect(obj, (i-38)*14, 0, (i-37)*14, 14);}
					if(i==53){ObjEffect_SetUVRect(obj, (i-52)*14, 0, (i-51)*14, 14);}
					if(i==54){ObjEffect_SetUVRect(obj, (i-41)*14, 14, (i-40)*14, 28);}
					if(i==55){ObjEffect_SetUVRect(obj, (i-43)*14, 0, (i-42)*14, 14);}
					if(i==56 || i==57){ObjEffect_SetUVRect(obj, (i-40)*14, 0, (i-39)*14, 14);}
					if(i>=58 && i <=65){ObjEffect_SetUVRect(obj, (i-58)*14, 14, (i-57)*14, 28);}
					if(i==67){ObjEffect_SetUVRect(obj, 8*14, 0, 9*14, 14);}
					if(i==68){ObjEffect_SetUVRect(obj, 9*14, 0, 10*14, 14);}
					if(i==69){ObjEffect_SetUVRect(obj, 8*14, 14, 9*14, 28);}
					if(i==70){ObjEffect_SetUVRect(obj, 15*14, 0, 16*14, 14);}
					if(i==71){ObjEffect_SetUVRect(obj, 5*14, 0, 6*14, 14);}
				}
				if(mov==1){
					if(i<=11 || (i>=13 && i<=21) || (i>=23 && i<=25)){curdistx+=10;}
					if(i==8){curdistxb-=2;}
					if(i==12 || i==22){curdistx+=12; curdistxb+=2;}
					if( (i>=26 && i<=33) || i==36 || (i>=38 && i<=44) || (i>=46 && i<=51)){curdistx+=9; curdistxb-=1;}
					if(i==34 || i==35 || i==37 || i==45){curdistx+=9; curdistxb-=2;}
					if(i==38 || i==48){curdistx+=2; curdistxb+=2;}
					if(i==52 || i==55){curdistx+=12; curdistxb-=8;}
					if(i==53){curdistx+=8; curdistxb-=2;}
					if(i==54 || (i>=56 && i<=65) ){curdistx+=10; curdistxb-=1;}
					if(i==66){curdistx+=5;}
					if(i==67){curdistx+=6; curdistxb-=0;}
					if(i==68){curdistx+=12; curdistxb-=4;}
					if(i==69){curdistx+=6; curdistxb-=4;}
					if(i==70){curdistx+=12; curdistxb-=2;}
					if(i==71){curdistx+=12; curdistxb-=2;}
				}
			}
		}
	}
	
	return drawnarray;
}