#==============================================================================
# ** Window_NameInput
#------------------------------------------------------------------------------
#  This window is used to select text characters on the input name screen.
#==============================================================================

class NameInputMode
  attr_reader :names
  attr_reader :size
  attr_accessor :index
  attr_accessor :count

  def initialize(names, bitmap)
    @names = names
    @size = names.map { |n| bitmap.text_size(n).width }.max
    @index = 0
    @count = 0
    RPG::Mod.exec_hooks("hooks/NameInputMode/init", binding)
  end

  def cycle
    @index = (@index + 1) % @count
  end

  def label
    @names[(@index + 1) % @count]
  end
end

class Window_NameInput < Window_Base
  BUTTON_BUFFER = 8
  BUTTON_PADDING = 16

  attr_accessor :index
  attr_accessor :ok_text
  attr_accessor :character_tables
  attr_accessor :table_height
  attr_accessor :char_w
  attr_accessor :char_h

  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize
    super(Graphics.width / 2 - 320, Graphics.height / 2 - 112, 640, 352)
    self.contents = Bitmap.new(width - 32, height - 32)
    @index = 0
    @ok_text = "OK"
    @char_w = 28
    @char_h = 32
  end
  def init
    # Create dimension information
    @table_size = @character_tables.values.first.size
    @table_width = @table_size / @table_height
    @start_x = ((width - 32) - @table_width * @char_w) / 2
    @start_y = ((height - 32) - (@table_height + 1) * @char_h + BUTTON_BUFFER) / 2
    @ok_text_size = self.contents.text_size(@ok_text).width

    # Initialize mode information
    @character_tables.each_key do |key|
      key.each_with_index do |new_max, i|
        @modes[i].count = new_max + 1 if @modes[i].count < new_max + 1
      end
    end

	RPG::Mod.exec_hooks("hooks/Window_NameInput/init2", binding)
	
    refresh
    update_cursor_rect
    self
  end
  #--------------------------------------------------------------------------
  # * Properties
  #--------------------------------------------------------------------------
  def set_mode_buttons(buttons)
    @modes = buttons.map { |n| NameInputMode.new(n, self.contents) }
  end
  #--------------------------------------------------------------------------
  # * Text Character Acquisition
  #--------------------------------------------------------------------------
  def character
    return current_table[@index]
  end
  #--------------------------------------------------------------------------
  # * Mode Button Cursor Positioning
  #--------------------------------------------------------------------------
  def mode_button_slot
    pos = @index % @table_width
    x = 0
    @modes.each_with_index do |mode, i|
      size = mode.size + BUTTON_PADDING * 2
      if pos * @char_w >= x && pos * @char_w <= x + size
        if (pos + 1) * @char_w - BUTTON_PADDING <= x + size || i < @modes.size - 1
          return i
        end
      end
      x += size
    end
    return -1
  end
  #--------------------------------------------------------------------------
  # * Cycle Current Mode
  #--------------------------------------------------------------------------
  def cycle_mode(slot)
    @modes[slot].cycle
    refresh
  end
  #--------------------------------------------------------------------------
  # * Get Character Table for Mode
  #--------------------------------------------------------------------------
  def current_table
    @character_tables[@modes.map { |m| m.index }]
  end
  #--------------------------------------------------------------------------
  # * Refresh
  #--------------------------------------------------------------------------
  def refresh
    self.contents.clear
	delete_text = tr("Press X to delete characters (default controls)")
	delete_width = self.contents.text_size(delete_text).width
	delete_height = self.contents.text_size(delete_text).height
	self.contents.draw_text((self.contents.width - delete_width)/2, self.contents.height - (delete_height+2), delete_width, delete_height, delete_text, 1)
    table = current_table
    @table_size.times do |i|
      x = @start_x + (i % @table_width) * @char_w
      y = @start_y + (i / @table_width) * @char_h
      self.contents.draw_text(x, y, @char_w, @char_h, table[i], 1)
    end
    # OK button
    self.contents.draw_text(@start_x + @table_width * @char_w - @ok_text_size - BUTTON_PADDING,
                            @start_y + @table_height * @char_h + BUTTON_BUFFER,
                            @ok_text_size, @char_h, @ok_text, 1)
    # Mode buttons
    x = @start_x + BUTTON_PADDING
    @modes.each do |mode|
      self.contents.draw_text(x, @start_y + @table_height * @char_h + BUTTON_BUFFER,
                              mode.size, @char_h, mode.label, 1)
      x += BUTTON_PADDING * 2 + mode.size
    end
  end
  #--------------------------------------------------------------------------
  # * Cursor Rectangle Update
  #--------------------------------------------------------------------------
  def update_cursor_rect
    if @index >= @table_size
      # Cursor is positioned on OK or mode buttons
      slot = mode_button_slot
      if slot >= 0
        # Cursor is positioned on mode button
        x = @start_x
        @modes.each_with_index do |mode, i|
          if slot == i
            self.cursor_rect.set(x, @start_y + @table_height * @char_h + BUTTON_BUFFER,
                                 mode.size + BUTTON_PADDING * 2, @char_h)
            break
          end
          x += BUTTON_PADDING * 2 + mode.size
        end
      else
        # Cursor is positioned on OK button
        self.cursor_rect.set(@start_x + @table_width * @char_w - @ok_text_size - BUTTON_PADDING * 2,
                             @start_y + @table_height * @char_h + BUTTON_BUFFER,
                             @ok_text_size + 32, @char_h)
      end
    else
      # Cursor is not positioned on OK or mode buttons
      x = @start_x + (@index % @table_width) * @char_w
      y = @start_y + (@index / @table_width) * @char_h
      self.cursor_rect.set(x, y, @char_w, @char_h)
    end
  end
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    super
    if @index >= @table_size
      # Cursor is positioned on OK or mode buttons
      if Input.repeat?(Input::LEFT)
        # If directional button pressed down is not a repeat, or
        # cursor is not positioned on the left edge
        old_slot = mode_button_slot
        if Input.trigger?(Input::LEFT) || old_slot != 0
          $game_system.se_play($data_system.cursor_se)
          if old_slot == 0
            @index = @table_size + @table_width - 1
          else
            while true
              @index -= 1
              break if old_slot != mode_button_slot
            end
          end
        end
      end
      if Input.repeat?(Input::RIGHT)
        # If directional button pressed down is not a repeat, or
        # cursor is not positioned on the right edge
        old_slot = mode_button_slot
        if Input.trigger?(Input::RIGHT) || old_slot != -1
          $game_system.se_play($data_system.cursor_se)
          if old_slot == -1
            @index = @table_size
          else
            while true
              @index += 1
              break if old_slot != mode_button_slot
            end
          end
        end
      end
      if Input.trigger?(Input::DOWN)
        $game_system.se_play($data_system.cursor_se)
        @index -= @table_size
      end
      if Input.repeat?(Input::UP)
        $game_system.se_play($data_system.cursor_se)
        @index -= @table_width
      end
    else
      # Cursor is not positioned on OK or mode buttons
      if Input.repeat?(Input::RIGHT)
        # If directional button pressed down is not a repeat, or
        # cursor is not positioned on the right edge
        if Input.trigger?(Input::RIGHT) || @index % @table_width < @table_width - 1
          $game_system.se_play($data_system.cursor_se)
          if @index % @table_width < @table_width - 1
            @index += 1
          else
            @index -= @table_width - 1
          end
        end
      end
      if Input.repeat?(Input::LEFT)
        # If directional button pressed down is not a repeat, or
        # cursor is not positioned on the left edge
        if Input.trigger?(Input::LEFT) || @index % @table_width > 0
          $game_system.se_play($data_system.cursor_se)
          if @index % @table_width > 0
            @index -= 1
          else
            @index += @table_width - 1
          end
        end
      end
      if Input.repeat?(Input::DOWN)
        $game_system.se_play($data_system.cursor_se)
        @index += @table_width
      end
      if Input.repeat?(Input::UP)
        # If directional button pressed down is not a repeat, or
        # cursor is not positioned on the upper edge
        if Input.trigger?(Input::UP) || @index >= @table_width
          $game_system.se_play($data_system.cursor_se)
          if @index >= @table_width
            @index -= @table_width
          else
            @index += @table_size
          end
        end
      end
    end
    update_cursor_rect
  end
end
