// アイコンを取得
const shootIcon = _.iconAsset("Shoot");
const reloadingIcon = _.iconAsset("Reloading");
const aimIcon = _.iconAsset("Aim");
const reloadIcon = _.iconAsset("Reload");

// 銃を持った時に、右腕～右手に適用する回転量
const upperArmRot = new Quaternion().setFromEulerAngles(new Vector3(-35, 0, -80));
const lowerArmRot = new Quaternion().setFromEulerAngles(new Vector3(-90, -90, -10));
const handRot = new Quaternion().setFromEulerAngles(new Vector3(-90, -90, 0));

// アイテムを掴んでる間はtrueとなる値
let isGrabbing = true;

// エイムボタンを押してズームアップしている間はtrueとなる値
let isAimed = false;

// 銃が撃てる間はtrueとなる値
let canShoot = true;

// プレイヤーがVRデバイスを使用して入室しているときにtrueとなる値
let isVr = _.isVr;

// 銃のItemIdを格納する変数
let sourceItemId = _.sourceItemId;

// カメラワークを設定する
setCamerawork(isAimed);

// ボタンを表示する
_.showButton(1, aimIcon);
_.showButton(2, reloadIcon);

_.onReceive((messageType, arg, sender) => {
  switch(messageType){

    // "Released"というメッセージを受信した時
    case "Released":
      // 全てのカメラワークをリセット
      resetCamerawork();

      // ボタンを非表示にする
      hideButtons();
      
      isGrabbing = false;
      break;

    // "CanShoot"というメッセージを受信した時
    case "CanShoot":
      // メッセージとともに送られてくるargの真偽値に応じてアイコンを変化させる
      // argがtrueの時は射撃可能なのでshootIconを、argがfalseの時は射撃不可能なためreloadingIconをボタンに設定する
      let icon = arg ? shootIcon : reloadingIcon;
      _.showButton(0, icon);

      canShoot = arg;
      break;

    // どのcaseにも当てはまらない時
    default:
      break;

  }
});

// 射撃ボタン
_.onButton(0, (isDown) => {
  if (!isDown || !canShoot) return;

  // アイテムに"Shoot"というメッセージを送信する
  _.sendTo(sourceItemId, "Shoot", null);

});

// エイムボタン
_.onButton(1, (isDown) => {
  if (isDown) { 

    // エイム状態を更新し、それに応じたカメラワークを設定する
    isAimed = !isAimed;
    setCamerawork(isAimed);

    // アイテムに"ShowRay"というメッセージを送信し、エイム中かどうかを伝達する
    _.sendTo(sourceItemId, "ShowRay", isAimed);

  }
});

// リロードボタン
_.onButton(2, (isDown) => {
  if (isDown) { 

    // アイテムに"Reload"というメッセージを送信する
    _.sendTo(sourceItemId, "Reload", null);

  }
});

// 毎フレーム実行する処理
_.onFrame((deltaTime) => {
  // プレイヤーのアバターの姿勢を更新する
  setUpFk();
});

// プレイヤーのアバターの姿勢を更新する
function setUpFk() {
  // アイテムを掴んでいないか、VRデバイスを使用している時は、処理を終了する
  if (!isGrabbing || isVr) return;
  
  // 三人称カメラの回転値を取得する
  let cameraRot = _.cameraHandle.getRotation();

  if (cameraRot !== null) {
    // RightUpperArm, RightLowerArm, RightHandに、三人称カメラの回転を適用する
    // Scriptの最初に設定した回転値をmutiplyすることで、腕の回転が自然になるように調整する
    _.setHumanoidBoneRotationOnFrame(HumanoidBone.RightUpperArm, cameraRot.clone().multiply(upperArmRot));
    _.setHumanoidBoneRotationOnFrame(HumanoidBone.RightLowerArm, cameraRot.clone().multiply(lowerArmRot));
    _.setHumanoidBoneRotationOnFrame(HumanoidBone.RightHand, cameraRot.clone().multiply(handRot));
  }
}

// エイム中かどうかでカメラワークを変更する
function setCamerawork(isAimed) { 

  // 三人称視点のとき、アバターが正面方向に向くよう姿勢を固定する
  _.cameraHandle.setThirdPersonAvatarForwardLock(true);

  // エイム:ON
  if (isAimed) { 
    _.cameraHandle.setThirdPersonDistance(1.7); // アバターとの距離
    _.cameraHandle.setFieldOfView(30); // 視野角
    _.cameraHandle.setThirdPersonAvatarScreenPosition(new Vector2(0.3, 0.4)); // アバターの表示位置

  // エイム:OFF
  } else {
    _.cameraHandle.setThirdPersonDistance(2.0); // アバターとの距離
    _.cameraHandle.setFieldOfView(50); // 視野角
    _.cameraHandle.setThirdPersonAvatarScreenPosition(new Vector2(0.35, 0.4)); // アバターの表示位置
  }
}

// 全てのカメラワークをリセット
function resetCamerawork(){
  _.cameraHandle.setFieldOfView(null);
  _.cameraHandle.setThirdPersonDistance(null);
  _.cameraHandle.setThirdPersonAvatarForwardLock(null);
  _.cameraHandle.setThirdPersonAvatarScreenPosition(null);
}

// ボタンを非表示にする
function hideButtons(){
  _.hideButton(0);
  _.hideButton(1); 
  _.hideButton(2); 
}