'use strict';
/*:
@plugindesc Display enemy actions in combat
@help
This works with turn based battle systems where enemy actions are
selected at the start of the turn.

The X and Y adjustments may be helpful to get out of the way of other
plugins that draw things above the heads of enemy sprites.

Note tags:
On an enemy, use the telepathy note tag to turn action display on or off.
The value is evaluated and actions are displayed if it returns a true value.
<telepathy:true> - display actions for this enemy
<telepathy:false> - do not display actions for this enemy
<telepathy:$gameSwitches.switch(1)> - display only if switch 1 is on

1.0: original release
2.0: configurable screen border for Luna MV compatibility
     documented dependency on YEP_BattleEngineCore
3.0: Rewritten to depend only on core scripts.
     Added window background option
     Added dynamic positioning to avoid state icons only when needed

@author Coelocanth

@param FontSize
@desc Font size to use for displaying enemy action
@type Number
@default 24

@param X
@desc Horizontal offset for the action display
@type Number
@default 0

@param Y
@desc Vertical offset for the action display
@type Number
@default 0

@param StateAdjustX
@desc Horizontal offset when afflicted by states with icons
@type Number
@default 0

@param StateAdjustY
@desc Vertical offset when afflicted by states with icons
@type Number
@default -32

@param ShowDefault
@desc Should enemy actions be shown by default?
@type boolean
@default true

@param ShowState
@desc Show enemy action if affected by this state
@type Number
@default 0

@param HideState
@desc Hide enemy action if affected by this state
@type Number
@default 0

@param ScreenBorderLeft
@desc Do not draw left of this point, to avoid collision with HUD elements
@type Number
@default 0

@param ScreenBorderRight
@desc Do not draw right of this point, to avoid collision with HUD elements
@type Number
@default 0

@param ScreenBorderTop
@desc Do not draw above of this point, to avoid collision with HUD elements
@type Number
@default 0

@param ScreenBorderBottom
@desc Do not draw below of this point, to avoid collision with HUD elements
@type Number
@default 0

@param WindowBackground
@desc Type of background for enemy action window, like "show text" command
The "dim" option may be helpful if text is hard to read on light battle backs
@type select
@option transparent
@option dim
@option visible
@default transparent
*/
var Imported = Imported || {};
Imported.CC_Telepathy = true;

var CC_Telepathy = {
    params: PluginManager.parameters('CC_Telepathy')
}
CC_Telepathy.params.FontSize = Number(CC_Telepathy.params.FontSize);
CC_Telepathy.params.X = Number(CC_Telepathy.params.X);
CC_Telepathy.params.Y = Number(CC_Telepathy.params.Y);
CC_Telepathy.params.StateAdjustX = Number(CC_Telepathy.params.StateAdjustX);
CC_Telepathy.params.StateAdjustY = Number(CC_Telepathy.params.StateAdjustY);
CC_Telepathy.params.ShowDefault = eval(CC_Telepathy.params.ShowDefault);
CC_Telepathy.params.ShowState = Number(CC_Telepathy.params.ShowState);
CC_Telepathy.params.HideState = Number(CC_Telepathy.params.HideState);
CC_Telepathy.params.ScreenBorderLeft = Number(CC_Telepathy.params.ScreenBorderLeft);
CC_Telepathy.params.ScreenBorderRight = Number(CC_Telepathy.params.ScreenBorderRight);
CC_Telepathy.params.ScreenBorderTop = Number(CC_Telepathy.params.ScreenBorderTop);
CC_Telepathy.params.ScreenBorderBottom = Number(CC_Telepathy.params.ScreenBorderBottom);
if(CC_Telepathy.params.WindowBackground == 'visible') {
    CC_Telepathy.params.WindowBackgroundType = 0;
} else if(CC_Telepathy.params.WindowBackground == 'dim') {
    CC_Telepathy.params.WindowBackgroundType = 1;
} else {
    CC_Telepathy.params.WindowBackgroundType = 2;
}

(function() {
    // Window_Telepathy observes a battler and displays its next action
    function Window_Telepathy() {
        this.initialize.apply(this, arguments);
    }
    
    Window_Telepathy.prototype = Object.create(Window_Base.prototype);
    Window_Telepathy.prototype.constructor = Window_Telepathy;

    Window_Telepathy.prototype.initialize = function(sprite, battler) {
        Window_Base.prototype.initialize.call(this, 0,0,0,0);
        this._sprite = sprite;
        this.setBattler(battler);
    }

    Window_Telepathy.prototype.setBattler = function(battler) {
        this._battler = battler;
        this._icon = 0;
        this._text = "";
        this.update();
    }

    Window_Telepathy.prototype.update = function() {
        Window_Base.prototype.update.call(this);
        this.updateParent();
        this.updateContents();
        this.updatePosition();
        this.updateOpacity();
    }

    Window_Telepathy.prototype.updateParent = function() {
        // Reparent to the scene as soon as it's set
        if(this._sprite && this._sprite.parent && this.parent !== this._sprite.parent) {
            this._sprite.removeChild(this);
            this._sprite.parent.addChild(this);
            this.calculateBoundingBox();
        }
    }

    Window_Telepathy.prototype.updateContents = function() {
        if(!this._battler) return;
        let action = this._battler.numActions() ? this._battler.action(0) : null;
        var icon = 0;
        var text = "";
        if(action) {
            let dbitem = action.item();
            icon = dbitem.iconIndex;
            text = dbitem.name;
        }
        if(icon == this._icon && text == this._text) return;
        // action has changed, need to redraw
        this._icon = icon;
        this._text = text;
        this.width = this.fittingWidth(text);
        this.height = this.fittingHeight(1);
        this.createContents();
        this.contents.fontSize = CC_Telepathy.params.FontSize;
        this.setBackgroundType(CC_Telepathy.params.WindowBackgroundType);
        this.drawIcon(icon, 0, 2);
        this.drawText(text, Window_Base._iconWidth + 4, 0);
        this.calculateBoundingBox();
    }

    Window_Telepathy.prototype.calculateBoundingBox = function() {
        this._minX = -1 * this.standardPadding();
        this._maxX = Graphics.boxWidth - this.width + this.standardPadding();
        this._minY = -1 * this.standardPadding();
        this._maxY = Graphics.boxHeight - this.height + this.standardPadding();
        this._minY += CC_Telepathy.params.ScreenBorderTop;
        this._maxY -= CC_Telepathy.params.ScreenBorderBottom;
        this._minX += CC_Telepathy.params.ScreenBorderLeft;
        this._maxX -= CC_Telepathy.params.ScreenBorderRight;    
    }

    // icon + text + padding
    Window_Telepathy.prototype.fittingWidth = function(text) {
        return this.textWidth(text) + this.standardPadding() * 2 + Window_Base._iconWidth + 4;
    }

    Window_Telepathy.prototype.updatePosition = function() {
        if(!this._sprite) return;
        var x = this._sprite.x - this.width / 2;
        var y = this._sprite.y - this._sprite.height * this._sprite.anchor.y - this.height;
        x += CC_Telepathy.params.X;
        y += CC_Telepathy.params.Y;
        // move out of the way of visible state icons
        if(this._battler.stateIcons().length || this._battler.buffIcons().length) {
            x += CC_Telepathy.params.StateAdjustX;
            y += CC_Telepathy.params.StateAdjustY;
        }
        this.x = x.clamp(this._minX, this._maxX);
        this.y = y.clamp(this._minY, this._maxY);
    }

    Window_Telepathy.prototype.isTelepathyActive = function() {
        if (!this._battler || this._battler.isDead()) {
            return false;
        }
        if (CC_Telepathy.params.ShowState && this._battler.isStateAffected(CC_Telepathy.params.ShowState)) {
            return true;
        }
        if (CC_Telepathy.params.HideState && this._battler.isStateAffected(CC_Telepathy.params.HideState)) {
            return false;
        }
        if (this._battler.isEnemy()) {
            var enemy = this._battler.enemy();
            if(enemy.meta.telepathy !== undefined) {
                return eval(enemy.meta.telepathy);
            }
        }
        return CC_Telepathy.params.ShowDefault;    
    }

    // fade in/out like map name window
    Window_Telepathy.prototype.updateOpacity = function() {
        if (this.isTelepathyActive() && this._text) {
            this.contentsOpacity += 16;
        } else {
            this.contentsOpacity -= 32;
        }
    };

    Window_Telepathy.prototype.updateBackgroundDimmer = function() {
        if (this._dimmerSprite) {
            this._dimmerSprite.opacity = this.contentsOpacity;
        }
    }
    
    // Sprite_Enemy is parasited to attach the window
    let cct_Sprite_Enemy_setBattler = Sprite_Enemy.prototype.setBattler;
    Sprite_Enemy.prototype.setBattler = function(battler) {
        cct_Sprite_Enemy_setBattler.call(this, battler);
        if(!this._cct_window) {
            this._cct_window = new Window_Telepathy(this, battler);
            this.addChild(this._cct_window);
        } else {
            this._cct_window.setBattler(battler);
        }
    }
})();