#include <stdio.h>

#include "concorde.h"
#include "tornado.h"
#include "ysmaze2.h"
#include "mzedit.h"
#include "YsMacro.h"
#include "ysgui.h"

#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <winb.h>
#include <te.h>
#include <fntb.h>
#include <gui.h>
#include <wgb.h>
#include <egb.h>



extern int ActiveWin;
extern MAZEWIN mzWin[MAZEWIN_NUM];
extern int Ys11Id;
extern int MenuBarDlg;

static void PartsSwitchOff();
static void PartsSwitchOn();
static void InitSwapPage();
static void ClearSwapPage();
static int SwapPage();
static void PlayGame(int *stx,int *sty,int *sdir,MAZESCREEN *ms,MAZEMAP *mz);
static void Turn(int *dir,int ofset);
static void Progress(MAZEMAP *mz,int *x,int *y,int dir,int v);

static int stx,sty,dir;
static PAGE *wp,vp[2];

/*	initDataMZEDIT:pdEtcEnter:MJ_MITEML40の呼び出し関数	*/
int	EnterMaze()
{
	MAZEMAP *mz;
	MAZESCREEN ms;
	char *egb;
	char *egbstk;

	ms.cx=80;     /* 迷路描画域中心座標 */
	ms.cy=60;
	ms.x0=0;      /* 迷路描画範囲 */
	ms.y0=0;
	ms.x1=159;
	ms.y1=119;
	ms.wc=0x7fe0; /* 壁の色は黄色だ */
	ms.dc=0x003f; /* ドアは青いぞ */
	ms.cont=5;    /* 1m先になると,輝度が5%減衰するぞ */
	ms.mag=128;   /* 拡大率は128 */

	egb=MMI_GetEgbPtr();
	mz=&mzWin[ActiveWin].map;

	if(mzWin[ActiveWin].openflag==FALSE)
	{
		YsConfirm(Ys11Id,"アクティブなウィンドウがありません.",NULL);
		return NOERR;
	}

	PartsSwitchOff();


	/* ここからゲーム */
	MG_mosDisp(2);
	MG_pushEgbWork(egb,&egbstk);

	stx=0;
	sty=0;
	dir=32768;

	EGB_displayPage(egb,1,2);

	EGB_writePage(egb,1);
	EGB_displayStart(egb,0,0,0);
	EGB_displayStart(egb,2,4,4);
	EGB_displayStart(egb,3,160,120);
	EGB_color(egb,1,0x8000);
	EGB_clearScreen(egb);

	InitSwapPage();
	PlayGame(&stx,&sty,&dir,&ms,mz);
	ClearSwapPage();

	EGB_displayPage(egb,0,1);

	MG_popEgbWork(egb,egbstk);
	MG_mosDisp(3);
	/* ここまでゲーム */


	PartsSwitchOn();

	return NOERR ;
}


static void PartsSwitchOff()
{
	int i;
	MTL_setAtrObj(MenuBarDlg,MS_INACTIVEL40);
	for(i=0; i<MAZEWIN_NUM; i++)
	{
		MTL_setAtrObj(mzWin[i].win,MS_INACTIVEL40);
	}
}

static void PartsSwitchOn()
{
	int i;
	MTL_resetAtrObj(MenuBarDlg,~MS_INACTIVEL40);
	for(i=0; i<MAZEWIN_NUM; i++)
	{
		MTL_resetAtrObj(mzWin[i].win,~MS_INACTIVEL40);
	}
}


static void InitSwapPage()
{
	YGH_initPage(&vp[0],SEG_VRAMP,0x40000,512,120);
	YGH_initPage(&vp[1],SEG_VRAMP,0x60000,512,120);
	ClearSwapPage();
	wp=&vp[0];
	YGH_clearPage(wp,0);
	SwapPage();
	YGH_clearPage(wp,0);
	SwapPage();
	return;
}

static void ClearSwapPage()
{
	YGH_clearPage(&vp[0],0);
	YGH_clearPage(&vp[1],0);
	return;
}

static int SwapPage()
{
	int oy;

	if(wp==&vp[0])
	{
		oy=0;
		wp=&vp[1];
	}
	else
	{
		oy=128;
		wp=&vp[0];
	}

	EGB_displayStart(MMI_GetEgbPtr(),1,0,oy);
	return 0;
}

static void PlayGame(int *stx,int *sty,int *sdir,MAZESCREEN *ms,MAZEMAP *mz)
{
	extern unsigned char ball[];
	static char bmbuf[160*120*2]; /* 暴走したらここを見ろ */

	int edf,mx,my,dir,pad;
	static MAZEZBUF zbuf[160]; /* スタックにたまると困るからstatic */
	int rx0,ry0,rx1,ry1,rl;
	EVENT *pev;
	int vx,vy;
	int timer,clk;

	mx=((*stx)*mz->bl)+mz->bl/2;
	my=((*stx)*mz->bl)+mz->bl/2;
	dir=*sdir;

	rl=(ms->y1 -ms->y0)/mz->ly;
	rx0=ms->x1+1;
	ry0=ms->y0;
	rx1=rx0+rl*mz->lx+1;
	ry1=ry0+rl*mz->ly;

	edf=FALSE;
	clk=clock();
	while(edf==FALSE)
	{
		while((timer=PassedTime(clk))<20);
		clk=clock();

		MMI_iosense();
		if(MMI_GetEvnt(EVMOSDN,&pev)==0)
		{
			if((pev->what & EVMOSDN)!=0)
			{
				edf=TRUE;
			}
		}

		MazeGetLines(zbuf,mz,ms,mx,my,dir,1500);
		MazeDrawWalls(wp,mz,ms,zbuf);

		MazePrepareInsertBitmap(mx,my,dir,1500,ms);
		MazeInsertBitmap((char *)ball,64,64,200,200,mz->bl/2,mz->bl/2);
		MazeInsertBitmap((char *)ball,64,64,200,200,
				(mz->bl*mz->lx)-(mz->bl/2),(mz->bl*mz->ly)-(mz->bl/2));
		MazeFlushBitmap(wp,zbuf,bmbuf);

		if(mx/mz->bl==mz->lx-1  &&  my/mz->bl==mz->ly-1)
		{
			YGH_color(wp,0x7c00);
			YGH_print8font(wp,8,16,"GOAL!");
			YGH_print8font(wp,8,24,"CONGRATULATIONS!");
		}
		else if(mx<mz->bl && my<mz->bl)
		{
			YGH_color(wp,0x7fff);
			YGH_print8font(wp,8,16,"YOU ARE AT THE");
			YGH_print8font(wp,8,24,"START POINT.");
		}

		vx=-MulSinHq(16,dir);
		vy= MulCosHq(16,dir);
		YGH_color(wp,0x003f);
		YGH_circle(wp,120,100,20);
		YGH_line(wp,120,100,120+vx,100-vy);
		SwapPage();

		pad=255;
		SND_joy_in_2(0,&pad);
		if(!(pad & 1))Progress(mz,&mx,&my,dir, mz->bl*timer/500);
		if(!(pad & 2))Progress(mz,&mx,&my,dir,-mz->bl*timer/500);
		if(!(pad & 4))Turn(&dir, 20000*timer/1000);
		if(!(pad & 8))Turn(&dir,-20000*timer/1000);
	}

	*stx= mx/mz->bl;
	*sty= my/mz->bl;
	*sdir=dir;
}

static void Turn(int *dir,int ofset)
{
	*dir=(*dir+ofset)&65535;
}

static void Progress(MAZEMAP *mz,int *x,int *y,int dir,int v)
{
	int vx,vy;
	int lx=mz->bl * mz->lx;
	int ly=mz->bl * mz->ly;
	int x2,y2,bx,by,bx2,by2;

	vx=-MulSin(v,dir);
	vy=-MulCos(v,dir);

	bx= *x/(mz->bl);
	by= *y/(mz->bl);

	x2= *x+vx;
	while(x2<  0)x2+=lx;
	while(x2>=lx)x2-=lx;
	bx2= x2/mz->bl;
	if     (vx>0 && bx2!=bx && MazePass(mz,bx,by,3))return;
	else if(vx<0 && bx2!=bx && MazePass(mz,bx,by,1))return;
	else bx=bx2;

	y2= *y+vy;
	while(y2<  0)y2+=ly;
	while(y2>=ly)y2-=ly;
	by2= y2/mz->bl;
	if     (vy>0 && by2!=by && MazePass(mz,bx,by,2))return;
	else if(vy<0 && by2!=by && MazePass(mz,bx,by,0))return;

	*x=x2;
	*y=y2;
}

