// DarkPlasma_Promise_EquipLayout 1.0.3
// Copyright (c) 2020 DarkPlasma

/**
 * 2021/08/01 1.0.3 装備効果が4つまでしか表示されない不具合を修正
 * 2020/10/12 1.0.2 アクター切り替え時に前のアクターのHPMP表示が残る不具合を修正
 * 2020/09/08 1.0.1 rollup構成へ移行
 * 2020/09/01 1.0.0 初回
 */

/*:ja
 * @plugindesc 装備画面レイアウトを変更する
 * @author DarkPlasma
 * @license No License
 *
 * @target MZ
 *
 * @base DarkPlasma_ParameterText
 *
 * @help
 * version: 1.0.3
 * 装備画面レイアウトをいい感じにします。
 */

(() => {
  'use strict';

  /**
   * 命中率、回避率、会心率、魔法回避率、魔法反射率
   */
  const XPARAM_IDS = [0, 1, 2, 4, 5];

  const _Scene_Equip_create = Scene_Equip.prototype.create;
  Scene_Equip.prototype.create = function () {
    _Scene_Equip_create.call(this);
    this.createEffectWindow();
  };

  Scene_Equip.prototype.createEffectWindow = function () {
    this._effectWindow = new Window_EquipEffect(this.effectWindowRect());
    this._slotWindow.setEffectWindow(this._effectWindow);
    this._itemWindow.setEffectWindow(this._effectWindow);
    this.addWindow(this._effectWindow);
  };

  Scene_Equip.prototype.effectWindowRect = function () {
    const commandWindowRect = this.commandWindowRect();
    const slotWindowRect = this.slotWindowRect();
    const wx = this.statusWidth();
    const wy = slotWindowRect.y + slotWindowRect.height;
    const ww = Graphics.boxWidth - this.statusWidth();
    const wh = this.mainAreaHeight() - slotWindowRect.height - commandWindowRect.height;
    return new Rectangle(wx, wy, ww, wh);
  };

  Scene_Equip.prototype.statusWidth = function () {
    return 412;
  };

  Scene_Equip.prototype.slotWindowRect = function () {
    const commandWindowRect = this.commandWindowRect();
    const wx = this.statusWidth();
    const wy = commandWindowRect.y + commandWindowRect.height;
    const ww = Graphics.boxWidth - this.statusWidth();
    const wh = this.calcWindowHeight(6, true);
    return new Rectangle(wx, wy, ww, wh);
  };

  class EquipEffectText {
    constructor(paramName, number) {
      this._paramName = paramName;
      this._number = number;
    }

    get paramName() {
      return this._paramName;
    }

    get number() {
      return this._number;
    }
  }

  class Window_EquipEffect extends Window_Base {
    /**
     * @param {MZ.Weapon|MZ.Armor} item 武器防具データ
     */
    setItem(item) {
      if (this._item !== item) {
        this._item = item;
        this.drawItemEffect();
      }
    }

    drawItemEffect() {
      this.contents.clear();
      if (this._item === null || this._item === undefined) {
        return;
      }
      this.effectTexts().forEach((effectText, index) => {
        this.changeTextColor(ColorManager.systemColor());
        this.drawText(effectText.paramName, this.textX(index), this.textY(index), this.paramNameWidth());
        this.changeTextColor(ColorManager.paramchangeTextColor(effectText.number));
        this.drawText(
          effectText.number > 0 ? `+${effectText.number}` : effectText.number,
          this.textX(index) + this.paramNameWidth(),
          this.textY(index),
          this.textWidth('0000'),
          'right'
        );
      });
    }

    paramNameWidth() {
      return this.textWidth('魔法回避 ');
    }

    /**
     * @param {number} index インデックス
     * @return {number}
     */
    textX(index) {
      return (index % 2) * (this.paramNameWidth() + this.textWidth('0000') + this.itemPadding());
    }

    /**
     * @param {number} index インデックス
     * @return {number}
     */
    textY(index) {
      return Math.floor(index / 2) * this.lineHeight();
    }

    /**
     * @return {EquipEffectText[]}
     */
    effectTexts() {
      return Array.from(Array(8).keys())
        .map((index) => {
          return new EquipEffectText(TextManager.param(index), this._item.params[index]);
        })
        .concat(
          XPARAM_IDS.map((paramId) => {
            return new EquipEffectText(
              TextManager.xparam(paramId),
              Math.round(
                this._item.traits
                  .filter((trait) => {
                    return trait.code === Game_BattlerBase.TRAIT_XPARAM && trait.dataId === paramId;
                  })
                  .reduce((a, b) => a + b.value, 0) * 100
              )
            );
          })
        )
        .filter((effectText) => effectText.number !== 0);
    }
  }

  const _Window_EquipStatus_refresh = Window_EquipStatus.prototype.refresh;
  Window_EquipStatus.prototype.refresh = function () {
    this.hideAdditionalSprites();
    _Window_EquipStatus_refresh.call(this);
    if (this._tempActor) {
      const lineHeight = this.lineHeight();
      const x = this.paramX() + this.paramWidth() + this.itemPadding() * 3;
      this.drawActorLevel(this._tempActor, x, lineHeight);
      this.placeBasicGauges(this._tempActor, x, lineHeight * 2);
    } else if (this._actor) {
      const lineHeight = this.lineHeight();
      const x = this.paramX() + this.paramWidth() + this.itemPadding() * 3;
      this.drawActorLevel(this._actor, x, lineHeight);
      this.placeBasicGauges(this._actor, x, lineHeight * 2);
    }
  };

  const _Window_EquipStatus_drawAllParams = Window_EquipStatus.prototype.drawAllParams;
  Window_EquipStatus.prototype.drawAllParams = function () {
    _Window_EquipStatus_drawAllParams.call(this);
    XPARAM_IDS.forEach((paramId, index) => {
      const x = this.itemPadding();
      const y = this.paramY(index);
      this.drawExtraItem(x, y, paramId);
    });
  };

  Window_EquipStatus.prototype.drawItem = function (x, y, paramId) {
    const paramX = this.paramX();
    this.drawParamName(x, y, paramId);
    if (this._tempActor) {
      this.drawNewParam(paramX, y, paramId);
    } else if (this._actor) {
      this.drawCurrentParam(paramX, y, paramId);
    }
  };

  Window_EquipStatus.prototype.drawExtraItem = function (x, y, paramId) {
    const paramX = this.paramX();
    const paramWidth = this.paramWidth();
    const extraParamX = this.extraParamX();
    this.drawExtraParamName(paramX + paramWidth + this.itemPadding() * 3, y, paramId);
    if (this._tempActor) {
      this.drawNewExtraParam(extraParamX, y, paramId);
    } else if (this._actor) {
      this.drawCurrentExtraParam(extraParamX, y, paramId);
    }
  };

  Window_EquipStatus.prototype.drawParamName = function (x, y, paramId) {
    const width = this.paramX() - this.itemPadding() * 2;
    this.changeTextColor(ColorManager.systemColor());
    this.drawText(TextManager.param(paramId), x, y, width);
  };

  Window_EquipStatus.prototype.drawExtraParamName = function (x, y, paramId) {
    const width = this.extraParamX() - this.itemPadding() * 2;
    this.changeTextColor(ColorManager.systemColor());
    this.drawText(TextManager.xparam(paramId), x, y, width);
  };

  /**
   * 命中率、回避率、会心率、魔法回避率、魔法反射率を表示する
   */
  Window_EquipStatus.prototype.drawCurrentExtraParam = function (x, y, paramId) {
    const paramWidth = this.paramWidth();
    this.resetTextColor();
    this.drawText(Math.round(this._actor.xparam(paramId) * 100), x, y, paramWidth, 'right');
  };

  /**
   * 命中率、回避率、会心率、魔法回避率、魔法反射率を表示する
   */
  Window_EquipStatus.prototype.drawNewExtraParam = function (x, y, paramId) {
    const paramWidth = this.paramWidth();
    const newValue = this._tempActor.xparam(paramId);
    const diffvalue = newValue - this._actor.xparam(paramId);
    this.changeTextColor(ColorManager.paramchangeTextColor(diffvalue));
    this.drawText(Math.round(newValue * 100), x, y, paramWidth, 'right');
  };

  Window_EquipStatus.prototype.paramX = function () {
    const itemPadding = this.itemPadding();
    const paramWidth = this.paramWidth();
    const offsetX = -20;
    return this.innerWidth / 2 - itemPadding - paramWidth + offsetX;
  };

  Window_EquipStatus.prototype.extraParamX = function () {
    const itemPadding = this.itemPadding();
    const paramWidth = this.paramWidth();
    return this.innerWidth - itemPadding - paramWidth;
  };

  Window_EquipSlot.prototype.slotNameWidth = function () {
    return this.textWidth('装飾品 ');
  };

  Window_EquipSlot.prototype.setEffectWindow = function (effectWindow) {
    this._effectWindow = effectWindow;
  };

  const _Window_EquipSlot_updateHelp = Window_EquipSlot.prototype.updateHelp;
  Window_EquipSlot.prototype.updateHelp = function () {
    _Window_EquipSlot_updateHelp.call(this);
    if (this._effectWindow) {
      this._effectWindow.setItem(this.item());
    }
  };

  Window_EquipItem.prototype.setEffectWindow = function (effectWindow) {
    this._effectWindow = effectWindow;
  };

  const _Window_EquipItem_updateHelp = Window_EquipItem.prototype.updateHelp;
  Window_EquipItem.prototype.updateHelp = function () {
    _Window_EquipItem_updateHelp.call(this);
    if (this._actor && this._effectWindow && this._slotId >= 0) {
      this._effectWindow.setItem(this.item());
    }
  };
})();
