/* =====================================================
   基本設定
===================================================== */
// 変数宣言
let mode; // start, play, end, clear
let maxX; // 画面幅
let maxY; // 画面高さ
let marimo; // マリモの変数
const ballCount = 10; // ボールの数
const ballSpeed = 5; // ボールの速度
let balls = []; // ボールの配列
let life = 3; // ライフ
let loopId; // ループID
let timeLimit = 10;   // 制限時間（秒）
let startTime;        // タイマー開始時刻

// 効果音の定義
const soundHit = new Audio('sound/puyo.mp3');
const soundGameOver = new Audio('sound/gaku.mp3');
const soundClear = new Audio('sound/clear.mp3');

/* =====================================================
   DOM取得
===================================================== */
// 画面切替用
const startScreen = document.querySelector("#start");
const playScreen = document.querySelector("#play");
const endScreen = document.querySelector("#end");
const clearScreen = document.querySelector("#clear");

// ボールとマリモ配置用
const marimoDiv = document.querySelector("#marimo");
const ballDiv = document.querySelector("#ball");

// ライフなど情報表示用
const lifeDiv = document.querySelector("#life");
const timeDiv = document.querySelector("#time");

/* =====================================================
   関数 / 生成処理
===================================================== */
// マリモを作成する関数
function makeMarimo() {
  // マリモを生成
  marimo = document.createElement("img");
  marimo.src = "img/marimo.png";
  marimo.style.position = "absolute";
  marimo.style.transform = "translate(-50%,-50%)";
  marimo.style.width = "70px";
  marimo.style.height = "70px";

  // マリモを画面に追加
  marimoDiv.appendChild(marimo);

  // マリモの座標
  marimo.posX = maxX * 0.5; // 中央に配置
  marimo.posY = maxY * 0.8; // 画面下部に配置
  
  // マリモの移動速度
  marimo.vX = 0;
  marimo.vY = 0;
  
}

// ボールを作成する関数
function makeBalls() {

  // ボールをfor文で生成
  for(let i = 0; i < ballCount; i++) {
    // ボール[i]を生成
    balls[i] = document.createElement("img");
    balls[i].src = "img/ball.png";
    balls[i].style.position = "absolute";
    balls[i].style.transform = "translate(-50%,-50%)";
    balls[i].style.width = "40px";
    balls[i].style.height = "40px";

    //ボール[i]を画面に追加
    ballDiv.appendChild(balls[i]);

    // ボール[i]の速度をランダムに設定（-5 〜 +5）
    let s = ballSpeed;
    balls[i].vX = Math.random() * s * 2 - s;
    balls[i].vY = Math.random() * s * 2 - s;

    // ボール[i]の座標をランダムに設定
    let r = balls[i].offsetWidth / 2; // 半径
    balls[i].posX = Math.random() * (maxX - r * 2 - s * 2) + r + s;
    balls[i].posY = Math.random() * (maxY - r * 2 - s * 2) + r + s;

  }

}


/* =====================================================
   関数 / 移動処理
===================================================== */
// マリモを移動させる関数
function moveMarimo() {

  // 座標を移動させる
  marimo.posX = marimo.posX + marimo.vX;
  marimo.posY = marimo.posY + marimo.vY;

  // 画面の左右の端で止まる
  if (marimo.posX > maxX - marimo.offsetWidth / 2) {
    marimo.posX = maxX - marimo.offsetWidth / 2;
  }
  if (marimo.posX < marimo.offsetWidth / 2) {
    marimo.posX = marimo.offsetWidth / 2;
  }

  // 画面の上下の端で止まる
  if (marimo.posY > maxY - marimo.offsetHeight / 2) {
    marimo.posY = maxY - marimo.offsetHeight / 2;
  }
  if (marimo.posY < marimo.offsetHeight / 2) {
    marimo.posY = marimo.offsetHeight / 2;
  }

  // マリモの位置を設定
  marimo.style.left = marimo.posX + "px";
  marimo.style.top = marimo.posY + "px";
}

// ボールを動かす関数
function moveBalls() {
  // ボールをfor文で移動
  for(let i = 0; i < ballCount; i++) {
    // x座標を vX 増やす
    balls[i].posX = balls[i].posX + balls[i].vX;
    balls[i].posY = balls[i].posY + balls[i].vY;

    // 画面の左右の端で跳ね返る
    if (balls[i].posX > maxX - balls[i].offsetWidth / 2) {
      balls[i].posX = maxX - balls[i].offsetWidth / 2;
      balls[i].vX = -balls[i].vX;
    }
    if (balls[i].posX < balls[i].offsetWidth / 2) {
      balls[i].posX = balls[i].offsetWidth / 2;
      balls[i].vX = -balls[i].vX;
    }

    // 画面の上下の端で跳ね返る
    if (balls[i].posY > maxY - balls[i].offsetHeight / 2) {
      balls[i].posY = maxY - balls[i].offsetHeight / 2;
      balls[i].vY = -balls[i].vY;
    }
    if (balls[i].posY < balls[i].offsetHeight / 2) {
      balls[i].posY = balls[i].offsetHeight / 2;
      balls[i].vY = -balls[i].vY;
    }

    // 画面に反映
    balls[i].style.left = balls[i].posX + "px";
    balls[i].style.top = balls[i].posY + "px";
  }
}

/* =====================================================
   関数 / ゲームロジック
===================================================== */
// 当たり判定を行う関数
function checkHit() {

  for(let i = 0; i < ballCount; i++) {
    
    const mr = marimo.offsetWidth / 2;  
    const br = balls[i].offsetWidth / 2;
    const hr = mr + br;

    const dx = balls[i].posX - marimo.posX;
    const dy = balls[i].posY - marimo.posY;

    const d = Math.sqrt(dx ** 2 + dy ** 2);

    if(d < hr){
      onHit(i);
    }
  }
}

// ★当たった時の処理を行う関数（ライフを減らす）  / onHit() {}
function onHit(i) {

  console.log("ボール" +i+ "があたった");

  life -= 1;
  lifeDiv.textContent = "Life: " + life;

  if (life <= 0) {
    // 効果音を再生（ゲームオーバー）
    soundGameOver.currentTime = 0;
    soundGameOver.play();
    endMode();
  }else{
    // 効果音を再生（ヒット）
    soundHit.currentTime = 0;
    soundHit.play();

    // 点滅させる（一回だけ）
    marimo.style.opacity = 0.2;

    // 0.2秒後に元に戻す
    setTimeout(function() {
        marimo.style.opacity = 1;
    }, 200);

    // ボール[i]の座標をランダムに設定
    let s = ballSpeed;
    let r = balls[i].offsetWidth / 2; // 半径
    balls[i].posX = Math.random() * (maxX - r * 2 - s * 2) + r + s;
    balls[i].posY = Math.random() * (maxY - r * 2 - s * 2) + r + s;
  }
}

/* =====================================================
   関数 / 画面切替
===================================================== */
// 画面表示を切り替える関数 / showScreen() {}
function showScreen(screenName) {

  // すべての画面からactiveクラスを除去
  startScreen.classList.remove("active");
  playScreen.classList.remove("active");
  endScreen.classList.remove("active");
  clearScreen.classList.remove("active");

  // 指定された画面だけactiveクラスを追加
  if (screenName === "start") {
    startScreen.classList.add("active");
    maxX = startScreen.clientWidth;
    maxY = startScreen.clientHeight;

  } else if (screenName === "play") {
    playScreen.classList.add("active");
    maxX = playScreen.clientWidth;
    maxY = playScreen.clientHeight;

  } else if (screenName === "end") {
    endScreen.classList.add("active");
    maxX = endScreen.clientWidth;
    maxY = endScreen.clientHeight;

  } else if (screenName === "clear") {
    clearScreen.classList.add("active");
    maxX = clearScreen.clientWidth;
    maxY = clearScreen.clientHeight;

  }

  console.log(maxX, maxY);
  
  // モードを更新
  mode = screenName;

}

/* =====================================================
   関数 / ループ処理
===================================================== */
// ループ関数 / loop() {}
function loop() {
  moveMarimo();
  moveBalls();
  checkHit();
  gameTimer();
}


/* =====================================================
   関数 / ゲーム進行
===================================================== */
function startMode() {
  // 画面表示 / showScreen();
  showScreen("start");
}

function playMode() {
  // 変数をリセット
  marimo = null; //nullが望ましいがここでは空文字で代用
  balls = [];
  life = 3;

  // 表示をリセット
  ballDiv.innerHTML   = "";
  marimoDiv.innerHTML = "";
  lifeDiv.textContent = "Life: " + life;
  timeDiv.textContent = "Time: " + timeLimit;

  // タイマー開始時刻を設定
  startTime = Date.now();

  // 画面表示
  showScreen("play");

  // マリモを生成
  makeMarimo();

  // ボールを生成
  makeBalls();

  // ゲームループ開始
  loopId = setInterval(loop, 20);
}

function endMode() {
  // ゲームループの停止
  clearInterval(loopId);
  console.log("ゲームオーバー");

  // 画面表示 / showScreen();
  showScreen("end");
}

function clearMode() {
  // ゲームループの停止
  clearInterval(loopId); // ゲームループを停止
  console.log("クリア");

  // 画面表示 / showScreen();
  showScreen("clear");

}


/* =====================================================
   初期実行
===================================================== */
// ★ゲーム起動 / startMode();
startMode();
//playMode();
//endMode();
//clearMode();

/* =====================================================
   キーボード操作
===================================================== */
// キーボードのキーを押したときの処理
function onKeyDown(e) {

  // ブラウザのデフォルト動作を止める
  e.preventDefault();

    // プレイ画面
  if (mode === "play") {
    // 左右上下移動
    if (e.code === "ArrowLeft") {
      marimo.vX = -5;
      marimo.src = 'img/marimo_L.png';
    } else if (e.code === "ArrowRight") {
      marimo.vX = 5;
      marimo.src = 'img/marimo_R.png';
    } else if (e.code === "ArrowUp") {
      marimo.vY = -5;
      marimo.src = 'img/marimo_U.png';
    } else if (e.code === "ArrowDown") {
      marimo.vY = 5;
      marimo.src = 'img/marimo.png';
    }
  }
}

// キーボードのキーを離したときの処理
function onKeyUp(e) {

  // ブラウザのデフォルト動作を止める
  e.preventDefault();

  console.log(mode + ":" + e.code);

  // プレイ画面
  if (mode === "play") {
    // 左右上下移動
    if (e.code === "ArrowLeft") {
      marimo.vX = 0;
      marimo.src = 'img/marimo.png';
    } else if (e.code === "ArrowRight") {
      marimo.vX = 0;
      marimo.src = 'img/marimo.png';
    } else if (e.code === "ArrowUp") {
      marimo.vY = 0;
      marimo.src = 'img/marimo.png';
    } else if (e.code === "ArrowDown") {
      marimo.vY = 0;
      marimo.src = 'img/marimo.png';
    }
  }

  // クリア画面 → スタート画面
  if (mode === "start" && e.code === "Space") {
    playMode();
  }
  //ゲームオーバー画面 → スタート画面
  if (mode === "end" && e.code === "Space") {
    startMode();
  }
  // クリア画面 → スタート画面
  if (mode === "clear" && e.code === "Space") {
    startMode(); 
  }

}

// keydownイベント
document.addEventListener('keydown', onKeyDown);
// keyupイベント
document.addEventListener('keyup', onKeyUp);
