#include <sys/bios.h>
#include "KSFont.h"
#include "KSKey.h"
#include "chuka.h"
#include "data.h"
#include "GameMain.h"

#include "GPanel.h"
#include "GameBall.h"
#include "GChara.h"
#include "GCursol.h"

int g_nGameCount;		/* ゲームカウント */
int g_nGameFinish;		/* バトル状況（0.対戦中 1.決着 2.引分） */
int g_nGamePlayer;		/* 攻撃プレイヤー（0.1P 1.2P） */

int g_nGameFirstAttack;	/* 先攻プレイヤー（0.1P 1.2P） */
int g_nGameFirstBall;	/* ハンディキャップ（1〜3） */
int g_nGameFirstWork;	/* ハンディキャップ（1〜3） */

int g_nGameWin;			/* 前回勝利者( -1.どちらでもない  0.1P  1.2P ) */
int g_nGameWinCount[2];	/* ゲーム勝利数(0.1P 1.2P) */

int g_nGameWinMax;		/* 勝利者アニメーション用のボールパネル座標 */
int g_nGameWinX[BASE_X * BASE_Y];
int g_nGameWinY[BASE_X * BASE_Y];



/*=================================================================*/
/* ゲームループ */
/*=================================================================*/
int CGameMain_Loop( void )
{
	static int m_nMode = 0;
	int m_nRet;


	switch( m_nMode )
	{
	case 0: /* ゲーム初期化 */
		CGameMain_Init();
		m_nMode = 100;
		break;

	case 100: /* タイトル画面の初期化 */
		/* グラフィックデータ読込 */
		KSFontInit();
		LoadFontData( 100 );

		/* 画面クリア */
		KSScreenFill( 0, SCREEN1, 0, 0, 32, 32 );
		KSScreenFill( 0, SCREEN2, 0, 0, 32, 32 );
		sprite_set_range( 0, 0 );
		m_nMode = 150;
		break;

	case 150: /* タイトル画面 */
		m_nRet = CGameMain_TitleView();
		if( m_nRet == 1 ) m_nMode = 300;
		break;

	case 300: /* 対決仕様の初期化 */
		/* グラフィックデータ読込 */
		KSFontInit();
		LoadFontData( 300 );

		/* 画面クリア */
		KSScreenFill( 0, SCREEN1, 0, 0, 32, 32 );
		KSScreenFill( 0, SCREEN2, 0, 0, 32, 32 );
		sprite_set_range( 0, 0 );

		CGameMain_VSView( 1 );

		m_nMode = 350;
		break;

	case 350: /* 対決仕様 */
		if( CGameMain_VSView( 0 ) == 1 ) m_nMode = 500;
		break;

	case 500: /* バトルの初期化 */
		KSFontInit();
		LoadFontData( 500 );

		/* 画面クリア */
		KSScreenFill( 0, SCREEN1, 0, 0, 32, 32 );
		KSScreenFill( 0, SCREEN2, 0, 0, 32, 32 );
		sprite_set_range( 0, 0 );

		CGameMain_InitBattle();
		CGamePanel_Init();
		CGameBall_Init();
		CGameCursol_Init();
		CGameTime_Init();
		CGameChara_Init();
		CGameAI_Init();
		m_nMode = 550;
		break;

	case 550: /* バトル */
		if( g_nGameFinish == 0 ){
			CGameAI_Action( g_nGamePlayer );
			CGameCursol_SetBall();
			CGameCursol_Move();
			CGameTime_Action();
		}
		CGamePanel_Action( 0 );

		CGamePanel_View();
		CGameBall_View();
		CGameCursol_View();
		CGameTime_View();
		CGameChara_View();

		/* バトル終了判定 */
		if( CGameMain_WinAnimation( 0 ) == 1 ){
			m_nMode = 0;
		}
		break;

	default:
		return FUNC_FALSE;
	}

	/* ゲームカウントの加算 */
	g_nGameCount++;

	/* 正常終了 */
	return FUNC_TRUE;
}



/*=================================================================*/
/* ゲーム初期化 */
/*=================================================================*/
int CGameMain_Init( void )
{
	g_nGameFinish = 0;
	g_nGamePlayer = 0;
	g_nGameFirstAttack = 0;	/* 先攻プレイヤー（0.1P 1.2P） */
	g_nGameFirstBall = 1;	/* ハンディキャップ（1〜3） */

	/* 正常終了 */
	return FUNC_TRUE;
}



/*=================================================================*/
/* バトル初期化 */
/*=================================================================*/
int CGameMain_InitBattle( void )
{
	g_nGameFinish = 0;
	g_nGamePlayer = g_nGameFirstAttack;
	g_nGameFirstWork = g_nGameFirstBall;

	/* 正常終了 */
	return FUNC_TRUE;
}





/*=================================================================*/
/* タイトルの表示 */
/*=================================================================*/
int CGameMain_TitleView( void )
{
	/* タイトル */
	KSScreenSet( 1, SCREEN1, 0, 0 );

	/* Push any key */
	if( (g_nGameCount % 30) >= 10 ){
		KSScreenSet( 2, SCREEN2, 2, 13 );
	}else{
		KSScreenSetPattern( 2, 0, SCREEN2, 2, 13 );
	}

	/* ボタン押下でバトル開始 */
	if( KSKeyGet( KEY_START, 1 ) ){
		return 1;
	}

	/* 正常終了 */
	return FUNC_TRUE;
}



/*=================================================================*/
/* 対決仕様の表示 */
/*=================================================================*/
int CGameMain_VSView( int p_nFlag )
{
	static int m_nTaiketsu[28*2] = { 0,-3,-3,-5,-5,-6,-6, -6,-6,-6,-5,-5,-3,-3,
									 0, 3, 3, 5, 5, 6, 6,  6, 6, 6, 5, 5, 3, 3,
									 0,-3,-3,-5,-5,-6,-6, -6,-6,-6,-5,-5,-3,-3,
									 0, 3, 3, 5, 5, 6, 6,  6, 6, 6, 5, 5, 3, 3 };
	static int m_nTaiketsuCount = 0;
	static int m_nTimeCount = 0;

	static int m_nSenkouX[6] = { 112+12, 112+12+16, 112+12+32, 112-28, 112-28-16, 112-28-32 };
	int m_nKey;
	int n;


	/* フラグのチェック */
	if( p_nFlag == 1 ){
		/* タイムカウント初期化 */
		m_nTimeCount = 0;

		/* 対決仕様のスプライト割当 */
		m_nTaiketsuCount = 0;
		KSSpriteSet( 0, 100, 8* 6, -32, 0 );
		KSSpriteSet( 1, 101, 8*10, -32, 0 );
		KSSpriteSet( 2, 102, 8*14, -32, 0 );
		KSSpriteSet( 3, 103, 8*18, -32, 0 );

		/* ハンディキャップのスプライト割当 */
		KSSpriteSet(10, 310, m_nSenkouX[0], 144, 1 );
		KSSpriteSet(11, 310, m_nSenkouX[1], 144, 1 );
		KSSpriteSet(12, 310, m_nSenkouX[2], 144, 1 );
		KSSpriteSet(13, 320, m_nSenkouX[3], 144, 1 );
		KSSpriteSet(14, 320, m_nSenkouX[4], 144, 1 );
		KSSpriteSet(15, 320, m_nSenkouX[5], 144, 1 );
		if( g_nGameFirstAttack == 0 && g_nGameFirstBall >= 1 ) KSSpriteMove( 10, m_nSenkouX[0], 124 );
		if( g_nGameFirstAttack == 0 && g_nGameFirstBall >= 2 ) KSSpriteMove( 11, m_nSenkouX[1], 124 );
		if( g_nGameFirstAttack == 0 && g_nGameFirstBall >= 3 ) KSSpriteMove( 12, m_nSenkouX[2], 124 );
		if( g_nGameFirstAttack == 1 && g_nGameFirstBall >= 1 ) KSSpriteMove( 13, m_nSenkouX[3], 124 );
		if( g_nGameFirstAttack == 1 && g_nGameFirstBall >= 2 ) KSSpriteMove( 14, m_nSenkouX[4], 124 );
		if( g_nGameFirstAttack == 1 && g_nGameFirstBall >= 3 ) KSSpriteMove( 15, m_nSenkouX[5], 124 );

		return FUNC_TRUE;
	}


	/* 対決仕様アニメーション */
	KSSpriteMove( 0, 8* 6, 6 + m_nTaiketsu[m_nTaiketsuCount+18] );
	KSSpriteMove( 1, 8*10, 6 + m_nTaiketsu[m_nTaiketsuCount+12] );
	KSSpriteMove( 2, 8*14, 6 + m_nTaiketsu[m_nTaiketsuCount+ 6] );
	KSSpriteMove( 3, 8*18, 6 + m_nTaiketsu[m_nTaiketsuCount+ 0] );
	m_nTaiketsuCount++;
	if( m_nTaiketsuCount >= 28 ) m_nTaiketsuCount = 0;

	/* タイムカウントの加算（最大14） */
	if( m_nTimeCount < 14 ){
		m_nTimeCount++;

		/* ライカ表示 */
		KSScreenSet( 1, SCREEN1,  28-m_nTimeCount, 3 ); /* ライカ(1P) */

		/* ライチ表示 */
		KSScreenSet( 2, SCREEN1, -14+m_nTimeCount, 3 ); /* ライチ(2P) */

		/* タグ表示 */
		KSScreenSet( 200, SCREEN2, 23, 14 ); /* 1Play */
		KSScreenSet( 202, SCREEN2,  0, 14 ); /* COM */

		/* ハンディキャップ枠表示 */
		KSScreenSet( 300, SCREEN2, 6, 15 );

		/* 先攻後攻表示 */
		KSScreenSet( 330, SCREEN2, 10, 13 );
	}

	/* 先入珠数の処理 */
	m_nKey = KSKeyGetX();
	if( g_nGameFirstAttack == 0 && m_nKey > 0 ){
		if( ++g_nGameFirstBall > 3 ) g_nGameFirstBall = 3;
	}else if( g_nGameFirstAttack == 0 && m_nKey < 0 ){
		if( --g_nGameFirstBall < 1 ){
			g_nGameFirstAttack = 1;
			g_nGameFirstBall = 1;
		}
	}else if( g_nGameFirstAttack == 1 && m_nKey < 0 ){
		if( ++g_nGameFirstBall > 3 ) g_nGameFirstBall = 3;
	}else if( g_nGameFirstAttack == 1 && m_nKey > 0 ){
		if( --g_nGameFirstBall < 1 ){
			g_nGameFirstAttack = 0;
			g_nGameFirstBall = 1;
		}
	}
	/* 先入珠数表示 */
	if( m_nKey != 0 ){
		for( n=0; n<6; n++ ){
			KSSpriteMove( 10+n, m_nSenkouX[n], 144 );
		}
		if( g_nGameFirstAttack == 0 && g_nGameFirstBall >= 1 ) KSSpriteMove( 10, m_nSenkouX[0], 124 );
		if( g_nGameFirstAttack == 0 && g_nGameFirstBall >= 2 ) KSSpriteMove( 11, m_nSenkouX[1], 124 );
		if( g_nGameFirstAttack == 0 && g_nGameFirstBall >= 3 ) KSSpriteMove( 12, m_nSenkouX[2], 124 );
		if( g_nGameFirstAttack == 1 && g_nGameFirstBall >= 1 ) KSSpriteMove( 13, m_nSenkouX[3], 124 );
		if( g_nGameFirstAttack == 1 && g_nGameFirstBall >= 2 ) KSSpriteMove( 14, m_nSenkouX[4], 124 );
		if( g_nGameFirstAttack == 1 && g_nGameFirstBall >= 3 ) KSSpriteMove( 15, m_nSenkouX[5], 124 );
	}

	/* ボタン押下でバトル開始 */
	if( KSKeyGet( KEY_A, 1 ) ){
		return 1;
	}

	/* 正常終了 */
	return FUNC_TRUE;
}



/*=================================================================*/
/* ゲーム勝利判定 */
/*=================================================================*/
int CGameMain_Judge( int p_nTX, int p_nTY, int p_nPlayer )
{
	const static int zx[8] = { 0, 1, 1, 1, 0,-1,-1,-1};
	const static int zy[8] = {-1,-1, 0, 1, 1, 1, 0,-1};
	int flag, ct, max;
	int x, y, z, z2;

	/* 対戦中以外なら戻る */
	if( g_nGameFinish > 0 ) return FUNC_TRUE;

	/* 判定初期化 */
	flag = 0;
	g_nGameWinMax = 0;
	g_nGameWinX[0] = p_nTX;
	g_nGameWinY[0] = p_nTY;

	/* 勝敗データの収集 */
	for( z=0; z<4; z++ ){
		ct = 1;
		max = 0;
		for( z2=0; z2<2; z2++ ){
			x = p_nTX;
			y = p_nTY;
			while( TRUE ){
				x += zx[z + z2*4];
				y += zy[z + z2*4];
				if(x<0 || x>6 || y<0 || y>5) break;
				if( CGameBall_GetBallColor( x, y ) != (1+p_nPlayer) ) break;
				ct++;
				max++;
				g_nGameWinX[g_nGameWinMax + max] = x;
				g_nGameWinY[g_nGameWinMax + max] = y;
			}
		}
		/* 珠が４つ以上連結なら勝利 */
		if( ct >= 4 ){
			flag = 1;
			g_nGameWinMax += max;
		}
	}

	/* 勝敗データの振り分け */
	if( flag == 1 ){
		/* 勝敗決着 */
		g_nGameFinish = 1;
		if( p_nPlayer == 0 ){
/*			Chara[0].SetMode( 1 );*/
/*			Chara[1].SetMode( 5 );*/
			g_nGameWin = p_nPlayer;	/* 1Pが勝利したことを記録 */
			g_nGameWinCount[0]++;	/* 1Pの勝利数を加算 */
		}else{
/*			Chara[0].SetMode( 5 );*/
/*			Chara[1].SetMode( 1 );*/
			g_nGameWin = p_nPlayer;	/* 2Pが勝利したことを記録 */
			g_nGameWinCount[1]++;	/* 2Pの勝利数を加算 */
		}
	}else{
		/* 空きエリアの算出(0.ない 1-42.個) */
		ct = 0;
		for( y=0; y<6; y++ ){
			for( x=0; x<7; x++ ){
				if( CGameBall_GetBallColor( x, y ) == 0 ) ct++;
			}
		}

		/* 引き分け */
		if( ct == 0 ){
			g_nGameFinish = 2;
/*			Chara[0].SetMode( 5 );*/
/*			Chara[1].SetMode( 5 );*/
		}
	}

	/* 勝敗が決着した場合は勝利アニメーション起動 */
	if( g_nGameFinish > 0 ){
		CGameMain_WinAnimation( 1 );
		CGamePanel_Action( 3 );
	}

	/* 正常終了 */
	return FUNC_TRUE;
}




/*=================================================================*/
/* ゲーム勝利アニメーション */
/*=================================================================*/
int CGameMain_WinAnimation( int p_nFlag )
{
	static int Ani[2] = {0,10};
	static int mode = 0;
	static int count = 0;
	static long scr = 0;
	static long scrpt = 0;
	static long scrframe = 0;
	static long kaminari = 0;
	int pt, x, y, n;

	/* 初期化 */
	if( p_nFlag ){
		if( g_nGameFinish == 0 ) mode = 0;
		if( g_nGameFinish == 1 ) mode = 1;
		if( g_nGameFinish == 2 ) mode = 90;
		return FUNC_TRUE;
	}


	switch( mode ){
	case 1: /* 勝利確定 */
		mode = 2;
		count = 0;
		scr = 0;
		scrpt = 0;
		scrframe = 0;
		kaminari = 0;
		break;

	case 2: /* ウェイト */
		if( count++ > 20 ){
			mode = 3;
			count = 0;
		}
		break;

	case 3: /* アニメ初期化 */
		mode = 4;
		for( y=0; y<6; y++ ){
			for( x=0; x<7; x++ ){
/*				GameBall[x][y].Action( 5 );*/	/* 爆風 */
/*				GamePanel[x][y].Action( 5 );*//* 破壊 */
			}
		}
		scrpt = 731;	/* Label Start */
		break;

	case 4: /* 珠光る */
		for( n=0; n<(g_nGameWinMax+1); n++ ){
			pt = 30 + Ani[count % 2];
			x  = 7 + 2 * g_nGameWinX[n];
			y  = 4 + 2 * g_nGameWinY[n];
			KSScreenSet( pt, SCREEN2, x, y );
		}
		if( ++count == 60 ){
			mode = 5;
			count = 0;
		}
		break;

	case 5: /* 龍表示 */
/*		KSSprite.Set( 300, 0,0, TRUE, -1 );*/
		if( ++count >= 30*4 || KSKeyGet( KEY_A, 1 ) ) mode = 100;
		break;

	case 90: /* 引き分け */
/*		for(y=0; y<6; y++){
			for(x=0; x<7; x++){
				GamePanel[x][y].Action( 5 );
				GameBall[x][y].Action( 5 );
			}
		}
*/		mode = 91;
		count = 0;
		scr = 0;
		scrpt = 732;
		scrframe = 0;
		kaminari = 0;
		break;

	case 91: /* 引き分けアニメ */
		if( ++count >= 30*4 ) mode = 100;
		if( count > 30*1 && KSKeyGet( KEY_A, 1 ) ) mode = 100;
		break;

	default:
		break;
	}

	/* 終了フラグ判定 */
	if( mode == 100 ){
		mode = 0;
		return 1;
	}


	return FUNC_TRUE;
}
