class Window_EffectTest < Window_Selectable
  EFFECT_LIST = [
    :EAXReverb,
    :Reverb,
    :Chorus,
    :Echo,
    :Distortion,
    :Flanger,
    :FrequencyShifter,
    :VocalMorpher,
    :PitchShifter,
    :RingModulator,
    :AutoWah,
    :Compressor,
    :Equalizer,
  ]
  PRESET_LIST = AudioEffects::presets

  def initialize
    super(0, 0, 640, 480)

    self.back_opacity = 230
    self.z = 9998
    self.visible = false
    self.active = false
    @index = 0

    @effect = :none

    @fade_in = false
    @fade_out = false
    @mode = "new effect"

    @var_index = 0
  end

  #==============================================================================
  # * Refresh
  #==============================================================================
  def refresh
    if self.contents != nil
      self.contents.dispose
      self.contents = nil
    end

    if @mode == "new effect"
      @item_max = EFFECT_LIST.size
      self.contents = Bitmap.new(width - 32, @item_max * 32)
      draw_new_effect
    elsif @mode == "preset"
      @item_max = PRESET_LIST.size
      self.contents = Bitmap.new(width - 32, @item_max * 32)
      draw_preset

      self.contents.font.size = 24
      self.contents.draw_text(320, 4, 480, 32, "Press ESC to cancel")
    elsif @mode == "variable"
      @item_max = @effect.instance_variables.size
      self.contents = Bitmap.new(width - 32, @item_max * 32)
      draw_variable

      self.contents.font.size = 24

      if @effect.is_a?(ALEffect::EAXReverb)
        self.contents.draw_text(320, 32, 480, 32, "Press 2 for presets")
      end
      self.contents.draw_text(320, 4, 480, 32, "Press ESC to cancel")
    end
    @item_max -= 1
    @row_max = @item_max
  end

  def draw_new_effect
    self.contents.font.size = 24
    self.contents.draw_text(4, 4, 200, 32, "New Effect")
    self.contents.font.size = 16

    EFFECT_LIST.each_with_index do |effect, i|
      self.contents.draw_text(4, 32 + i * 32, 200, 32, effect.to_s)
    end
  end

  def draw_preset
    self.contents.font.size = 24
    self.contents.draw_text(4, 4, 200, 32, "Preset")
    self.contents.font.size = 16
    PRESET_LIST.each_with_index do |preset, i|
      self.contents.draw_text(4, 32 + i * 32, 200, 32, preset.to_s)
    end
  end

  def draw_variable
    self.contents.font.size = 24
    self.contents.draw_text(4, 4, 480, 32, "#{@effect.class.name.sub(/ALEffect::/, "")} - Settings")
    self.contents.font.size = 16
    @effect.instance_variables.each_with_index do |var, i|
      self.contents.draw_text(4, 32 + i * 32, 480, 32, var.to_s)
      self.contents.draw_text(
        self.contents.text_size(var.to_s).width,
        32 + i * 32, 200, 32, @effect.instance_variable_get(var).to_s, 2
      )
    end
  end

  #==============================================================================
  # * Update
  #==============================================================================
  def update
    super

    # Handle fade-in effect
    if @fade_in
      if Input.trigger?(Input::MENU)
        @fade_in = false
        @fade_out = true
      else
        self.opacity += 48
        self.contents_opacity += 48
        if self.contents_opacity == 255
          @fade_in = false
        end
        return
      end
    end

    # Handle fade-out effect
    if @fade_out
      self.opacity -= 48
      self.contents_opacity -= 48
      if self.contents_opacity == 0
        @fade_out = false
        self.visible = false
        self.active = false
      end
      return
    end

    # Don't do anything if not active
    if !self.active
      return
    end

    if Input.trigger?(Input::ACTION)
      if @mode == "new effect"
        $game_system.se_play($data_system.decision_se)
        @effect = eval("ALEffect::#{EFFECT_LIST[@index]}.new")

        @mode = "variable"
        @index = 0
        self.refresh
        Audio.bgm_set_al_effect(@effect)
      end

      if @mode == "preset"
        $game_system.se_play($data_system.decision_se)
        eval("@effect.load_preset_#{PRESET_LIST[@index]}")
        Audio.bgm_set_al_effect(@effect)
      end
    end

    if @mode == "variable"
      variable = @effect.instance_variable_get(
        @effect.instance_variables[@index]
      )

      case variable.class.name.to_s
      when "Float"
        if Input.repeat?(Input::LEFT)
          if variable < 5.0
            variable -= 0.01
          elsif variable > 100.0
            variable -= 10.0
          elsif variable > 10.0
            variable -= 1.0
          elsif variable > 5.0
            variable -= 0.1
          end
        end
        if Input.repeat?(Input::RIGHT)
          if variable < 5.0
            variable += 0.01
          elsif variable > 100.0
            variable += 10.0
          elsif variable > 10.0
            variable += 1.0
          elsif variable > 5.0
            variable += 0.1
          end
        end
      when "Integer"
        if Input.repeat?(Input::LEFT)
          variable -= 1
        end
        if Input.repeat?(Input::RIGHT)
          variable += 1
        end
      when "TrueClass"
        if Input.trigger?(Input::LEFT) || Input.trigger?(Input::RIGHT) || Input.trigger?(Input::ACTION)
          variable = false
        end
      when "FalseClass"
        if Input.trigger?(Input::LEFT) || Input.trigger?(Input::RIGHT) || Input.trigger?(Input::ACTION)
          variable = true
        end
      when "Array"
        if Input.repeat?(Input::LEFT)
          variable[@var_index] -= 0.01
        end
        if Input.repeat?(Input::RIGHT)
          variable[@var_index] += 0.01
        end
        if Input.trigger?(Input::KEY_K)
          @var_index += 1
          @var_index = 0 if @var_index > variable.size - 1
        end
        if Input.trigger?(Input::KEY_J)
          @var_index -= 1
          @var_index = variable.size - 1 if @var_index < 0
        end
      end
      self.refresh if Input.press?(Input::ACTION) || Input.press?(Input::LEFT) || Input.press?(Input::RIGHT)

      @effect.instance_variable_set(@effect.instance_variables[@index], variable)
      Audio.bgm_set_al_effect(@effect)
    end

    if Input.trigger?(Input::CANCEL)
      @index = 0
      if @mode == "variable"
        Audio.bgm_clear_al_effect
        @mode = "new effect"
        self.refresh
      elsif @mode == "preset"
        @mode = "variable"
        self.refresh
      else
        @fade_out = true
      end
    end

    if Input.trigger?(Input::KEY_2) && @effect.is_a?(ALEffect::EAXReverb)
      @mode = "preset"
      self.refresh
    end

    if Input.trigger?(Input::KEY_3) && @mode != "new effect"
      Audio.bgm_set_al_effect(@effect)
      $game_system.se_play($data_system.decision_se)
    end
  end

  #==============================================================================
  # * Update Cursor Rectangle
  #==============================================================================
  def update_cursor_rect
    # If cursor position is less than 0
    if @index < 0
      self.cursor_rect.empty
      return
    end
    # Get current row
    row = @index / @column_max + 1
    # If current row is before top row
    if row < self.top_row
      # Scroll so that current row becomes top row
      self.top_row = row
      if row == 1
        self.top_row = 0
      end
    end
    # If current row is more to back than back row
    if row > self.top_row + (self.page_row_max - 1)
      # Scroll so that current row becomes back row
      self.top_row = row - (self.page_row_max - 1)
    end
    # Calculate cursor width
    cursor_width = self.width / @column_max - 32
    # Calculate cursor coordinates
    x = @index % @column_max * (cursor_width + 32)
    y = @index / @column_max * 32 - self.oy + 32
    # Update cursor rectangle
    self.cursor_rect.set(x, y, cursor_width, 32)
  end

  #==============================================================================
  # * Open
  #==============================================================================
  def open
    refresh

    self.opacity = 0
    self.contents_opacity = 0
    self.visible = true
    self.active = true
    @fade_in = true
  end
end
