/*:
 * @target MZ
 * @plugindesc [v1.0.0] ゲージを一括グレースケール化。メニュー用(Sprite_Gauge)もバトル用(Window_Base.drawGauge)も白黒でグラデ。戦闘でもカラーに戻りません。
 * @author
 *
 * @help
 * =============================================================================
 * ■ 概要
 * =============================================================================
 * - ツクールMZでは、メニュー画面のゲージ表示に Sprite_Gauge を使うことが多く、
 *   バトルステータスのゲージに Window_Base.drawGauge を用いるパターンがあり、
 *   片方だけを上書きしていると「メニューは白黒だけどバトルはカラー」の問題が起こります。
 * - このプラグインは両方( drawGaugeRect と drawGauge )を上書きし、
 *   color1/color2 をモノクロにしたうえで輝度差を強制的に大きめに保ち、
 *   白黒グラデーションが消えないようにします。
 * - 結果として、メニュー画面でもバトルステータスでもゲージはモノクロ化され、
 *   グラデーションもはっきり見えるようになります。
 *
 * ■ 使い方
 * 1) このファイルを「IM_GrayscaleGaugeUnifiedPatch.js」でjs/pluginsフォルダに置き、
 *    プラグイン管理でONにします。
 * 2) それだけで、メニュー画面・バトル画面を含めたすべてのゲージがグレースケール表示
 *    (color1/color2を白黒化)されるようになります。
 * 3) 他プラグインで drawGaugeRect または drawGauge を再上書きしている場合、
 *    ロード順によって競合する可能性があります。最下部に置くなど調整してください。
 *
 * ■ バージョン
 * v1.0.0 (2025/xx/xx):
 *   - 初版。Sprite_Gauge と Window_Base.drawGauge の両方を白黒化＆差分強制処理。
 *
 */

(() => {
    "use strict";

    //--------------------------------------------------------------------------
    // A) ヘルパー: color1, color2 をモノクロ化し、輝度差を強制してグラデを残す
    //--------------------------------------------------------------------------
    function calcLuminance(hexColor) {
        const hex = hexColor.replace(/^#/, "");
        if (hex.length<6) return 128; // fallback
        const r = parseInt(hex.slice(0,2),16);
        const g = parseInt(hex.slice(2,4),16);
        const b = parseInt(hex.slice(4,6),16);
        return Math.round(0.299*r + 0.587*g + 0.114*b);
    }

    function lumToHex(L) {
        const v = Math.max(0, Math.min(255, L));
        const s = v.toString(16).padStart(2,"0");
        return `#${s}${s}${s}`;
    }

    // 2色をモノクロ化してから、差が minDiff未満なら押し広げる
    function grayscaleWithMinDiff(c1, c2, minDiff=80) {
        let L1 = calcLuminance(c1);
        let L2 = calcLuminance(c2);

        const diff = Math.abs(L2 - L1);
        if (diff<minDiff) {
            const needed = minDiff - diff;
            const push = Math.floor(needed/2);
            if (L1< L2) {
                L1 = Math.max(0, L1 - push);
                L2 = Math.min(255, L2 + push);
            } else if (L1> L2) {
                L1 = Math.min(255, L1 + push);
                L2 = Math.max(0, L2 - push);
            } else {
                // L1==L2
                let up = L1 + minDiff;
                if (up>255) up=255;
                L2= up;
            }
        }
        return [lumToHex(L1), lumToHex(L2)];
    }

    //--------------------------------------------------------------------------
    // B) Window_Base.drawGauge の上書き => バトル画面などがcolorで戻るのを防ぐ
    //--------------------------------------------------------------------------
    const _Window_Base_drawGauge = Window_Base.prototype.drawGauge;
    Window_Base.prototype.drawGauge = function(x, y, width, rate, color1, color2) {
        // minDiff=80などで白黒化
        const [g1, g2] = grayscaleWithMinDiff(color1, color2, 80);
        _Window_Base_drawGauge.call(this, x, y, width, rate, g1, g2);
    };

    //--------------------------------------------------------------------------
    // C) Sprite_Gauge.drawGaugeRect の上書き => メニュー画面などに対応
    //--------------------------------------------------------------------------
    if (typeof Sprite_Gauge !== "undefined") {
        const _Sprite_Gauge_drawGaugeRect = Sprite_Gauge.prototype.drawGaugeRect;
        Sprite_Gauge.prototype.drawGaugeRect = function(x, y, w, h) {
            // gaugeBackColorは元の色(背景) => そのままでOK or グレースケールしてもOK
            // color1, color2
            const c1 = this.gaugeColor1();
            const c2 = this.gaugeColor2();

            const [g1, g2] = grayscaleWithMinDiff(c1, c2, 80);

            // fillRect(背景色) は元のまま
            const fillW = Math.floor(w * this.gaugeRate());
            this.bitmap.fillRect(x, y, w, h, this.gaugeBackColor());

            // gradientFillRect => g1, g2
            this.bitmap.gradientFillRect(x, y, fillW, h, g1, g2, false);
        };
    }

})();
