//=============================================================================
// RPG Maker MZ - CustomChoiceList
//
// Copyright 2024 Panzer-IV. All rights reserved.
// This source code or any portion thereof must not be
// reproduced or used without licensed in any manner whatsoever.
//=============================================================================
/*:
 * @target MZ
 * @plugindesc 選択肢UI
 * @author 四号戦車
 * @base PluginCommonBase
 * @orderAfter PluginCommonBase
 * @base AsyncLoadImage
 * @orderAfter PluginCommonBase
 * @orderAfter DebugSwitch
 * @orderAfter AsyncLoadImage
 *
 * @help CustomChoiceList.js
 *
 * Version: 0.0.2
 *
 * 選択肢UI変更プラグインです。
 *
 * @requiredAssets img/system/choice_bg_active
 * @requiredAssets img/system/choice_bg_normal
 *
 */
(() => {
	"use strict";

    const pluginName = "CustomChoiceList";
    const script = document.currentScript;
    const param  = PluginManagerEx.createParameter(script);

    const UNSELECTED_TEXT_COLOR = '#A1A1A1';

    /********************************************************************************************************
     * 共有基盤
     ********************************************************************************************************/
    const log = (text) => {
        if (DebugSwitch.isEnable()) {
            console.log(text);
        }
    };

    /********************************************************************************************************
     * クラス拡張
     ********************************************************************************************************/
    const CHOICE_SPACING = 30;

    class Window_CustomChoiceList extends Window_ChoiceList {
        constructor(top, commands, onSetup) {
            super();

            const empty = new Bitmap(1, 1);
            this.bgImage = empty;
            this.bgImageActive = empty;

            this.commands = commands;
            this.cancellable = true;
            this.autoHeightPlacement = false;
            this.placementTop = top;

            const bg = ImageManager.loadSystemAsync('choice_bg_normal');
            const bgActive = ImageManager.loadSystemAsync('choice_bg_active');

            const loaded = array => {
                this.bgImage = array[0];
                this.bgImageActive = array[1];
                log('choice list bg loaded');
                this.refresh();

                if (!!onSetup && typeof onSetup === 'function') {
                    onSetup(this);
                }
            };
            Promise.all([ bg, bgActive ]).then(loaded.bind(this));
            this.cursorVisible = false;
        }

        itemWidth() {
            if (!!this.bgImage) {
                return this.bgImage.width;
            } else {
                return 96;
            }
        }

        itemHeight() {
            if (!!this.bgImage) {
                return this.bgImage.height + CHOICE_SPACING;
            } else {
                return 194;
            }
        }

        colSpacing() {
            return 0;
        }

        rowSpacing() {
            return CHOICE_SPACING;
        }

        start() {
            this.refresh();
            super.start();
        }

        drawItemBackground(index) {
            const rect = this.itemRect(index);
            log(`drawItemBackground: index = ${index}, x = ${rect.x}, y = ${rect.y}, width = ${rect.width}, height = ${rect.height}`);

            const enabled = !this.commands || this.commands[index].enabled;
            const bitmap =  (index === this._index && enabled) ? this.bgImageActive : this.bgImage;

            if (!!bitmap) {

                this.contentsBack.fontSize = 38;
                this.contentsBack.clearRect(rect.x, rect.y, rect.width, rect.height);
                this.contentsBack.paintOpacity = enabled ? 255 : PluginUtils.percent(255, 60);
                this.contentsBack.blt(bitmap, 0, 0, bitmap.width, bitmap.height,
                     rect.x, rect.y, rect.width, rect.height);
            }
        }

        setHeightPlacement(auto) {
            this.autoHeightPlacement = true;
        }

        //========================================================================
        // 親クラスの処理変更・抑止したい系
        //========================================================================
        updatePlacement() {
            this.width = this.windowWidth();
            this.height = this.windowHeight();

            this.x = (Graphics.width - this.width) / 2;
            if (this.autoHeightPlacement === false) {
                this.y = (Graphics.height - this.height) / 2;
            } else {
                this.y = this.placementTop;
            }
        }

        loadWindowskin() {
            this.windowskin = new Bitmap(this.width, this.height);
        }

        updatePadding() {
            this.padding = 0;
        }

        updateBackOpacity() {
            this.backOpacity = 256;
        }

        contentsWidth() {
            return this.width;
        }

        contentsHeight() {
            return this.height;
        }

        selectDefault() {
            log(`selectDefault`);
            if (!!this.commands) {
                this.select(0);
            } else {
                super.selectDefault();
            }
        }

        updateBackground() {
            // DO NOTHING
            log(`updateBackGround`);
        }

        select(index) {
            super.select(index);
            this.paint();
            log(`select: index = ${index}`);
        }

        windowY() {
            return this.y;
        }

        callOkHandler() {
            if (!!this.commands) {
                log(`callOkHandler: index = ${this._index}`);
                const command = this.commands[this._index];
                if (!!command.ext && typeof command.ext === 'function') {
                    command.ext(this._index);
                }
            } else {
                super.callOkHandler();
            }
        }

        callCancelHandler() {
            if (!!this.commands) {
                SceneManager.pop();
            } else {
                super.callCancelHandler();
            }
        }

        makeCommandList() {
            if (!!this.commands) {
                for (const command of this.commands) {
                    this.addCommand(command.name, command.symbol, command.enabled, command.ext);
                }
            } else {
                super.makeCommandList();
            }
            this.updatePlacement();
        }

        drawText(text, x, y, maxWidth, align) {
            this.contents.outlineWidth = 2;
            this.contents.fontSize = 38;
            this.contents.drawText(text, x, y, maxWidth, this.lineHeight(), align);
        }

        drawItem(index) {
            const rect = this.itemLineRect(index);
            const enabled = !this.commands || this.commands[index].enabled;
            this.contents.paintOpacity = enabled ? 255 : PluginUtils.percent(255, 60);
            this.contents.textColor = (index === this._index && enabled) ? ColorManager.normalColor() : UNSELECTED_TEXT_COLOR;
            this.drawText(this.commandName(index), rect.x, rect.y, rect.width, 'center');
        }

        windowX() {
            const width = this.windowWidth();
            return (Graphics.width - width) / 2;
        }

        windowWidth() {
            return this.maxChoiceWidth();
        }

        fittingHeight(numLines) {
            log(`CustomChoiceList.fittingHeight: numLines = ${numLines}`);
            if (!!this.bgImage) {
                return numLines * this.itemHeight();
            } else {
                return super.fittingHeight(numLines);
            }
        }

        numVisibleRows() {
            if (!!this.commands) {
                const length = this.commands.length;
                return Math.min(length, this.maxLines());
            } else {
                return super.numVisibleRows();
            }
        }

        maxChoiceWidth() {
            if (!!this.bgImage && this.bgImage._loadingState === "loaded") {
                return this.bgImage.width;
            } else {
                return 96;
            }
        }

        setCancellable(enable) {
            this.cancellable = enable;
        }

        isCancelEnabled() {
            return this.cancellable;
        }

        paint() {
            this.contents.clear();
            this.drawAllItems();
        }

        update() {
            super.update();
        }
    }
    window.Window_CustomChoiceList = Window_CustomChoiceList;
})();
