/* =====================================================
   基本設定
===================================================== */

// ゲーム設定
const MARIMO_SIZE  = 70;           // マリモのサイズ
const BALL_SIZE    = 40;           // ボールのサイズ
const BALL_COUNT   = 10;           // ボールの数
const BALL_MARGIN  = 10;           // ボール配置の余裕
const MARIMO_SPEED = 5;            // マリモの移動速度
const BALL_SPEED   = 5;            // ボールの移動速度
const TIME_LIMIT   = 10;           // 制限時間（秒）
const LIFE_MAX     = 3;            // ライフ最大値

// 変数宣言
let mode; // start, play, end, clear
let maxX; // 画面幅
let maxY; // 画面高さ
let marimo; // マリモの変数
let balls = []; // ボールの配列
let life; // ライフ
let loopId; // ループID
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 = MARIMO_SIZE + "px";
  marimo.style.height = MARIMO_SIZE + "px";

  // マリモを画面に追加
  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 < BALL_COUNT; 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 = BALL_SIZE + "px";
    balls[i].style.height = BALL_SIZE + "px";

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

    // ボール[i]の速度をランダムに設定
    balls[i].vX = Math.random() * BALL_SPEED * 2 - BALL_SPEED;
    balls[i].vY = Math.random() * BALL_SPEED * 2 - BALL_SPEED;

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

  }

}


/* =====================================================
   関数 / 移動処理
===================================================== */
// マリモを移動させる関数
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 < BALL_COUNT; 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;

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

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


// タイマーを更新する関数
function gameTimer() {
  const now = Date.now();
  const el = Math.floor((now - startTime) / 1000);
  const rem = TIME_LIMIT - el;

  // 時間切れでクリア
  if (rem <= 0) {
    // 効果音を再生（クリア）
    soundClear.currentTime = 0;
    soundClear.play();
    clearMode();
  }

  timeDiv.textContent = "Time: " + rem;
}


/* =====================================================
   関数 / 画面切替
===================================================== */
// 画面表示を切り替える関数 / 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");

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

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

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

  }
  
  // モードを更新
  mode = screenName;

}

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


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

function playMode() {
  // 変数をリセット
  marimo = null;
  balls = [];
  life = LIFE_MAX;

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

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

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

  // 画面サイズの取得
  maxX = playScreen.clientWidth;
  maxY = playScreen.clientHeight;

  // マリモを生成
  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 (e.code === "ArrowLeft") {
    marimo.vX = -MARIMO_SPEED;
    marimo.src = 'img/marimo_L.png';
  } else if (e.code === "ArrowRight") {
    marimo.vX = MARIMO_SPEED;
    marimo.src = 'img/marimo_R.png';
  } else if (e.code === "ArrowUp") {
    marimo.vY = -MARIMO_SPEED;
    marimo.src = 'img/marimo_U.png';
  } else if (e.code === "ArrowDown") {
    marimo.vY = MARIMO_SPEED;
    marimo.src = 'img/marimo.png';
  }
}

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

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

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

  // 左右上下移動
  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);
