#include <stdio.h>
#include <math.h>
#include <time.h>

#include "MAIN.h"
#include "UTIL.h"
#include "EGBCTRL.h"
#include "PAGECTRL.h"
#include "BGM.h"

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

#include "SPRGDEMO.h"


struct MassSpring
{
	int x0,y0;
	int L0,cycle;
	int x,y;
	int c;
	int phase;
};


static int writePage=0;
static int nSpring=0;
#define maxNSpring 8
static struct MassSpring ms[maxNSpring];


void SpringDemoInit(void)
{
	int i=0;
	nSpring=6;

	for(i=0; i<nSpring; ++i)
	{
		ms[i].x0=25+i*50;
		ms[i].phase=(i&1)*2-1;
	}

	// T130 -> 130 tones per minutes. -> 0.461538 seconds.
	// 65536/n increment per 0.461538 seconds.

	ms[0].y0=0;
	ms[0].L0=140;
	ms[0].cycle=32768*1000/462;
	ms[0].x=ms[0].x0;
	ms[0].y=40;
	ms[0].c=15;

	ms[1].y0=0;
	ms[1].L0=140;
	ms[1].cycle=32768*1000/462;
	ms[1].x=ms[1].x0;
	ms[1].y=40;
	ms[1].c=15*32;

	ms[2].y0=0;
	ms[2].L0=140;
	ms[2].cycle=32768*1000/462;
	ms[2].x=ms[2].x0;
	ms[2].y=40;
	ms[2].c=15*32+15;

	ms[3].y0=0;
	ms[3].L0=140;
	ms[3].cycle=32768*1000/462;
	ms[3].x=ms[3].x0;
	ms[3].y=40;
	ms[3].c=15*1024;

	ms[4].y0=0;
	ms[4].L0=140;
	ms[4].cycle=32768*1000/462;
	ms[4].x=ms[4].x0;
	ms[4].y=40;
	ms[4].c=15*1024+15;

	ms[5].y0=0;
	ms[5].L0=140;
	ms[5].cycle=32768*1000/462;
	ms[5].x=ms[5].x0;
	ms[5].y=40;
	ms[5].c=15*1024+15*32;
}

void MoveSpring(struct MassSpring *ms,int t)
{
	// t 100*sec
	int angle,disp;
	angle=ms->cycle*t/100;
	disp=ms->phase*MulSin(80,angle);

	ms->y=ms->L0+disp;
}

void SpringDemoOneStep(int t,int bgmBegin)
{
	int i;
	for(i=0; i<nSpring; ++i)
	{
		MoveSpring(&ms[i],t);
	}

	YGH_clearPage(&rp[writePage],0);

	for(i=0; i<nSpring; ++i)
	{
		YGH_color(&rp[writePage],ms[i].c);
		{
			YGH_line(&rp[writePage],ms[i].x0,ms[i].y0,ms[i].x0,ms[i].y0+10);
			YGH_line(&rp[writePage],ms[i].x,ms[i].y-10,ms[i].x,ms[i].y-20);

			int j,x0,y0,x1,y1,lastX,lastY,dx;
			x0=ms[i].x0;
			y0=ms[i].y0+10;
			x1=ms[i].x;
			y1=ms[i].y-20;

			lastX=x0;
			lastY=y0;
			dx=5;
			for(j=1; j<=29; j+=2)
			{
				int x=ms[i].x0+dx;
				int y=y0+(y1-y0)*j/30;
				YGH_line(&rp[writePage],lastX,lastY,x,y);
				lastX=x;
				lastY=y;
				dx=-dx;
			}
			YGH_line(&rp[writePage],lastX,lastY,x1,y1);

		}
		YGH_filledBox(&rp[writePage],ms[i].x-10,(ms[i].y-10),ms[i].x+10,(ms[i].y+10));
	}


	{
		int msgCounter=(GetBGMCounter()-bgmBegin)/2;
		YGH_color(&rp[writePage],32767);
		switch(msgCounter)
		{
		case 0:
			YGH_print8font(&rp[writePage],32,120,"FOR THOSE WHO USED MY PROGRAMS");
			YGH_print8font(&rp[writePage],32,130,"IN 1990s");
			break;
		case 1:
			YGH_print8font(&rp[writePage],48,120,"VERY GOOD TO SEE YOU!");
			YGH_print8font(&rp[writePage],48,130,"AND THANK YOU FOR WATCHING!");
			break;
		case 2:
			YGH_print8font(&rp[writePage],80,120,"I AM STILL ALIVE");
			YGH_print8font(&rp[writePage],80,130,"AS OF OCTOBER 2018.");
			break;
		case 3:
			YGH_print8font(&rp[writePage],56,120,"ALTHOUGH I AM LOSING HAIR.");
			YGH_print8font(&rp[writePage],56,130,"");
			break;
		}
	}


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

void SpringDemoCleanUp(void)
{
}


void SpringDemo(int bgmBegin,int bgmStop)
{
	clock_t lastClk,t0;

	SetUpEGB320x240_320x240();
	SetUpPage320x240_320x240();

	lastClk=clock();
	t0=lastClk;

	SpringDemoInit();
	for(;;)
	{
		int elapsed;

		// clock() shouldn't be used for real-time clock in most of the platforms.
		// It's fine on TOWNS OS native app.
		clock_t newClk;
		for(newClk=clock(); (newClk-lastClk)*19<CLOCKS_PER_SEC; newClk=clock())
		{
		}
		lastClk=newClk;

		elapsed=(newClk-t0)*100/CLOCKS_PER_SEC;
		SpringDemoOneStep(elapsed,bgmBegin);

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

