/*:
 * @target MZ
 * @plugindesc v1.0 メッセージ系ウィンドウの背景を「完全な黒」でベタ塗り表示にします（ウィンドウスキン無視）
 * @author ChatGPT
 *
 * @help
 * このプラグインは、RPGツクールMZのメッセージ関連ウィンドウの背景を
 * ウィンドウスキン画像に依存せず「真っ黒のベタ塗り」で描画します。
 * 「文章の表示」の背景設定（ウィンドウ／暗くする／透明）に関わらず、
 * 対象ウィンドウの内側は常に黒で塗りつぶされます。
 *
 * ■使い方
 * 1) 本ファイルをプロジェクトの js/plugins フォルダへ置きます。
 * 2) プラグイン管理で「有効」にします。
 * 3) 必要に応じてパラメータで対象ウィンドウや不透明度を調整してください。
 *
 * ■注意点
 * ・対象ウィンドウの「枠（フレーム）」は既定で非表示にします（設定で変更可）。
 * ・他のウィンドウ見た目変更系プラグインと併用する場合、読み込み順で表示が変わる
 *   ことがあります。黒ベタを最優先にしたい場合は、本プラグインを下（後）に配置してください。
 *
 * ■動作対象
 * ・メッセージウィンドウ、選択肢ウィンドウ（既定でON）
 * ・数値入力、アイテム選択、ネームボックス（既定でOFF／必要時にON）
 *
 * @param ApplyToMessage
 * @text メッセージに適用
 * @type boolean
 * @on する
 * @off しない
 * @default true
 *
 * @param ApplyToChoiceList
 * @text 選択肢に適用
 * @type boolean
 * @on する
 * @off しない
 * @default true
 *
 * @param ApplyToNumberInput
 * @text 数値入力に適用
 * @type boolean
 * @on する
 * @off しない
 * @default false
 *
 * @param ApplyToEventItem
 * @text アイテム選択に適用
 * @type boolean
 * @on する
 * @off しない
 * @default false
 *
 * @param ApplyToNameBox
 * @text ネームボックスに適用
 * @type boolean
 * @on する
 * @off しない
 * @default false
 *
 * @param HideWindowFrame
 * @text ウィンドウ枠を隠す
 * @type boolean
 * @on 隠す
 * @off 表示する
 * @default true
 *
 * @param Opacity
 * @text 背景の不透明度(0-255)
 * @type number
 * @min 0
 * @max 255
 * @default 255
 */
(() => {
    "use strict";
    const PLUGIN_NAME = document.currentScript
        ? (document.currentScript.src.match(/([^\/]+)\.js$/) || [,"SolidBlackMessage"])[1]
        : "SolidBlackMessage";

    const params = PluginManager.parameters(PLUGIN_NAME);
    const applyMessage     = String(params["ApplyToMessage"] ?? "true") === "true";
    const applyChoiceList  = String(params["ApplyToChoiceList"] ?? "true") === "true";
    const applyNumberInput = String(params["ApplyToNumberInput"] ?? "false") === "true";
    const applyEventItem   = String(params["ApplyToEventItem"] ?? "false") === "true";
    const applyNameBox     = String(params["ApplyToNameBox"] ?? "false") === "true";
    const hideFrame        = String(params["HideWindowFrame"] ?? "true") === "true";
    const backOpacity      = Math.max(0, Math.min(255, Number(params["Opacity"] ?? 255)));

    function solidRefreshBack() {
        // Window 内部の黒ベタ背景を描く。ウィンドウスキンは使わない。
        const margin = (this._margin !== undefined) ? this._margin : 4;
        const w = Math.max(1, this.width - margin * 2);
        const h = Math.max(1, this.height - margin * 2);

        if (this._backSprite) {
            const bmp = new Bitmap(w, h);
            // 完全な黒で塗りつぶし（不透明度はSprite側で調整）
            bmp.fillRect(0, 0, w, h, "#000000");
            this._backSprite.bitmap = bmp;
            if (this._backSprite.setFrame) this._backSprite.setFrame(0, 0, w, h);
            this._backSprite.move(margin, margin);
            this._backSprite.opacity = backOpacity;
        }
        if (this._frameSprite) {
            this._frameSprite.visible = !hideFrame;
        }
    }

    function patchWindowClass(WindowClass) {
        if (!WindowClass || !WindowClass.prototype || !WindowClass.prototype._refreshBack) return;
        const _refreshBack = WindowClass.prototype._refreshBack;
        WindowClass.prototype._refreshBack = function() {
            // 既存処理を完全に置き換える（黒ベタ優先）
            solidRefreshBack.call(this);
        };
    }

    // 適用対象にパッチを当てる
    if (applyMessage && typeof Window_Message !== "undefined") {
        patchWindowClass(Window_Message);
    }
    if (applyChoiceList && typeof Window_ChoiceList !== "undefined") {
        patchWindowClass(Window_ChoiceList);
    }
    if (applyNumberInput && typeof Window_NumberInput !== "undefined") {
        patchWindowClass(Window_NumberInput);
    }
    if (applyEventItem && typeof Window_EventItem !== "undefined") {
        patchWindowClass(Window_EventItem);
    }
    if (applyNameBox && typeof Window_NameBox !== "undefined") {
        patchWindowClass(Window_NameBox);
    }

})();