#include "FKUT/FKUT.h"


// プログラムが始まるmain関数
int main(int argc, char *argv[])
{
	// ウィンドウ準備しまーす
	fkut_SimpleWindow	window;			// すごい変数「3DCGが描けるウィンドウになる変数」

	window.setSize(800, 600);			// ウィンドウの大きさはお好みで
	window.setBGColor(0.3, 0.6, 0.8);	// 背景色はR, G, Bの色成分を0.0〜1.0でブレンドして作るよ
	window.showGuide();					// グリッドと軸の表示
	window.setTrackBallMode(true);		// マウスでぐりぐりモード
	window.open();						// ウィンドウ自体を表示するよ
	// ウィンドウ準備ここまで

	// ここから表示するものを用意している部分
	fkut_SphereModel	body;			// 操作する球

	body.create(4, 10.0);
	body.setMaterial(Yellow);
	body.glMoveTo(0.0, 0.0, 0.0);
	window.entry(body);

	fkut_BlockModel		floor;			// 床をあらわすブロックモデル

	floor.create(1000.0, 1.0, 1000.0);
	floor.glMoveTo(0.0, -0.5, 0.0);		// ちょいと低めにしておく
	floor.setMaterial(Brown);
	window.entry(floor);
	// 表示用意部分ここまで

	/////////////////////////////////////////////////////////////
	// ぶつかれるブロックを用意する
	fkut_BlockModel		hitBlk[10];
	// 当たり判定で使う変数
	fk_Vector			back;
	bool				stand = false;

	// 配列と繰り返しを利用して、まとめて設定
	for(int i = 0; i < 10; i++) {
		hitBlk[i].create(30.0, 60.0, 30.0);
		hitBlk[i].glMoveTo(-100.0 + i*60.0, 0.0, -50.0);
		hitBlk[i].setMaterial(Green);
		window.entry(hitBlk[i]);
	}
	/////////////////////////////////////////////////////////////

	///////////////////////////////////////////////////////////////////////////
	// 状態管理用の変数
	fk_Vector	vSpd, vPos;	// 速度ベクトル、位置取得用変数
	int			iState = 0;	// 0: ふつう, 1: 上昇中, 2: 下降中
	///////////////////////////////////////////////////////////////////////////

	// カメラを自前で定義するよ
	fk_Model	camera;

	window.setCameraModel(camera);
	camera.glMoveTo(0.0, 100.0, 400.0);
	camera.glFocus(0.0, 0.0, 0.0);
	camera.setParent(&body);
	// カメラ定義ここまで

	//AUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIO//
	// サウンド関係
	fk_AudioStream		bgm;
	fk_AudioWavBuffer	se0, se1, se3D;
	bool				bgm_play, se0_play, se1_play, se3D_play;

	if(!bgm.open("BGM\\stage_01.ogg")) {
		fl_alert("bgm open failed.");	// 読み込みに失敗したらエラーメッセージを出す
	}
	bgm.setLoopMode(true);

	if(!se0.open("drum\\BDTIGHT2.wav")) {
		fl_alert("se0 open failed.");	// 読み込みに失敗したらエラーメッセージを出す
	}
	if(!se1.open("drum\\SDCRKRM.wav")) {
		fl_alert("se1 open failed.");	// 読み込みに失敗したらエラーメッセージを出す
	}
	if(!se3D.open("SE\\iPhone.wav")) {
		fl_alert("se3D open failed.");	// 読み込みに失敗したらエラーメッセージを出す
	}
	se3D.setLoopMode(true);
	se3D.setPosition(fk_Vector(0.0, 0.0, 0.0));
	se3D.setReferenceDist(100.0);
	se3D.setListenerModel(body);

	bgm_play = false;
	se0_play = false;
	se1_play = false;
	se3D_play = false;
	// サウンド関係ここまで
	//AUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIO//

	//=========================================================================
	// ぐるぐる回るよー
	while(window.update() == true) {
		// キー操作で前進後退＆左右旋回(速度ベースに変更)
		vSpd.x = vSpd.z =  0.0;
		if(window.getSpecialKeyStatus(FK_UP) == FKUT_SW_PRESS) {
			vSpd.z = -1.0;
		}
		if(window.getSpecialKeyStatus(FK_DOWN) == FKUT_SW_PRESS) {
			vSpd.z =  1.0;
		}
		if(window.getSpecialKeyStatus(FK_LEFT) == FKUT_SW_PRESS) {
			vSpd.x = -1.0;
		}
		if(window.getSpecialKeyStatus(FK_RIGHT) == FKUT_SW_PRESS) {
			vSpd.x =  1.0;
		}
		// キー操作処理ここまで

		/////////////////////////////////////////////////////////////
		// 今時？風ジャンプ
		if(iState == 0) {			// 通常モード
			// zキーを押された瞬間、上昇モードへ移行
			if(window.getKeyStatus('z') == FKUT_SW_DOWN) {
				iState = 1;
				vSpd.y = 10.0;		// ジャンプの初速度を与える
			} else {
				vSpd.y = -0.5;
			}
		} else if(iState == 1) {	// 上昇モード
			// 速度を変化させる(擬似的な重力加速度を与える)
			if(vSpd.y > 4.0) {
				// 上向きの速度があるうちはきつめに減らす
				vSpd.y -= 1.0;
			} else if(vSpd.y > 0.0) {
				// 速度が少なくなったら減らす量を減らす
				vSpd.y -= 0.5;
			} else {
				// 速度が下向きに反転したら下降モードへ移行
				iState = 2;
			}
		} else if(iState == 2) {	// 下降モード
			// 速度を変化させる(擬似的な重力加速度を与える)
			if(vSpd.y > -4.0) {
				// 下向きの速度が少ないうちはゆるめに加速
				vSpd.y -= 0.5;
			} else {
				// 速度がきつくなってきたらきつめに加速
				vSpd.y -= 1.0;
			}
		}
		// 今時風ジャンプここまで
		/////////////////////////////////////////////////////////////

		/////////////////////////////////////////////////////////////
		// ブロックとの当たり判定
		stand = false;
		for(int i = 0; i < 10; i++) {
			// 当たっていたらtrueが返る
			// (移動してから判定ではなく、位置と速度を渡す判定に変更)
			if(hitBlk[i].checkToMovingSphere(body, vSpd, back) == true) {
				// ブロックから見ためりこみ具合がbackに入るので、
				// プレイヤー側を動かして調整する場合は逆方向になる
				// 予定速度(vSpd)に対して減算
				vSpd -= back;
				
				// 乗っかり判定処理
				if(-back.y > 0.0) {	// 乗っかっためり込みを感知したら
					vSpd.y = 0.0;	// 速度リセット
					iState = 0;		// 通常モードへ移行
					stand = true;
				}
			}
		}

		// キー操作、重力、衝突によって変化した速度によってモデルを移動
		body.glTranslate(vSpd);

		// 通常時に下向きの力を受けなかったら下降モードへ移行
		if(iState == 0 && stand == false) {
			iState = 2;
		}
		
		// 床との当たり判定処理(例外的な当たり判定なのでそのまま)
		vPos = body.getPosition();	// 現在位置を取ってくる
		if(vPos.y < 0.0) {			// 床にめり込んでいたら
			vSpd.y = 0.0;			// 速度リセット
			vPos.y = 0.0;			// Y座標を0.0に固定
			body.glMoveTo(vPos);	// 固定した座標に強制転送
			// 通常モードへ移行
			iState = 0;
		}
		/////////////////////////////////////////////////////////////

		//AUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIO//
		// サウンド関係
		// se0のキー操作(a)による再生
		if(window.getKeyStatus('a') == FKUT_SW_DOWN) {
			se0_play = true;
			se0.seek(0.0);
		}
		if(se0_play == true) {
			se0_play = se0.play();
		}
		// se1のキー操作(s)による再生
		if(window.getKeyStatus('s') == FKUT_SW_DOWN) {
			se1_play = true;
			se1.seek(0.0);
		}
		if(se1_play == true) {
			se1_play = se1.play();
		}

		// BGMはスペースで再生と一時停止を切り替え
		if(window.getKeyStatus(' ') == FKUT_SW_DOWN) {
			if(bgm_play == true) {
				bgm_play = false;
				bgm.pause();
			} else {
				bgm_play = true;
			}
		}
		if(bgm_play == true) {
			bgm_play = bgm.play();
		}

		// こいつは条件によらず鳴らしっぱなし
		se3D.play();
		// サウンド関係ここまで
		//AUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIOAUDIO//
	}
	//=========================================================================
	// おつかれさまでした

	return 0;
}
