/*:
* @target MZ
* @plugindesc v1.0.0 This plugin helps you to show text on the screen by using the plugin command. 
* Can be used for questing, notification, etc.
* @author Sang Hendrix & Chat GPT
*
* @command ShowText
* @text Show Text
* @desc Show text on the screen
*
* @arg text
* @type multiline_string
* @text Text
* @desc The text to be shown
*
* @arg x
* @type combo
* @option center
* @option custom
* @text X position
* @desc The X position of the text. Default: center
*
* @arg y
* @type number
* @min -9999
* @text Y position
* @desc The Y position of the text.
*
* @arg sfx
* @type file
* @dir audio/se/
* @text SFX
* @desc The SFX to play when the text is shown
*
* @arg sfxVolume
* @type number
* @min 0
* @max 100
* @default 70
* @text SFX Volume
* @desc SFX Volume
*
* @arg sfxPitch
* @type number
* @min 50
* @max 150
* @default 100
* @text SFX Pitch
* @desc SFX Pitch
*
* @arg fontSize
* @type number
* @min 1
* @default 28
* @text Font Size
* @desc Font size
*
* @arg fontFace
* @type string
* @default GameFont
* @text Font Namne
* @desc Font Name
*
* @arg textColor
* @type string
* @default #FFFFFF
* @text Color
* @desc Text color in hex code
*
* @arg outlineEnabled
* @type boolean
* @default true
* @text Show Outline
* @desc Choose whether or not to show outline
*
* @arg outlineColor
* @type string
* @default #000000
* @text Outline Color
* @desc Outline Color
*
* @arg duration
* @type number
* @min 1
* @default 5000
* @text Text Duration
* @desc The time of the text to show in millisecond.
*
* @arg fadeInDuration
* @type number
* @min 1
* @default 1000
* @text Fade in Duration
* @desc The time for the text to fade in in millisecond.
*
* @arg fadeDuration
* @type number
* @min 1
* @default 1000
* @text Fade out Duration
* @desc The time for the text to fade out in millisecond.
*/

(() => {
    class ShowTextSprite extends Sprite {
        constructor(text, x, y, fontSize, fontFace, textColor, outlineEnabled, outlineColor, duration, fadeInDuration, fadeDuration, sfx, sfxVolume, sfxPitch) {
            super();
            this.bitmap = new Bitmap(Graphics.width, Graphics.height);
            this._text = text;
            this._x = x;
            this._y = y;
            this._fontSize = fontSize;
            this._fontFace = fontFace;
            this._textColor = textColor;
            this._outlineEnabled = outlineEnabled;
            this._outlineColor = outlineColor;

            this.z = 100;
            this.refresh();
            this._sfx = sfx;
            this.opacity = 0; // Set initial opacity to 0 for fade in effect

            setTimeout(() => {
                const fadeInInterval = setInterval(() => {
                    this.opacity += 255 / (fadeInDuration / (1000 / 60));
                    if (this.opacity >= 255) {
                        clearInterval(fadeInInterval);
                    }
                }, 1000 / 60); // 60 frames per second
            }, 0);

            setTimeout(() => {
                const fadeOutInterval = setInterval(() => {
                    this.opacity -= 255 / (fadeDuration / (1000 / 60));
                    if (this.opacity <= 0) {
                        clearInterval(fadeOutInterval);
                        SceneManager._scene.removeChild(this);
                    }
                }, 1000 / 60); // 60 frames per second
            }, duration);

            if (this._sfx) {
                const sound = {
                    name: this._sfx,
                    volume: sfxVolume,
                    pitch: sfxPitch,
                    pan: 0
                };
                AudioManager.playSe(sound);
            }
        }

        async refresh() {
            this.bitmap.clear();

            let localizedText = this._text;

            // Replace the variable code with the actual value
            localizedText = localizedText.replace(/\\v\[(\d+)\]/g, (match, p1) => $gameVariables.value(Number(p1)));

            if (typeof DKTools !== 'undefined' && typeof DKTools.Localization !== 'undefined' && typeof DKTools.Localization.Manager !== 'undefined') {
                localizedText = await DKTools.Localization.Manager.localizeAsync(this._text);
            }

            this.bitmap.fontSize = parseInt(this._fontSize);
            this.bitmap.fontFace = this._fontFace;
            this.bitmap.textColor = this._textColor;

            if (this._outlineEnabled) {
                this.bitmap.outlineColor = this._outlineColor;
                this.bitmap.outlineWidth = 3;
            } else {
                this.bitmap.outlineWidth = 0;
            }

            const width = Graphics.width;
            const baseTextX = this._x === 'center' ? (Graphics.width - this.bitmap.measureTextWidth(this._text)) / 2 : parseInt(this._x);
            const y = parseInt(this._y);

            this.bitmap.drawText(localizedText, 0, y, width, Graphics.height, 'center');
        }
    }

    PluginManager.registerCommand("ShowTextOnScreen", "ShowText", async (args) => {
        const { text, x, y, fontSize, fontFace, textColor, outlineEnabled, outlineColor, duration, fadeInDuration, fadeDuration, sfx, sfxVolume, sfxPitch } = args;
        const newTextSprite = new ShowTextSprite(text, x, parseInt(y), parseInt(fontSize), fontFace, textColor, outlineEnabled === "true", outlineColor, parseInt(duration), parseInt(fadeInDuration), parseInt(fadeDuration), sfx, parseInt(sfxVolume), parseInt(sfxPitch));
        await newTextSprite.refresh();
        SceneManager._scene.addChild(newTextSprite);
    });


})();
