/*:
 * @target MZ
 * @plugindesc ボイスのオートスクロール
 * @author
 */
(function () {
	// 変数117 → 状態
	// 変数118 → duration
	// スイッチ142 → オートON

	//ボイス再生するとき、'loading'
	//ボイスの再生時間が入ったら 'playding'
	//ボイスの再生時間終わったら'next'
	//遷移したら'end'

	//NovelGameUI.jsの競合対策

	Window_Message.prototype.update = function () {
		if (!$gameMessage.isHideUiMode()) {
			this.checkToNotClose();
			this.updateControlButtons();
			Window_Base.prototype.update.call(this);
			this.synchronizeNameBox();
			while (!this.isOpening() && !this.isClosing()) {
				//開いてる時の独自処理
				if (this.isOpen() && $gameSwitches.value(142)) {
					var v = $gameVariables.value(117);
					var vt = $gameVariables.value(118);

					if (v === "loading") {
						//ボイスのロード完了してたら
						if (AudioManager._voiceBuffer && AudioManager._voiceBuffer._totalTime) {
							$gameVariables.setValue(117, "playing");
							$gameVariables.setValue(
								118,
								Math.ceil((AudioManager._voiceBuffer._totalTime - AudioManager._voiceBuffer.seek()) * 60 + 10)
							);
						} else {
							vt--;

							//ロード時間切れ
							if (vt < 0) {
								$gameVariables.setValue(117, "next");
							} else {
								$gameVariables.setValue(118, vt);
							}
						}
					} else if (v === "playing" || v === "text") {
						vt--;
						//オート時間終了
						if (vt < 0) {
							this.CBR_auto_wait = 30;
							$gameVariables.setValue(117, "next"); //ここから先はinputの方でやる
						} else {
							$gameVariables.setValue(118, vt);
						}
					} else {
						$gameVariables.setValue(118, 40);
						$gameVariables.setValue(117, "next"); //ここから先はinputの方でやる
					}
				}

				if (this.updateWait()) {
					if (this._waitForTerminate && this._waitCount === 0) {
						this._waitForTerminate = false;
						this.terminateMessage();
					}
					return;
				} else if (this.updateLoading()) {
					return;
				} else if (this.updateInput()) {
					return;
				} else if (this.updateMessage()) {
					return;
				} else if (this.canStart()) {
					this.startMessage();
				} else {
					this.startInput();
					return;
				}
			}
		}
	};

	var Window_Message_newPage = Window_Message.prototype.newPage;
	Window_Message.prototype.newPage = function (textState) {
		Window_Message_newPage.call(this, textState);
		if ($gameSwitches.value(142) && $gameVariables.value(117) != "loading" && $gameVariables.value(117) != "playing") {
			//loading出ない場合、新しいテキストを開いたときは文字数を待機時間にする
			$gameVariables.setValue(117, "text");
			$gameVariables.setValue(118, Math.ceil(textState.text.length * (8 - (7 / 100) * ConfigManager.autoMsSpeedVolume))); // 1文字辺りのフレーム数を1~8
		}
	};

	Window_Message.prototype.updateInput = function () {
		if (this.isAnySubWindowActive()) {
			return true;
		}
		//飛ばすとき
		if (this.pause) {
			if (utakata.MessageSkip.isPressedMsgSkipButton()) {
				this.pause = false;
				if (!this._textState) {
					this.terminateMessage();
				}
				return true;
			}

			if (this.isTriggered() || ($gameSwitches.value(142) && $gameVariables.value(117) === "next")) {
				if (this.isTriggered()) {
					this.CBR_auto_wait = 0;
				}

				if (0 < this.CBR_auto_wait) {
					if (!this.isHidden()) {
						this.CBR_auto_wait--;
					}
				} else {
					$gameVariables.setValue(117, "end");
					Input.update();
					this.pause = false;
					if (!this._textState) {
						this.terminateMessage();
					}
				}
			}
			return true;
		}
		return false;
	};

	const _Window_Message_terminateMessage = Window_Message.prototype.terminateMessage;
	Window_Message.prototype.terminateMessage = function () {
		// ボイスを停止
		AudioManager.playVoice({ name: "", volume: 100, pitch: 100, pan: 0 });
		if ($gameSwitches.value(146)) {
			// BGSを復帰させる（ボリューム調整した場合のみ）
			AudioManager.bgsVolume = $gameVariables.value(119);
			$gameSwitches.setValue(146, false);
		}
		// ピクチャ9を消去する
		$gameScreen.erasePicture(9);
		// 元の処理
		_Window_Message_terminateMessage.call(this);
	};
})();

AudioManager._voiceVolume = 100;
AudioManager._voiceBuffer = null;

Object.defineProperty(AudioManager, "voiceVolume", {
	get: function () {
		return this._voiceVolume;
	},
	set: function (value) {
		this._voiceVolume = value;
		this.updateVoiceParameters(this._currentVoice);
	},
	configurable: true
});

AudioManager.playVoice = function (voice) {
	var mat = /^Vo_([a-z]+)/g.exec(voice.name);
	if (mat) {
		var list = {
			sir: 503,
			yoz: 504,
			rei: 505,
			kao: 506,
			kur: 507,
			chi: 508,
			aki: 510,
			nar: 511,
			mir: 509,
			kag: 512,
			mob: 513
		};
		var key = list[mat[1]] || 513;
		if (key) {
			if ($gameVariables.value(key) === 2) {
				return;
			}
		}
	} else {
		if ($gameVariables.value(key) === 2) {
			return;
		}
	}

	this.stopVoice();

	if (voice.name) {
		//現在のBGVのボリュームを記憶する（戦闘中は除外）
		if (!$gameParty.inBattle()) {
			if (SceneManager._scene.constructor.name != "Scene_SplashScreen" && SceneManager._scene.constructor.name != "Scene_Title") {
				$gameVariables.setValue(119, AudioManager._bgsVolume);
				$gameSwitches.setValue(146, true);
				AudioManager.bgsVolume = 0;
			}
		}
		this._voiceBuffer = this.createBuffer("voice/", voice.name);
		this.updateVoiceParameters(voice);
		this._voiceBuffer.play(false);
		this._voiceBuffer.addStopListener(this.stopVoice.bind(this));
	}
};
AudioManager.stopVoice = function () {
	if (this._voiceBuffer) {
		this._voiceBuffer.destroy();
		this._voiceBuffer = null;
	}
};
AudioManager.updateVoiceParameters = function (voice) {
	this.updateBufferParameters(this._voiceBuffer, this._meVolume, voice);
};

AudioManager.fadeOutMe = function (duration) {
	if (this._voiceBuffer) {
		this._voiceBuffer.fadeOut(duration);
	}
};

AudioManager.stopMe = function () {
	if (this._voiceBuffer) {
		this._voiceBuffer.destroy();
		this._voiceBuffer = null;
	}
};
