#include "block_breaker.h"

// グローバル変数
char block[ROW][COL]; // ブロック（マス目）を管理する配列
char broke[ROW][COL]; // ブロックを壊した時の演出用の配列
int blocks; // ブロックの数（残りの数）

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    // ＤＸライブラリを使用する準備
    SetWindowText("対戦型ワンキーアクションゲーム"); // ウィンドウのタイトル
    SetGraphMode(WIDTH, HEIGHT, 32); // ウィンドウの大きさとカラービット数の指定
    ChangeWindowMode(TRUE); // ウィンドウモードで起動
    if (DxLib_Init() == -1) return -1; // ライブラリ初期化 エラーが起きたら終了
    SetBackgroundColor(0, 0, 0); // 背景色の指定
    SetDrawScreen(DX_SCREEN_BACK); // 描画面を裏画面にする

    int scene = TITLE; // 画面遷移を行うための変数
    int timer = 0; // 経過時間を数える変数

    initBlock(); // ブロックを初期化する

    Fighter fighter[FIGHTER_MAX]; // 機体のオブジェクト
    fighter[0].init(BSIZE * 1.5, BSIZE * 1.5, 8, GetColor(255, 0, 0)); // 赤い機体
    fighter[1].init(BSIZE * (COL - 1.5), BSIZE * (ROW - 1.5), 8, GetColor(0, 64, 255)); // 青い機体

    while (ProcessMessage() == 0) { // メインループ
        timer++;
        ClearDrawScreen(); // 画面をクリアする
        drawBlock(); // ブロックを描く

        switch (scene) {
        case TITLE: // ---------- タイトル画面の処理 ----------
            drawText(WIDTH / 2, HEIGHT * 0.33, "BLOCK BREAKER", 0, 100, GetColor(32, 192, 96));
            if (timer % 30 < 15) drawText(WIDTH / 2, HEIGHT * 0.66, "Press [R]or[B] to Start.", 0, 50, GetColor(224, 192, 0));
            if (CheckHitKey(KEY_INPUT_R) || CheckHitKey(KEY_INPUT_B)) {
                scene = PLAY; // ゲームプレイに移行
            }
            break;

        case PLAY: // ---------- ゲームプレイ画面の処理 ----------
            drawText(WIDTH / 2, HEIGHT / 2, "[E]勝敗決定画面", 0, 50, GetColor(255, 0, 0));
            if (CheckHitKey(KEY_INPUT_E)) { // ※仮の処理
                scene = OVER; // ゲームオーバーに移行
                timer = 0; // 一定時間経過後にタイトルに戻すために0を代入
            }
            break;

        case OVER: // ---------- 勝敗の表示 ----------
            drawText(WIDTH / 2, HEIGHT / 2, "D R A W.", 0, 100, GetColor(192, 128, 192));
            if (timer > FRAME_RATE * 7) scene = TITLE; // 一定時間後にタイトルに戻る
            break;
        }

        for (int i = 0; i < FIGHTER_MAX; i++) { // 機体を表示する
            fighter[i].draw();
        }

        ScreenFlip(); // 裏画面の内容を表画面に反映させる
        WaitTimer(FRAME_TIME); // 一定時間待つ
        if (CheckHitKey(KEY_INPUT_ESCAPE) == 1) break; // ESCキーが押されたら終了
    }

    DxLib_End(); // ＤＸライブラリ使用の終了処理
    return 0; // ソフトの終了
}

// 自作関数
void initBlock() { // ブロックを初期状態にする関数
    for (int y = 0; y < ROW; y++) { // いったん全体を壊せない壁にする
        for (int x = 0; x < COL; x++) {
            block[y][x] = WALL;
            broke[y][x] = 0; // 演出用の配列をリセットしておく
        }
    }
    for (int y = 1; y < ROW - 1; y++) { // 内側を何もない状態にする
        for (int x = 1; x < COL - 1; x++) block[y][x] = FLOOR;
    }
    for (int y = 2; y < ROW - 2; y++) { // 2マス内側をブロックにする
        for (int x = 2; x < COL - 2; x++) block[y][x] = BLOCK;
    }
    blocks = (COL - 4) * (ROW - 4); // ブロックの数を計算
}

void drawBlock() { // ブロックを描く関数
    for (int y = 0; y < ROW; y++) {
        for (int x = 0; x < COL; x++) {
            int cx = x * BSIZE, cy = y * BSIZE;
            DrawBox(cx, cy, cx + BSIZE - 1, cy + BSIZE - 1, COLOR[block[y][x]], TRUE);
        }
    }
}

void drawText(int x, int y, const char* txt, int val, int siz, int col) { // 文字列の表示関数
    SetFontSize(BSIZE * siz / 100); // フォントの大きさを指定
    int strWidth = GetDrawStringWidth(txt, strlen(txt)); // 文字列の幅
    x = x - strWidth / 2; // センタリングの座標計算
    y = y - BSIZE * siz / 100 / 2;
    DrawFormatString(x + 1, y + 2, GetColor(0, 0, 0), txt, val);
    DrawFormatString(x, y, col, txt, val);
}

// クラスのメンバ関数
void Fighter::init(int x, int y, int lr, int col) { // 初期化
    this->x = x;
    this->y = y;
    this->lr = lr;
    this->color = col;
    this->angle = 0;
    this->speed = 0;
    this->score = 0;
}

int Fighter::getCol() { return color; } // 色を返す
int Fighter::getSc() { return score; } // スコアを返す

void Fighter::draw() { // 機体を表示
    int px[3], py[3];
    for (int i = 0; i < 3; i++) {
        px[i] = x + (int)(FIGHTER_SIZE * std::cos(M_PI * (angle + 120 * i) / 180));
        py[i] = y + (int)(FIGHTER_SIZE * std::sin(M_PI * (angle + 120 * i) / 180));
    }
    for (int i = 0; i < 3; i++) {
        DrawLine(px[i], py[i], px[(i + 1) % 3], py[(i + 1) % 3], color, FIGHTER_WIDTH);
    }
    DrawLine(x, y, px[0], py[0], 0xffffff, FIGHTER_WIDTH); // 進む向き
}