//=============================================================================
// KMS_QuickNotification.js
//   Last update: 2020/02/01
//=============================================================================

/*:
 * @plugindesc
 * [v0.1.1] Show popup notification.
 *
 * @author Kameo (Kamesoft)
 *
 * @param Display duration
 * @default 300
 * @desc Display frame count.
 *
 * @param Display position
 * @default 0
 * @desc
 *  Notification position.
 *  0: TopLeft  1: TopRight  2: BottomLeft  3: BottomRight
 *
 * @param Face image size
 * @default 64
 * @desc Face image size in notification by pixel.
 *
 * @param Font size
 * @default 18
 * @desc Font size for notification.
 *
 * @param Max notification count
 * @default 4
 * @desc Max number of notifications which can be displayed together.
 *
 * @param Notification SE
 * @default Saint5
 * @require 1
 * @dir audio/se/
 * @type file
 * @desc SE for showing notification.
 *
 * @param Notification SE param
 * @default 100, 50
 * @desc
 * Format: Volume, Pitch, Pan
 * Parameters for notification SE.
 *
 * @param Notification skin
 * @default QuickNotificationSkin
 * @require 1
 * @dir img/system/
 * @type file
 * @desc Skin for notifications. Load from img/system.
 *
 *
 * @help
 *
 * ## Plugin command
 *
 * QuickNotification enable     # Enable quick notification
 * QuickNotification disable    # Display quick notification
 * QuickNotification register   # Register quick notification by the next message event
 *
 */

/*:ja
 * @plugindesc
 * [v0.1.1] ポップアップ通知を表示する機能を追加します。
 *
 * @author かめお (Kamesoft)
 *
 * @param Display duration
 * @default 180
 * @desc 通知表示時間をフレーム単位で指定します。
 *
 * @param Display position
 * @default 0
 * @desc
 *  通知を表示する位置です。
 *  0: 左上  1: 右上  2: 左下  3: 右下
 *
 * @param Face image size
 * @default 64
 * @desc 通知用顔グラフィックのサイズをピクセル単位で指定します。
 *
 * @param Font size
 * @default 18
 * @desc 通知のフォントサイズを指定します。
 *
 * @param Max notification count
 * @default 4
 * @desc 同時に表示できる通知の最大数です。
 *
 * @param Notification SE
 * @default Saint5
 * @require 1
 * @dir audio/se/
 * @type file
 * @desc 通知表示時に演奏する SE のファイル名です。 audio/se から読み込みます。
 *
 * @param Notification SE param
 * @default 100, 50
 * @desc
 * 書式: ボリューム, ピッチ, パン
 * 通知表示時に演奏する SE のパラメータです。ピッチ以降省略可。
 *
 * @param Notification skin
 * @default QuickNotificationSkin
 * @require 1
 * @dir img/system/
 * @type file
 * @desc 通知の表示に使用するスキン画像です。 img/system から読み込みます。
 *
 *
 * @help
 *
 * ■ プラグインコマンド
 *
 * QuickNotification enable     # 通知を有効にします。
 * QuickNotification disable    # 通知を無効にします。
 * QuickNotification register   # 次の「文章の表示」コマンドで通知を登録します。
 *
 */

var KMS = KMS || {};

(function () {
  "use strict";

  // 定数
  var Const = {
    debug: false, // デバッグモード
    pluginCode: "QuickNotification", // プラグインコード

    // 表示位置
    displayPosition: {
      topLeft: 0, // 左上
      topRight: 1, // 右上
      bottomLeft: 2, // 左下
      bottomRight: 3, // 右下
    },
  };

  var PluginName = "KMS_" + Const.pluginCode;

  KMS.imported = KMS.imported || {};
  KMS.imported[Const.pluginCode] = true;

  // デフォルト値つきで文字列から int を解析
  function parseIntWithDefault(param, defaultValue) {
    var value = parseInt(param);
    return isNaN(value) ? defaultValue : value;
  }

  var pluginParams = PluginManager.parameters(PluginName);
  var Params = {};
  Params.displayDuration = Math.max(
    parseIntWithDefault(pluginParams["Display duration"], 300),
    1
  );
  Params.displayGap = parseIntWithDefault(pluginParams["Display gap"], 16);
  Params.displayOffsetX = parseIntWithDefault(
    pluginParams["Display offset X"],
    -2
  );
  Params.displayOffsetY = parseIntWithDefault(
    pluginParams["Display offset Y"],
    32
  );
  Params.faceImageSize = Math.max(
    parseIntWithDefault(pluginParams["Face image size"], 64),
    1
  );
  Params.fadeFrameCount = Math.max(
    parseIntWithDefault(pluginParams["Fade frame count"], 8),
    1
  );
  Params.fontSize = Math.max(
    parseIntWithDefault(pluginParams["Font size"], 18),
    1
  );
  Params.notificationCountMax = Math.max(
    parseIntWithDefault(pluginParams["Max notification count"], 4),
    1
  );
  Params.notificationSkin =
    pluginParams["Notification skin"] || "QuickNotificationSkin";
  Params.displayPosition = Math.min(
    Math.max(
      parseIntWithDefault(
        pluginParams["Display position"],
        Const.displayPosition.topLeft
      ),
      Const.displayPosition.topLeft
    ),
    Const.displayPosition.bottomRight
  );

  // 通知 SE の解析
  (function () {
    Params.notificationSe = null;

    var paramFile = pluginParams["Notification SE"];
    if (!paramFile) {
      return;
    }

    var paramFileArgs = paramFile.replace(/\s+/g, "").split(/,/);
    if (paramFileArgs.length <= 0) {
      return;
    }

    Params.notificationSe = { name: paramFileArgs[0] };

    var paramArgs = { volume: 90, pitch: 100, pan: 0 };
    var paramDetail = pluginParams["Notification SE param"];
    if (paramDetail != null) {
      var paramDetailArgs = paramDetail.replace(/\s+/g, "").split(/,/);
      paramArgs.volume = Number(paramDetailArgs[0]) || paramArgs.volume;
      paramArgs.pitch = Number(paramDetailArgs[1]) || paramArgs.pitch;
      paramArgs.pan = Number(paramDetailArgs[2]) || paramArgs.pan;
    }

    Params.notificationSe.volume = Number(paramArgs.volume) || 90;
    Params.notificationSe.pitch = Number(paramArgs.pitch) || 100;
    Params.notificationSe.pan = Number(paramArgs.pan) || 0;
  })();

  // デバッグログ
  var debuglog;
  if (Const.debug) {
    debuglog = function () {
      console.log(arguments);
    };
  } else {
    debuglog = function () {};
  }

  var _Game_Interpreter_pluginCommand =
    Game_Interpreter.prototype.pluginCommand;
  Game_Interpreter.prototype.pluginCommand = function (command, args) {
    _Game_Interpreter_pluginCommand.call(this, command, args);

    if (command !== Const.pluginCode) {
      return;
    }

    switch (args[0]) {
      case "enable": // 有効化
        $gameSystem.setQuickNotificationEnabled(true);
        break;

      case "disable": // 無効化
        $gameSystem.setQuickNotificationEnabled(false);
        break;

      case "register": // 通知の登録開始
        $gameTemp.setQuickNotificationRegistrationMode(true);
        break;

      default:
        // 不明なコマンド
        console.error("[%s %s] Unknown command.", Const.pluginCode, args[0]);
        break;
    }
  };

  //-----------------------------------------------------------------------------
  // Game_Temp

  var _Game_Temp_initialize = Game_Temp.prototype.initialize;
  Game_Temp.prototype.initialize = function () {
    _Game_Temp_initialize.call(this);

    this.setQuickNotificationRegistrationMode(false);
    this.clearQuickNotification();
  };

  /**
   * 通知登録モードの切り替え
   */
  Game_Temp.prototype.setQuickNotificationRegistrationMode = function (flag) {
    this._isQuickNotificationRegistering = !!flag;
  };

  /**
   * 通知登録モードに設定されているか
   */
  Game_Temp.prototype.isQuickNotificationRegistrationMode = function () {
    return this._isQuickNotificationRegistering;
  };

  /**
   * 通知の登録
   */
  Game_Temp.prototype.registerQuickNotification = function (notification) {
    this._quickNotifications.push(notification);
  };

  /**
   * 通知のクリア
   */
  Game_Temp.prototype.clearQuickNotification = function () {
    this._quickNotifications = [];
  };

  /**
   * 次の通知を取得
   */
  Game_Temp.prototype.retrieveNextQuickNotification = function () {
    return this._quickNotifications.shift();
  };

  /**
   * 通知が登録されているか
   */
  Game_Temp.prototype.isQuickNotificationReady = function () {
    return this._quickNotifications.length > 0;
  };

  //-----------------------------------------------------------------------------
  // Game_System

  /**
   * 通知の有効状態を取得
   */
  Game_System.prototype.isQuickNotificationEnabled = function () {
    return this._quickNotificationEnabled != null
      ? this._quickNotificationEnabled
      : true;
  };

  /**
   * 通知の有効状態を設定
   */
  Game_System.prototype.setQuickNotificationEnabled = function (enabled) {
    this._quickNotificationEnabled = !!enabled;
  };

  //-----------------------------------------------------------------------------
  // Game_Interpreter

  var _Game_Interpreter_command101 = Game_Interpreter.prototype.command101;
  Game_Interpreter.prototype.command101 = function () {
    if (
      !$gameMessage.isBusy() &&
      $gameTemp.isQuickNotificationRegistrationMode()
    ) {
      $gameTemp.setQuickNotificationRegistrationMode(false);

      var notification = {
        text: "",
        faceName: this._params[0],
        faceIndex: this._params[1],
      };
      //$gameMessage.setBackground(this._params[2]);
      //$gameMessage.setPositionType(this._params[3]);

      // テキストを改行区切りで連結
      while (this.nextEventCode() === 401) {
        if (notification.text.length > 0) {
          notification.text += "\n";
        }

        this._index++;
        notification.text += this.currentCommand().parameters[0];
      }

      // 通知の登録
      $gameTemp.registerQuickNotification(notification);

      // 次のコマンドへ
      this._index++;

      return false;
    }

    return _Game_Interpreter_command101.call(this);
  };

  //-----------------------------------------------------------------------------
  // Window_QuickNotification
  //
  // 通知を表示するウィンドウ

  function Window_QuickNotification() {
    this.initialize.apply(this, arguments);
  }

  Window_QuickNotification.prototype = Object.create(Window_Base.prototype);
  Window_QuickNotification.prototype.constructor = Window_QuickNotification;

  // メッセージの一時描画バッファ
  Window_QuickNotification.tempMessageBuffer = null;

  /**
   * 通知用スキンの事前読み込み
   */
  Window_QuickNotification.preloadWindowskin = function () {
    ImageManager.loadSystem(Params.notificationSkin);
  };

  Window_QuickNotification.prototype.initialize = function () {
    // コンテンツサイズは内容に応じて可変なので、ウィンドウサイズは仮
    Window_Base.prototype.initialize.call(this, 0, 0, 64, 64);

    if (Window_QuickNotification.tempMessageBuffer == null) {
      Window_QuickNotification.tempMessageBuffer = new Bitmap(
        Graphics.boxWidth,
        Graphics.boxHeight / 2
      );
    }

    this.opacity = 0;
    this.contentsOpacity = 0;
    this.initMembers();
  };

  Window_QuickNotification.prototype.standardFontSize = function () {
    return Params.fontSize;
  };

  Window_QuickNotification.prototype.loadWindowskin = function () {
    // デフォルトのスキンの代わりに、通知用のスキンを読み込む
    this._windowskin = ImageManager.loadSystem(Params.notificationSkin);
  };

  Window_QuickNotification.prototype.initMembers = function () {
    this._textState = null;
    this._allTextWidth = 0;
    this._allTextHeight = 0;
    this._duration = 0;
    this._destinationY = -1;
    this._faceName = "";
    this._faceIndex = 0;
    this._faceBitmap = null;
  };

  /**
   * 目標 Y 座標を設定
   */
  Window_QuickNotification.prototype.setDestinationY = function (y) {
    // 最初は目標位置にそのまま表示する
    if (this._destinationY < 0) {
      this.y = y;
    }

    this._destinationY = y;
  };

  Window_QuickNotification.prototype.hide = function () {
    this._duration = 0;

    Window_Base.prototype.hide.call(this);
  };

  /**
   * フェードアウト
   */
  Window_QuickNotification.prototype.fadeOut = function () {
    if (this.isFadingOut()) {
      return;
    }

    if (this.isFadingIn()) {
      // フェードイン中は同じ不透明度からフェードアウトする
      this._duration = Params.displayDuration - this._duration;
    } else {
      this._duration = Params.fadeFrameCount;
    }
  };

  Window_QuickNotification.prototype.numVisibleRows = function () {
    return 4;
  };

  /**
   * 通知を表示中か
   */
  Window_QuickNotification.prototype.isDisplaying = function () {
    return this._duration > 0;
  };

  /**
   * フェードイン中か
   */
  Window_QuickNotification.prototype.isFadingIn = function () {
    return this._duration >= Params.displayDuration - Params.fadeFrameCount;
  };

  /**
   * フェードアウト中か
   */
  Window_QuickNotification.prototype.isFadingOut = function () {
    return this._duration < Params.fadeFrameCount;
  };

  /**
   * 顔グラフィックのロード中処理
   */
  Window_QuickNotification.prototype.updateLoading = function () {
    if (this._faceBitmap == null) {
      return false;
    }

    if (ImageManager.isReady()) {
      this.drawMessageFace();
      this._faceBitmap = null;
      return false;
    } else {
      return true;
    }
  };

  /**
   * 目標不透明度の取得
   */
  Window_QuickNotification.prototype.getTargetOpacity = function () {
    if (this.isFadingIn()) {
      // フェードイン
      return (
        (255 * (Params.displayDuration - this._duration)) /
        Params.fadeFrameCount
      );
    } else if (this.isFadingOut()) {
      // フェードアウト
      return (255 * this._duration) / Params.fadeFrameCount;
    } else {
      return 255;
    }
  };

  /**
   * 通知の表示開始
   */
  Window_QuickNotification.prototype.display = function (notification) {
    this.initMembers();

    if (notification == null || notification.text == null) {
      this.hide();
      return;
    }

    // 表示パラメータの設定
    this._textState = {
      index: 0,
      text: this.convertEscapeCharacters(notification.text),
    };
    this._allTextWidth = 0;
    this._duration = Params.displayDuration;
    this._faceName = notification.faceName || "";
    this._faceIndex = notification.faceIndex;
    this._faceBitmap = null;

    this.newPage(this._textState);
    this.updatePosition();
    this.updateOpacity();
    this.show();
  };

  /**
   * 新しいページの表示
   */
  Window_QuickNotification.prototype.newPage = function (textState) {
    // コンテンツを一時領域に書く
    this.contents = Window_QuickNotification.tempMessageBuffer;
    this.contents.clear();
    this.resetFontSettings();
    this.loadMessageFace();
    textState.x = this.newLineX();
    textState.y = 0;
    textState.left = this.newLineX();
    textState.height = this.calcTextHeight(textState, false);
    this._allTextHeight = this.calcTextHeight(textState, true);
    if (this._faceName) {
      this._allTextHeight = Math.max(this._allTextHeight, Params.faceImageSize);
    }

    this.updateMessage();

    // コンテンツを一時領域から正式に反映
    this.createContents();
    this.contents.blt(
      Window_QuickNotification.tempMessageBuffer,
      0,
      0,
      this._allTextWidth,
      this._allTextHeight,
      0,
      0,
      this._allTextWidth,
      this._allTextHeight
    );
  };

  /**
   * 顔グラフィックを読み込む
   */
  Window_QuickNotification.prototype.loadMessageFace = function () {
    this._faceBitmap = ImageManager.loadFace(this._faceName);
  };

  /**
   * 表示位置を設定
   */
  Window_QuickNotification.prototype.updatePosition = function () {
    // 不透明度に応じて位置をずらす
    var xOffset =
      Params.displayOffsetX -
      ((this.width / 2) * (255 - this.getTargetOpacity())) / 255;
    switch (Params.displayPosition) {
      case Const.displayPosition.topRight:
      case Const.displayPosition.bottomRight:
        // 右側
        this.x = Graphics.boxWidth - this.width - xOffset;
        break;

      default:
        // 左側
        this.x = xOffset;
        break;
    }

    var epsilon = 8;
    var diffY = this.y - this._destinationY;
    if (Math.abs(diffY) > epsilon) {
      // 目標位置とズレている場合はぬるっと移動
      if (diffY > 0) {
        this.y -= Math.max(diffY / 8, epsilon);
      } else {
        this.y -= Math.min(diffY / -8, -epsilon);
      }
    } else {
      this.y = this._destinationY;
    }
  };

  /**
   * ウィンドウのサイズを更新
   */
  Window_QuickNotification.prototype.updateWindowSize = function () {
    var offset = this.standardPadding() * 2;
    this.width = this._allTextWidth + offset;
    this.height = this._allTextHeight + offset;
  };

  /**
   * 不透明度の更新
   */
  Window_QuickNotification.prototype.updateOpacity = function () {
    this.opacity = this.contentsOpacity = this.getTargetOpacity();
  };

  Window_QuickNotification.prototype.update = function () {
    Window_Base.prototype.update.call(this);

    if (!this.isDisplaying()) {
      return;
    }

    if (this.updateLoading()) {
      // スキンのロード中
      return;
    }

    this._duration--;
    this.updateOpacity();
    this.updatePosition();

    // 表示が終了したら初期化
    if (!this.isDisplaying()) {
      this.initMembers();
    }
  };

  /**
   * メッセージの更新
   */
  Window_QuickNotification.prototype.updateMessage = function () {
    if (this._textState == null) {
      return false;
    }

    while (!this.isEndOfText(this._textState)) {
      this.processCharacter(this._textState);
      this._allTextWidth = Math.max(this._allTextWidth, this._textState.x);
    }

    this.updateWindowSize();

    return true;
  };

  /**
   * 顔グラフィックを描画
   */
  Window_QuickNotification.prototype.drawMessageFace = function () {
    // 指定サイズに拡縮して描画
    var size = Params.faceImageSize;
    var bitmap = ImageManager.loadFace(this._faceName);
    var sw = Window_Base._faceWidth;
    var sh = Window_Base._faceHeight;
    var sx = (this._faceIndex % 4) * sw;
    var sy = Math.floor(this._faceIndex / 4) * sh;
    this.contents.blt(bitmap, sx, sy, sw, sh, 0, 0, size, size);
  };

  /**
   * 改行時の描画先 X 座標
   */
  Window_QuickNotification.prototype.newLineX = function () {
    return this._faceName === "" ? 0 : Params.faceImageSize + 24;
  };

  /**
   * 改行の処理
   */
  Window_QuickNotification.prototype.processNewLine = function (textState) {
    this._allTextWidth = Math.max(this._allTextWidth, textState.x);

    Window_Base.prototype.processNewLine.call(this, textState);
  };

  /**
   * 改ページの処理
   */
  Window_QuickNotification.prototype.processNewPage = function (textState) {
    Window_Base.prototype.processNewPage.call(this, textState);
    if (textState.text[textState.index] === "\n") {
      textState.index++;
    }

    textState.y = this.contents.height;
  };

  /**
   * テキスト終端か
   */
  Window_QuickNotification.prototype.isEndOfText = function (textState) {
    return textState.index >= textState.text.length;
  };

  /**
   * 改ページが必要か
   */
  Window_QuickNotification.prototype.needsNewPage = function (textState) {
    return (
      !this.isEndOfText(textState) &&
      textState.y + textState.height > this.contents.height
    );
  };

  //-----------------------------------------------------------------------------
  // Scene_Base

  // シーンをまたいで保持するための通知ウィンドウの一覧
  Scene_Base._gQuickNotificationWindows = [];

  /**
   * 通知ウィンドウの作成
   */
  Scene_Base.prototype.createQuickNotificationWindow = function () {
    if (this._quickNotificationWindowLayer != null) {
      return;
    }

    var width = Graphics.boxWidth;
    var height = Graphics.boxHeight;
    var x = (Graphics.width - width) / 2;
    var y = (Graphics.height - height) / 2;
    this._quickNotificationWindowLayer = new WindowLayer();
    this._quickNotificationWindowLayer.move(x, y, width, height);
    this.addChild(this._quickNotificationWindowLayer);

    Window_QuickNotification.preloadWindowskin();

    // 表示終了前の通知があれば表示
    Scene_Base._gQuickNotificationWindows.forEach(function (windowObj) {
      this._quickNotificationWindowLayer.addChild(windowObj);
    }, this);
  };

  /**
   * 通知ウィンドウを表示可能か
   */
  Scene_Base.prototype.isQuickNotificationAvailable = function () {
    // ゲーム起動時は $gameTemp と $gameSystem が生成されていない可能性があるのでチェック
    return (
      this._quickNotificationWindowLayer != null &&
      $gameTemp != null &&
      $gameSystem != null
    );
  };

  var _Scene_Base_update = Scene_Base.prototype.update;
  Scene_Base.prototype.update = function () {
    _Scene_Base_update.call(this);

    this.updateQuickNotificationDisplay();
  };

  var _Scene_Base_terminate = Scene_Base.prototype.terminate;
  Scene_Base.prototype.terminate = function () {
    _Scene_Base_terminate.call(this);

    this.destroyQuickNotificationWindows();
  };

  /**
   * 通知ウィンドウの破棄
   */
  Scene_Base.prototype.destroyQuickNotificationWindows = function () {
    if (!this.isQuickNotificationAvailable()) {
      return;
    }

    var layer = this._quickNotificationWindowLayer;
    layer.children.forEach(function (child) {
      this._quickNotificationWindowLayer.removeChild(child);
    }, this);

    this.removeChild(layer);
    this._quickNotificationWindowLayer = null;
  };

  /**
   * 通知の表示を更新
   */
  Scene_Base.prototype.updateQuickNotificationDisplay = function () {
    if (!this.isQuickNotificationAvailable()) {
      return;
    }

    if (!$gameSystem.isQuickNotificationEnabled()) {
      // 通知を表示できないときは非表示にしつつ各種フラグを解除
      $gameTemp.clearQuickNotification();
      this._quickNotificationWindowLayer.children.forEach(function (windowObj) {
        windowObj.fadeOut();
      });
      return;
    }

    this.removeFinishedQuickNotification();

    // 最大数まで表示されている場合は追加表示しない
    if (
      this._quickNotificationWindowLayer.children.length >=
      Params.notificationCountMax
    ) {
      return;
    }

    // 要求されているメッセージを表示できるだけ表示
    while ($gameTemp.isQuickNotificationReady()) {
      if (!this.displayQuickNotification()) {
        break;
      }
    }

    this.updateQuickNotificationPosition();
  };

  /**
   * 表示が終了した通知を削除
   */
  Scene_Base.prototype.removeFinishedQuickNotification = function () {
    var finishedWindows = this._quickNotificationWindowLayer.children.filter(
      function (child) {
        return !child.isDisplaying();
      }
    );

    if (finishedWindows.length <= 0) {
      // 終了した通知がない
      return;
    }

    finishedWindows.forEach(function (windowObj) {
      this._quickNotificationWindowLayer.removeChild(windowObj);
    }, this);

    Scene_Base._gQuickNotificationWindows =
      Scene_Base._gQuickNotificationWindows.filter(function (windowObj) {
        return finishedWindows.indexOf(windowObj) < 0;
      });
  };

  /**
   * 通知の表示
   */
  Scene_Base.prototype.displayQuickNotification = function () {
    var notification = $gameTemp.retrieveNextQuickNotification();
    if (notification == null) {
      return false;
    }

    // 予約されている通知を表示
    var windowObj = new Window_QuickNotification();
    windowObj.display(notification);
    this._quickNotificationWindowLayer.addChild(windowObj);
    Scene_Base._gQuickNotificationWindows.push(windowObj);

    // 通知音を再生
    if (Params.notificationSe) {
      AudioManager.playSe(Params.notificationSe);
    }

    return true;
  };

  /**
   * 通知の表示位置を更新
   */
  Scene_Base.prototype.updateQuickNotificationPosition = function () {
    // 表示位置に応じた調整
    var isBottom;
    var y;
    var sign;
    switch (Params.displayPosition) {
      case Const.displayPosition.bottomLeft:
      case Const.displayPosition.bottomRight:
        // 下側
        isBottom = true;
        y = Graphics.boxHeight - Params.displayOffsetY;
        sign = -1;
        break;

      default:
        // 上側
        isBottom = false;
        y = Params.displayOffsetY;
        sign = 1;
        break;
    }

    var children = this._quickNotificationWindowLayer.children;
    for (var i = 0; i < children.length; i++) {
      var windowObj = children[i];
      if (isBottom) {
        y -= windowObj.height;
      }
      windowObj.setDestinationY(y);
      if (!isBottom) {
        y += windowObj.height;
      }

      y += sign * Params.displayGap;
    }
  };

  //-----------------------------------------------------------------------------
  // Scene_Base

  var _Scene_Base_start = Scene_Base.prototype.start;
  Scene_Base.prototype.start = function () {
    _Scene_Base_start.call(this);

    // 他のオブジェクトより前面に表示するため、シーン開始時まで生成を遅延
    this.createQuickNotificationWindow();
  };

  //-----------------------------------------------------------------------------
  // Scene_Map

  var _Scene_Map_snapForBattleBackground =
    Scene_Map.prototype.snapForBattleBackground;
  Scene_Map.prototype.snapForBattleBackground = function () {
    // 通知はキャプチャしない
    var layer = this._quickNotificationWindowLayer;
    if (layer != null) {
      layer.visible = false;
    }

    _Scene_Map_snapForBattleBackground.call(this);

    if (layer != null) {
      layer.visible = true;
    }
  };
})();
