//#################################
//# main.cpp
//# 
//#		(c) 2017 white, Ptech
//#
//#################################

#include "DxLib.h"	//Dxライブラリ
#include "Scene.h"	//シーンヘッダ


/** setupAppearance関数
 * 配列からAppearanceを設定する関数
 * @param mobs 設定先。
 * @param enemies 敵のひな型
 * @param matrix 設定配列。サイズは任意x4の2次元配列である必要がある
 * @param size サイズ。何体の敵が出現するか
 */
void setupAppearance(Mobs * mobs, Enemy enemies[], const int matrix[][4], int size) {
	int i = 0;
	for ( ; i < size; i++) {
		mobs->apps[i].enemy = &enemies[matrix[i][0]];
		mobs->apps[i].x = matrix[i][1];
		mobs->apps[i].y = matrix[i][2];
		mobs->apps[i].count = matrix[i][3];
	}
	mobs->max_enemies = i;
}


/** setupCharactors関数
 * 敵や自機の設定を行う
 * @param gi GameInformationのポインタ。ここへ設定を記述する
 */
void setupCharactors(GameInformation * gi) {
	//#プレイヤーの基本設定（変更されないもの）
	//この他の設定はPrepare.cppへ書いてある
	gi->player.image = LoadGraph("media\\jiki.png");	//プレイヤーの画像
	gi->player.full_health = 500;					//プレイヤーのMAX HP
	gi->player.matchless_interval = 10;				//プレイヤーの無敵時間

	//#プレイヤーの弾の基本設定（変更されないもの）
	gi->player.bullet.image = LoadGraph("media\\shell.png");	//弾の画像
	gi->player.bullet.damage = 8;//20							//弾の強さ
	gi->player.bullet.h = 11;									//弾の当たり判定高さ
	gi->player.bullet.w = 22;									//弾の当たり判定幅
	gi->player.bullet.speed = 20;//15							//弾のスピード
	gi->player.bullet.interval = 2;//10							//弾の発射間隔

	//#敵の弾の基本設定
	gi->enemy_bullet[0].image = LoadGraph("media\\shell2.png");	//弾の画像
	gi->enemy_bullet[0].damage = 12;								//弾の強さ
	gi->enemy_bullet[0].h = 6;									//当たり判定高さ
	gi->enemy_bullet[0].w = 6;									//当たり判定幅
	gi->enemy_bullet[0].speed = 12;								//弾のスピード
	gi->enemy_bullet[1].image = LoadGraph("media\\shell3.png");	//弾の画像
	gi->enemy_bullet[1].damage = 84;							//弾の強さ
	gi->enemy_bullet[1].h = 20;									//当たり判定高さ
	gi->enemy_bullet[1].w = 20;									//当たり判定幅
	gi->enemy_bullet[1].speed = 5;								//弾のスピード

	//#敵1
	gi->ens[0].health = 45, gi->ens[0].full_health = 45;	//体力
	gi->ens[0].image = LoadGraph("media\\enemy01.png");		//画像
	setMovement(gi->ens[0].movements, 0, 0, 0, 0);			//登場のモーション設定（必要なし）
	setMovement(gi->ens[0].movements, 1, -4, 0, 60);		//移動のモーション設定
	setMovement(gi->ens[0].movements, 2, 0, 2, 60);
	setMovement(gi->ens[0].movements, 3, -4, 0, 60);
	setMovement(gi->ens[0].movements, 4, 0, -2, 60);
	gi->ens[0].movement_num = 5;						//全モーション数
	gi->ens[0].w = 100;									//当たり判定の幅
	gi->ens[0].h = 90;									//当たり判定の高さ
	gi->ens[0].bullet = gi->enemy_bullet[0];			//弾の設定をコピー
	gi->ens[0].attack_interval = 100;					//攻撃の間隔
	gi->ens[0].canon_num = 1;							//砲台の数
	gi->ens[0].canons[0].x = 0;							//砲台のX位置
	gi->ens[0].canons[0].y = 0;							//砲台のY位置

													//#敵2
	gi->ens[1].health = 5, gi->ens[1].full_health = 5;
	gi->ens[1].image = LoadGraph("media\\enemy02.png");
	setMovement(gi->ens[1].movements, 0,-10, 0, 100);
	setMovement(gi->ens[1].movements, 1, 0, 10, 30);
	setMovement(gi->ens[1].movements, 2, 10, 0, 60);
	setMovement(gi->ens[1].movements, 3, 0, -10, 30);
	setMovement(gi->ens[1].movements, 4, -10, 0, 60);
	gi->ens[1].movement_num = 5;
	gi->ens[1].w = 80;
	gi->ens[1].h = 42;
	gi->ens[1].bullet = gi->enemy_bullet[0];
	gi->ens[1].attack_interval = 50;					//攻撃の間隔
	gi->ens[1].canon_num = 1;							//砲台の数
	gi->ens[1].canons[0].x = 0;							//砲台のX位置
	gi->ens[1].canons[0].y = 0;							//砲台のY位置

	//#敵3
	gi->ens[2].health = 400, gi->ens[2].full_health = 400;
	gi->ens[2].image = LoadGraph("media\\enemy03.png");
	setMovement(gi->ens[2].movements, 0, -6, 0, 200);
	setMovement(gi->ens[2].movements, 1, 0, -3, 60);
	setMovement(gi->ens[2].movements, 2, 0, 3, 120);
	setMovement(gi->ens[2].movements, 3, 0, -3, 60);
	setMovement(gi->ens[2].movements, 4, -6, 0, 30);
	setMovement(gi->ens[2].movements, 5, 6, 0, 30);
	gi->ens[2].movement_num = 6;
	gi->ens[2].w = 280;
	gi->ens[2].h = 280;
	gi->ens[2].bullet = gi->enemy_bullet[1];
	gi->ens[2].attack_interval = 20;						//攻撃の間隔
	gi->ens[2].canon_num = 1;							//砲台の数
	gi->ens[2].canons[0].x = 0;							//砲台のX位置
	gi->ens[2].canons[0].y = 0;							//砲台のY位置

	//#敵4
	gi->ens[3].health = 1900, gi->ens[3].full_health = 1900;
	gi->ens[3].image = LoadGraph("media\\enemy04.png");
	setMovement(gi->ens[3].movements, 0, 0, 0, 0);
	setMovement(gi->ens[3].movements, 1, -1, 0, 600);
	setMovement(gi->ens[3].movements, 2, -2, 0, 300);
	setMovement(gi->ens[3].movements, 3, -3, 0, 2000);
	gi->ens[3].movement_num = 4;
	gi->ens[3].w = 300;
	gi->ens[3].h = 1080;
	gi->ens[3].bullet = gi->enemy_bullet[0];
	gi->ens[3].attack_interval = 8;
	gi->ens[3].canons[0].x = -30;
	gi->ens[3].canons[0].y = -450;
	gi->ens[3].canons[1].x = -30;
	gi->ens[3].canons[1].y = -180;
	gi->ens[3].canons[2].x = -30;
	gi->ens[3].canons[2].y = 180;
	gi->ens[3].canons[3].x = -30;
	gi->ens[3].canons[3].y = 450;
	gi->ens[3].canon_num = 4;

	//#敵の出現設定
	int appear_settings[][4] = {
		{ 0,1950,100,20 },
		{ 0,1950,300,20 },
		{ 0,1950,500,20 },
		{ 0,1950,700,20 },
		{ 0,1950,100,100 },
		{ 0,1950,300,100 },
		{ 0,1950,500,100 },
		{ 0,1950,700,100 },
		{ 0,1950,100,180 },
		{ 0,1950,300,180 },//10
		{ 0,1950,500,180 },
		{ 0,1950,700,180 },
		{ 0,1950,100,260 },
		{ 0,1950,300,260 },
		{ 0,1950,500,260 },
		{ 0,1950,700,260 },
		{ 1,1950,100,350 },
		{ 1,1950,500,350 },
		{ 1,1950,300,450 },
		{ 1,1950,700,450 },//20
		{ 0,1950,100,550 },
		{ 0,1950,300,550 },
		{ 0,1950,500,550 },
		{ 0,1950,700,550 },
		{ 2,1950,540,800 },
		{ 2,1950,540,1200 },
		{ 1,1950,300,1400 },
		{ 1,1950,700,1400 },
		{ 2,1950,540,1600 },
		{ 2,1950,540,2000 },//30
		{ 3,2200,540,2500 },
	};

	setupAppearance(&gi->mobs, gi->ens, appear_settings, 31);
}


/** WinMain関数
 * ゲームメイン関数
 */
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {

	//*** 起動前の初期化 ***
	ChangeWindowMode(true);			//ウィンドウモードで起動
	SetWindowSize(1920, 1080);		//1920x1080に設定
	SetGraphMode(1920, 1080, 32);	//1920x1080の32bitに設定
	SetWindowText("ShootingGame");	//ウィンドウテキストを変更
	SetWaitVSyncFlag(true);			//垂直同期を使用（フレームレートによるスピード変動対策未実装）
	SetAlwaysRunFlag(true);			//裏画面に行っても動作継続


	//*** 初期化 ***
	if (DxLib_Init() == -1) return -1;	//DxLibの初期化
	SetMouseDispFlag(false);


	//*** ゲーム本体の初期化 ***
	int scene_no = SCENE_TITLE;		//シーン制御用の変数（Scene.hを参照）

	GameInformation gi;				//シーンをまたいで情報共有するための変数

	gi.screen = MakeScreen(1920, 1080, false);

	SetDrawScreen(gi.screen);	//描写スクリーンを背景へ

	//#リソースの読み込み
	gi.rs.background = LoadGraph("media\\background.jpg");		//背景画像
	gi.rs.explosion_image = LoadGraph("media\\explosion.png");	//爆発画像
	gi.rs.explosion_sound = LoadSoundMem("media\\bomb.mp3");	//爆発音声
	gi.rs.shot_sound = LoadSoundMem("media\\shot.mp3");			//発射音声
	gi.rs.bgm = LoadSoundMem("media\\bgm.mp3");					//BGM
	ChangeVolumeSoundMem(90, gi.rs.bgm);						//BGMの音量変更
	gi.rs.damage_sound = LoadSoundMem("media\\damage2.wav");		//ダメージ音声
	gi.rs.damage_sound2 = LoadSoundMem("media\\damage.wav");	//ダメージ音声（敵）
	gi.rs.UI = LoadGraph("media\\UI.png");						//UI画像
	gi.rs.gameover = LoadGraph("media\\gameover.png");			//ゲームオーバー文字
	gi.rs.gameclear = LoadGraph("media\\gameclear.png");		//ゲームクリアー文字
	LoadDivGraph("media\\numeric.png", 10, 10, 1, 80, 140, gi.rs.numeric);	//数字フォント文字
	gi.rs.danger_image = LoadGraph("media\\danger.png");
	gi.rs.danger_sound1 = LoadSoundMem("media\\danger1.wav");
	gi.rs.danger_sound2 = LoadSoundMem("media\\danger2.wav");
	gi.rs.gameclear_sound = LoadSoundMem("media\\gameclear.mp3");
	gi.rs.gameover_sound = LoadSoundMem("media\\gameover.mp3");
	gi.rs.decision = LoadSoundMem("media\\decision14.wav");


	//#キャラクターの基本設定
	setupCharactors(&gi);
	

	//*** メインループ ***
	//scene_noがSHUTDOWNならループを抜ける
	//それぞれのsceneの戻り値を取得し、それに応じてシーン制御する。
	while (ProcessMessage() == 0 && scene_no != SCENE_SHUTDONW) {
		switch (scene_no) {
		case SCENE_TITLE:			//タイトル
			scene_no = TitleScene(&gi);
			break;
		case SCENE_PREPARE_GAME:	//ゲーム前
			scene_no = PrepareScene(&gi);
			break;
		case SCENE_GAME:			//ゲーム中
			scene_no = GameScene(&gi);
			break;
		case SCENE_RESULT:			//ゲーム結果
			scene_no = GameResultScene(&gi);
			break;
		default:					//バグか何かでいずれでもない時
			scene_no = SCENE_SHUTDONW;	//無限ループを避けるため終了
			break;
		}
		
	}

	//*** 終了処理 ***
	DxLib_End();

	return 0; 
}