#include <time.h>
#include "ACRODEMO.h"
#include "MAIN.h"
#include "UTIL.h"
#include "EGBCTRL.h"
#include "PAGECTRL.h"
#include "BGM.h"

#include "../airforce/airforce.h"
#include "../tomahawk/tomahawk.h"

#define DEF_SKY    28*1024+28
#define DEF_GROUND 25*1024

static int airpos[6]={0,0,0,0,0};
static int eyepos[6]={0,0,0,0,0};

void AcroDemo_360(PAGE rp[2],int bgmStop)
{
	clock_t clk0=clock(); // Not to worry FM-TOWNS clock() returns real time.  It is a useful version of clock().
	int writePage=0;

	airpos[0]=150000;
	airpos[1]=10000;
	airpos[2]=-250000;
	airpos[3]=0;
	airpos[4]=0;
	airpos[5]=0;

	eyepos[0]=-1500;
	eyepos[1]=11500;
	eyepos[2]=-100000;
	eyepos[3]=-16384;
	eyepos[4]=-4096;
	eyepos[5]=0;

	HideBuffers();
	clock_t lastClock=0;
	for(;;)
	{
		clock_t now=clock();
		int timer=(now-clk0)*100/CLOCKS_PER_SEC;
		int dt=timer-lastClock;
		lastClock=timer;

		{
			// 300kt=150m/s, 10fps-> 15m/frame
			{
				int fv[3],uv[3];
				AngleToVector(fv,uv,airpos+3);

				fv[0]*=150; // 15000cm/sec -> 150cm/0.01sec
				fv[1]*=150;
				fv[2]*=150;

				fv[0]*=dt;
				fv[1]*=dt;
				fv[2]*=dt;

				fv[0]/=65536;
				fv[1]/=65536;
				fv[2]/=65536;

				airpos[0]+=fv[0];
				airpos[1]+=fv[1];
				airpos[2]+=fv[2];
			}

			int ev[3]={1300,200,-800};
			int uv[3]={0,256,0};
			VectorToAngle(eyepos+3,ev,uv);

			eyepos[0]=airpos[0]-ev[0];
			eyepos[1]=airpos[1]-ev[1];
			eyepos[2]=airpos[2]-ev[2];


			if(timer<100)
			{
				int phaseTimer=timer;
				airpos[5]=-phaseTimer*145;
			}
			else if(timer<1050)
			{
				int phaseTimer=timer-100;
				airpos[3]=-65536*phaseTimer/950;
				airpos[5]=-14500;
			}
			else if(timer<1250)
			{
				int phaseTimer=timer-1050;
				airpos[3]=0;
				airpos[5]=-14500+phaseTimer*145;
			}
			else if(timer<2200)
			{
				int phaseTimer=timer-1250;
				airpos[3]=65536*phaseTimer/950;
				airpos[5]=14500;
			}
			else if(timer<2300)
			{
				int phaseTimer=timer-2200;
				airpos[3]=0;
				airpos[5]=14500-phaseTimer*145;
			}
			else
			{
				airpos[3]=0;
				airpos[5]=0;
			}
		}

		{
			PRJSCRN prj;
			int gndSky[2]={DEF_GROUND,DEF_SKY};
			int rect[4]={0,0,255,255};

			prj.prj.cx=128;
			prj.prj.cy=128;
			prj.prj.mag=100;
			prj.cpz=150;
			prj.lx=128;
			prj.ly=128;

			// YGH_clearPage(&rp[writePage],0);
			AL_Horizon(&rp[writePage],eyepos+3,rect,gndSky,&prj);

			AL_Draw(&rp[writePage],map,eyepos,&prj);

			AL_Set_Eye(eyepos,&prj);
			AL_Insert_Model(f117a,airpos);
			AL_Insert_Lax(map);
			AL_Flush_Buffer(&rp[writePage]);

			ShowBuffer(writePage);
			writePage=1-writePage;
		}

		if(2500<timer || 0!=CheckButtonPress() || bgmStop<=GetBGMCounter())
		{
			break;
		}
	}
}

void AcroDemo_Roll(PAGE rp[2],int bgmStop)
{
	clock_t clk0=clock(); // Not to worry FM-TOWNS clock() returns real time.  It is a useful version of clock().
	clock_t lastClock=0;
	int writePage=0;

	airpos[0]=150000;
	airpos[1]=20000;
	airpos[2]=-250000;
	airpos[3]=0;
	airpos[4]=0;
	airpos[5]=0;

	eyepos[0]=-1500;
	eyepos[1]=11500;
	eyepos[2]=-100000;
	eyepos[3]=-16384;
	eyepos[4]=-4096;
	eyepos[5]=0;

	HideBuffers();
	for(;;)
	{
		clock_t now=clock();
		int timer=(now-clk0)*100/CLOCKS_PER_SEC;
		int dt=timer-lastClock;
		lastClock=timer;

		{
			// 300kt=150m/s, 10fps-> 15m/frame
			{
				int fv[3],uv[3];
				AngleToVector(fv,uv,airpos+3);

				fv[0]*=150; // 15000cm/sec -> 150cm/0.01sec
				fv[1]*=150;
				fv[2]*=150;

				fv[0]*=dt;
				fv[1]*=dt;
				fv[2]*=dt;

				fv[0]/=65536;
				fv[1]/=65536;
				fv[2]/=65536;

				airpos[0]+=fv[0];
				airpos[1]+=fv[1];
				airpos[2]+=fv[2];
			}

			int ev[3]={650,-2048,-400};
			int uv[3]={0,256,0};
			VectorToAngle(eyepos+3,ev,uv);

			eyepos[0]=airpos[0]-ev[0];
			eyepos[1]=airpos[1]-ev[1];
			eyepos[2]=airpos[2]-ev[2];

			airpos[5]=-timer*650;
		}

		{
			PRJSCRN prj;
			int gndSky[2]={DEF_GROUND,DEF_SKY};
			int rect[4]={0,0,255,255};

			prj.prj.cx=128;
			prj.prj.cy=128;
			prj.prj.mag=100;
			prj.cpz=150;
			prj.lx=128;
			prj.ly=128;

			// YGH_clearPage(&rp[writePage],0);
			AL_Horizon(&rp[writePage],eyepos+3,rect,gndSky,&prj);

			AL_Draw(&rp[writePage],map,eyepos,&prj);

			AL_Set_Eye(eyepos,&prj);
			AL_Insert_Model(a10a,airpos);
			AL_Insert_Lax(map);
			AL_Flush_Buffer(&rp[writePage]);

			ShowBuffer(writePage);
			writePage=1-writePage;
		}

		if(500<timer || 0!=CheckButtonPress() || bgmStop<=GetBGMCounter())
		{
			break;
		}
	}
}

void AcroDemo_CubanEight(PAGE rp[2],int bgmStop)
{
	clock_t clk=clock(); // Not to worry FM-TOWNS clock() returns real time.  It is a useful version of clock().
	int writePage=0;
	int phase=0,phaseCount=0;

	airpos[0]=150000;
	airpos[1]=20000;
	airpos[2]=10000;
	airpos[3]=32768;
	airpos[4]=0;
	airpos[5]=0;

	eyepos[0]=0;
	eyepos[1]=60000;
	eyepos[2]=0;
	eyepos[3]=-16384;
	eyepos[4]=-4096;
	eyepos[5]=0;

	HideBuffers();
	for(;;)
	{
		{
			// 300kt=150m/s, 10fps-> 15m/frame
			{
				int fv[3],uv[3];
				AngleToVector(fv,uv,airpos+3);
				airpos[0]+=fv[0]/64;
				airpos[1]+=fv[1]/64;
				airpos[2]+=fv[2]/64;;
			}

			// Imaichi
			//int ev[3]={airpos[0]-eyepos[0],airpos[1]-eyepos[1],airpos[2]-eyepos[2]};
			//int uv[3]={0,256,0};
			//VectorToAngle(eyepos+3,ev,uv);

			int ev[3]={0,-200,2000};
			int uv[3]={0,256,0};
			VectorToAngle(eyepos+3,ev,uv);

			eyepos[0]=airpos[0]-ev[0];
			eyepos[1]=airpos[1]-ev[1];
			eyepos[2]=airpos[2]-ev[2];

			switch(phase)
			{
			case 0:
				++phaseCount;
				if(10<phaseCount)
				{
					phase++;
					phaseCount=0;
				}
				break;
			case 1:
				PitchUp(airpos+3,airpos+3,256);
				++phaseCount;
				if(160<=phaseCount)
				{
					phase++;
					phaseCount=0;
				}
				break;
			case 2:
			case 4:
				++phaseCount;
				airpos[5]+=2048;
				if(80<=phaseCount)
				{
					phase++;
					phaseCount=0;
				}
				break;
			case 3:
				PitchUp(airpos+3,airpos+3,256);
				++phaseCount;
				if(192<=phaseCount)
				{
					phase++;
					phaseCount=0;
				}
				break;
			case 5:
				PitchUp(airpos+3,airpos+3,256);
				++phaseCount;
				if(32<=phaseCount)
				{
					phase++;
					phaseCount=0;
				}
				break;
			case 6:
				++phaseCount;
				if(64<=phaseCount)
				{
					return;
				}
				break;
			}
		}

		{
			PRJSCRN prj;
			int gndSky[2]={DEF_GROUND,DEF_SKY};
			int rect[4]={0,0,255,255};

			prj.prj.cx=128;
			prj.prj.cy=128;
			prj.prj.mag=100;
			prj.cpz=150;
			prj.lx=128;
			prj.ly=128;

			// YGH_clearPage(&rp[writePage],0);
			AL_Horizon(&rp[writePage],eyepos+3,rect,gndSky,&prj);

			AL_Draw(&rp[writePage],map,eyepos,&prj);

			AL_Set_Eye(eyepos,&prj);
			AL_Insert_Model(a10a,airpos);
			AL_Insert_Lax(map);
			AL_Flush_Buffer(&rp[writePage]);

			ShowBuffer(writePage);
			writePage=1-writePage;
		}

		{
			clock_t nextClk;
			for(;;)
			{
				nextClk=clock();
				if((nextClk-clk)*30>CLOCKS_PER_SEC)
				{
					break;
				}
			}
			clk=nextClk;
		}

		if(0!=CheckButtonPress() || bgmStop<=GetBGMCounter())
		{
			break;
		}
	}
}

void AcroDemo_VerticalCuban(PAGE rp[2],int bgmStop)
{
	clock_t clk0=clock(); // Not to worry FM-TOWNS clock() returns real time.  It is a useful version of clock().
	clock_t lastClock=0;
	int writePage=0;

	airpos[0]=150000;
	airpos[1]=20000;
	airpos[2]=0;
	airpos[3]=32768;
	airpos[4]=0;
	airpos[5]=0;

	eyepos[0]=-1500;
	eyepos[1]=11500;
	eyepos[2]=-100000;
	eyepos[3]=-16384;
	eyepos[4]=-4096;
	eyepos[5]=0;

	HideBuffers();
	for(;;)
	{
		clock_t now=clock();
		int timer=(now-clk0)*100/CLOCKS_PER_SEC;
		int dt=timer-lastClock;
		lastClock=timer;

		{
			// 300kt=150m/s, 10fps-> 15m/frame
			{
				int fv[3],uv[3];
				AngleToVector(fv,uv,airpos+3);

				fv[0]*=150; // 15000cm/sec -> 150cm/0.01sec
				fv[1]*=150;
				fv[2]*=150;

				fv[0]*=dt;
				fv[1]*=dt;
				fv[2]*=dt;

				fv[0]/=65536;
				fv[1]/=65536;
				fv[2]/=65536;

				airpos[0]+=fv[0];
				airpos[1]+=fv[1];
				airpos[2]+=fv[2];
			}

			int ev[3]={650,-2048,-400};
			int uv[3]={0,256,0};
			VectorToAngle(eyepos+3,ev,uv);

			eyepos[0]=airpos[0]-ev[0];
			eyepos[1]=airpos[1]-ev[1];
			eyepos[2]=airpos[2]-ev[2];


			if(timer<500)
			{
				int phaseTimer=timer;
				airpos[4]=phaseTimer*24576/500;
			}
			else if(timer<550)
			{
				int phaseTimer=timer-500;
				airpos[4]=24576;
				airpos[5]=phaseTimer*32768/50;
			}
			else if(timer<1500)
			{
				int phaseTimer=timer-550;
				airpos[3]=0;
				airpos[4]=8192+phaseTimer*49152/950;
				airpos[5]=0;
			}
			else if(timer<1550)
			{
				int phaseTimer=timer-1500;
				airpos[4]=57344;
				airpos[5]=phaseTimer*32768/50;
			}
			else if(timer<2000)
			{
				int phaseTimer=timer-1550;
				airpos[3]=32768;
				airpos[4]=-24576+24576*phaseTimer/450;
				airpos[5]=0;
			}
			else
			{
				airpos[4]=0;
				airpos[5]=0;
			}
		}

		{
			PRJSCRN prj;
			int gndSky[2]={DEF_GROUND,DEF_SKY};
			int rect[4]={0,0,255,255};

			prj.prj.cx=128;
			prj.prj.cy=128;
			prj.prj.mag=100;
			prj.cpz=150;
			prj.lx=128;
			prj.ly=128;

			// YGH_clearPage(&rp[writePage],0);
			AL_Horizon(&rp[writePage],eyepos+3,rect,gndSky,&prj);

			AL_Draw(&rp[writePage],map,eyepos,&prj);

			AL_Set_Eye(eyepos,&prj);
			AL_Insert_Model(f16c,airpos);
			AL_Insert_Lax(map);
			AL_Flush_Buffer(&rp[writePage]);

			ShowBuffer(writePage);
			writePage=1-writePage;
		}

		if(2400<timer || 0!=CheckButtonPress() || bgmStop<=GetBGMCounter())
		{
			break;
		}
	}
}

void AcroDemo(PAGE rp[2],int bgmStop1,int bgmStop2,int bgmStop3)
{
	SetUpEGB256x256_256x256();
	SetUpPage256x256_256x256();

	AcroDemo_360(rp,bgmStop1);
	AcroDemo_Roll(rp,bgmStop2);
	AcroDemo_VerticalCuban(rp,bgmStop3);
}

