/*:
 * @target MZ
 * @plugindesc Auto-scrolls help window text when it's too long to fit
 * @author GitHub Copilot
 * @url https://github.com/
 *
 * @param scrollSpeed
 * @text Scroll Speed
 * @desc Speed of auto-scroll in pixels per frame (default: 0.5)
 * @type number
 * @decimals 2
 * @default 0.5
 *
 * @param pauseAtTop
 * @text Pause At Top
 * @desc Frames to pause when at top before scrolling (default: 90)
 * @type number
 * @default 90
 *
 * @param pauseAtBottom
 * @text Pause At Bottom
 * @desc Frames to pause when scrolled to bottom (default: 90)
 * @type number
 * @default 90
 *
 * @help AutoScrollHelpWindow.js
 *
 * This plugin automatically scrolls the help window text when it's too long
 * to fit in the window. This is particularly useful for passive skill
 * descriptions in the body history menu.
 *
 * No plugin commands needed - it works automatically!
 */

(() => {
    'use strict';

    const pluginName = 'AutoScrollHelpWindow';
    const parameters = PluginManager.parameters(pluginName);
    const scrollSpeed = Number(parameters['scrollSpeed'] || 0.5);
    const pauseAtTop = Number(parameters['pauseAtTop'] || 90);
    const pauseAtBottom = Number(parameters['pauseAtBottom'] || 90);

    //-----------------------------------------------------------------------------
    // Window_Help
    //-----------------------------------------------------------------------------

    const _Window_Help_initialize = Window_Help.prototype.initialize;
    Window_Help.prototype.initialize = function(rect) {
        _Window_Help_initialize.call(this, rect);
        this._scrollData = {
            y: 0,
            timer: pauseAtTop,
            state: 'waiting',
            maxScroll: 0,
            enabled: false
        };
        this._baseContentsHeight = this.contents.height;
    };

    const _Window_Help_setText = Window_Help.prototype.setText;
    Window_Help.prototype.setText = function(text) {
        const changed = (this._text !== text);
        _Window_Help_setText.call(this, text);
        if (changed) {
            this._scrollData.y = 0;
            this._scrollData.timer = pauseAtTop;
            this._scrollData.state = 'waiting';
            this.origin.y = 0;
        }
    };

    // Call original refresh, then setup scrolling after
    const _Window_Help_refresh = Window_Help.prototype.refresh;
    Window_Help.prototype.refresh = function() {
        // Measure text first
        const textSize = this._text ? this.textSizeEx(this._text) : { width: 0, height: 0 };
        const neededHeight = textSize.height + 16;
        
        // Ensure contents is big enough
        if (neededHeight > this.contents.height) {
            this.contents.resize(this.contents.width, neededHeight);
        }
        
        // Call original refresh (clears and draws)
        _Window_Help_refresh.call(this);
        
        // Setup scroll parameters
        const rect = this.baseTextRect();
        this._scrollData.maxScroll = Math.max(0, textSize.height - rect.height);
        this._scrollData.enabled = this._scrollData.maxScroll > 2;
    };

    const _Window_Help_update = Window_Help.prototype.update;
    Window_Help.prototype.update = function() {
        _Window_Help_update.call(this);
        this.updateAutoScroll();
    };

    Window_Help.prototype.updateAutoScroll = function() {
        const s = this._scrollData;
        if (!s || !s.enabled) {
            if (this.origin.y !== 0) this.origin.y = 0;
            return;
        }

        switch (s.state) {
            case 'waiting':
                if (--s.timer <= 0) s.state = 'down';
                break;
            case 'down':
                s.y = Math.min(s.y + scrollSpeed, s.maxScroll);
                this.origin.y = Math.floor(s.y);
                if (s.y >= s.maxScroll) {
                    s.state = 'paused';
                    s.timer = pauseAtBottom;
                }
                break;
            case 'paused':
                if (--s.timer <= 0) s.state = 'up';
                break;
            case 'up':
                s.y = Math.max(s.y - scrollSpeed * 2, 0);
                this.origin.y = Math.floor(s.y);
                if (s.y <= 0) {
                    s.state = 'waiting';
                    s.timer = pauseAtTop;
                }
                break;
        }
    };

})();
