(() => {
    "use strict";
    const P = PluginManager.parameters("zz_textfit");
    const DLG = Number(P.dlgDefault || 28), UI = Number(P.uiDefault || 24);
    const STEP = 2;
    const S_DLG = "ruDlgFont", S_UI = "ruUiFont";
    const RANGE = { [S_DLG]: [18, 40], [S_UI]: [16, 30] };
    const isFont = s => s === S_DLG || s === S_UI;
    const defOf = s => (s === S_DLG ? DLG : UI);

    ConfigManager.ruDlgFont = DLG;
    ConfigManager.ruUiFont = UI;
    const _make = ConfigManager.makeData;
    ConfigManager.makeData = function() {
        const c = _make.call(this); c.ruDlgFont = this.ruDlgFont; c.ruUiFont = this.ruUiFont; return c;
    };
    const _apply = ConfigManager.applyData;
    ConfigManager.applyData = function(c) {
        _apply.call(this, c);
        const f = (v, d) => { v = Number(v); return (isFinite(v) && v >= 12 && v <= 48) ? v : d; };
        this.ruDlgFont = f(c.ruDlgFont, DLG);
        this.ruUiFont = f(c.ruUiFont, UI);
    };

    Window_Base.prototype.ruFontSize = function() { return ConfigManager.ruUiFont || UI; };
    Window_Message.prototype.ruFontSize = function() { return ConfigManager.ruDlgFont || DLG; };
    if (window.Window_ChoiceList) Window_ChoiceList.prototype.ruFontSize = function() { return ConfigManager.ruDlgFont || DLG; };
    if (window.Window_ScrollText) Window_ScrollText.prototype.ruFontSize = function() { return ConfigManager.ruDlgFont || DLG; };
    Window_Options.prototype.ruFontSize = function() { return 24; };

    const _reset = Window_Base.prototype.resetFontSettings;
    Window_Base.prototype.resetFontSettings = function() {
        _reset.call(this);
        if (this.contents) this.contents.fontSize = this.ruFontSize();
    };
    Window_Base.prototype.lineHeight = function() { return Math.round(this.ruFontSize() * 1.42); };

    const _addGen = Window_Options.prototype.addGeneralOptions;
    Window_Options.prototype.addGeneralOptions = function() {
        _addGen.call(this);
        this.addCommand("Текст диалогов", S_DLG);
        this.addCommand("Текст меню", S_UI);
    };

    function barGeom(self, index) {
        const rect = self.itemLineRect(index);
        const titleW = self.textWidth(self.commandName(index)) + 16;
        const valW = 58;
        const barX = rect.x + titleW;
        const barW = Math.max(60, rect.width - titleW - valW - 8);
        const barY = rect.y + Math.round(rect.height / 2) - 4;
        return { rect, barX, barY, barW, barH: 8, valW, titleW };
    }
    function valToFrac(sym, v) { const [mn, mx] = RANGE[sym]; return (v - mn) / (mx - mn); }

    const _drawItem = Window_Options.prototype.drawItem;
    Window_Options.prototype.drawItem = function(index) {
        const sym = this.commandSymbol(index);
        if (!isFont(sym)) return _drawItem.call(this, index);
        const g = barGeom(this, index);
        const val = this.getConfigValue(sym) || defOf(sym);
        this.resetTextColor();
        this.drawText(this.commandName(index), g.rect.x, g.rect.y, g.titleW - 16, "left");
        const c = this.contents, y = g.barY, h = g.barH;
        c.fillRect(g.barX, y, g.barW, h, "rgba(255,255,255,0.25)");
        const f = Math.max(0, Math.min(1, valToFrac(sym, val)));
        c.fillRect(g.barX, y, Math.round(g.barW * f), h, ColorManager.textColor(4) || "#88ccff");
        const kx = g.barX + Math.round(g.barW * f);
        c.fillRect(kx - 3, y - 6, 6, h + 12, "#ffffff");
        this.drawText(val + " px", g.barX + g.barW + 8, g.rect.y, g.valW, "right");
    };

    function setFromTouch(self, index, sym) {
        const g = barGeom(self, index);
        const p = self.worldTransform.applyInverse(new Point(TouchInput.x, TouchInput.y));
        const localX = p.x - self.padding;
        let f = (localX - g.barX) / g.barW;
        f = Math.max(0, Math.min(1, f));
        const [mn, mx] = RANGE[sym];
        let v = mn + Math.round((f * (mx - mn)) / STEP) * STEP;
        v = Math.max(mn, Math.min(mx, v));
        if (v !== (self.getConfigValue(sym) || defOf(sym))) {
            ConfigManager[sym] = v;
            self.redrawItem(index);
        }
    }

    const _processTouch = Window_Options.prototype.processTouch;
    Window_Options.prototype.processTouch = function() {
        if (this.isOpenAndActive()) {
            if (TouchInput.isPressed() || TouchInput.isTriggered()) {
                const hi = this.hitIndex();
                if (hi >= 0 && isFont(this.commandSymbol(hi))) {
                    this.select(hi);
                    setFromTouch(this, hi, this.commandSymbol(hi));
                    this._fontDragging = true;
                    return;
                }
            }
            if (TouchInput.isReleased() && this._fontDragging) {
                this._fontDragging = false;
                return;
            }
        }
        _processTouch.call(this);
    };

    function stepKey(self, sym, dir) {
        const [mn, mx] = RANGE[sym];
        let v = (self.getConfigValue(sym) || defOf(sym)) + dir * STEP;
        if (v > mx) v = mn; if (v < mn) v = mx;
        self.changeValue(sym, v);
    }
    const _ok = Window_Options.prototype.processOk;
    Window_Options.prototype.processOk = function() {
        const s = this.commandSymbol(this.index());
        if (isFont(s)) { stepKey(this, s, 1); return; }
        _ok.call(this);
    };
    const _cr = Window_Options.prototype.cursorRight;
    Window_Options.prototype.cursorRight = function() {
        const s = this.commandSymbol(this.index());
        if (isFont(s)) { stepKey(this, s, 1); return; }
        _cr.call(this);
    };
    const _cl = Window_Options.prototype.cursorLeft;
    Window_Options.prototype.cursorLeft = function() {
        const s = this.commandSymbol(this.index());
        if (isFont(s)) { stepKey(this, s, -1); return; }
        _cl.call(this);
    };
})();
