#==============================================================================
#  @> Stat Allocation Scene ~ Karin's Soulkeeper, 2015
#------------------------------------------------------------------------------
#   v1.1 - May 10 : Optimized script & Made customization easier
#   v1.0 - Apr 09 : Started & finished.
#------------------------------------------------------------------------------
#  * Description:
#    This script launches a simple stat allocation scene that allows the
#    player to select which stat to increase. This is my own interpretation
#    of the system found in the game Summon Knight.
#
#    This scene is supposed to be called by events (like after boss battles),
#    as a form of reward for completing something worthwhile, and was
#    NOT designed to be a game's MAIN stat gain system. More of a way to gain
#    bonus stats, really. Although it can be used as such if you want.
#------------------------------------------------------------------------------
#  * To Use:
#    Put this script below Materials and above Main.
#    Script Call: SceneManager.call(Scene_StatAlloc)
#
#    NOTE: Remember to set VARIABLE to the position of the target actor in the
#    party!
#------------------------------------------------------------------------------
#  * Compatibility:
#    This script performs no aliases or overwrites, so it should be compatible
#    with all other scripts.
#------------------------------------------------------------------------------
#  * Terms:
#    Free to use in any kind of project, with or without credit. I wouldn't
#    really mind. Though I'd appreciate it! (^w^)/
#    Just don't, you know, claim that you made this here script yourself,
#    Because that's just mean (._.)
#==============================================================================

#CUSTOMIZATION OPTIONS
module KS
  module StatAllocSys
  #--------------------------------------------------------------------------
  # Set the id of the variable that will determine the target actor
  # You then need to set that variable to the position of the target
  # actor in the party.
  #--------------------------------------------------------------------------
  # Do note that the first party member is 0, the second is 1, third is 2,
  # and so on (The counting starts at 0 instead of 1).
  #--------------------------------------------------------------------------
  VARIABLE = 1
  
  #--------------------------------------------------------------------------
  # Set the included parameters (in ascending order please, to be safe)
  # Param ID's : 0=mhp, 1=mmp, 2=atk, 3=def, 4=mat, 5=mdf, 6=agi, 7=luk
  #--------------------------------------------------------------------------
  PARAMETERS = [0, 1, 2, 3, 4, 5, 6, 7]
  
  #--------------------------------------------------------------------------
  # Set the commands to be included, and their corresponding text to display
  # These *should* be in the same order as the one set in PARAMETERS
  #--------------------------------------------------------------------------
  # Commands:  :mhp, :mmp, :atk, :def, :mat, :mdf, :agi, :luk
  #--------------------------------------------------------------------------
  COMMANDS   = [
               #[:cmd, 'Name'],
                [:mhp, 'Max HP'],
                [:mmp, 'Max MP'],
                [:atk, 'Attack'],
                [:def, 'Defense'],
                [:mat, 'Mag Atk'],
                [:mdf, 'Mag Def'],
                [:agi, 'Agility'],
                [:luk, 'Luck']
               ] # FFS, DO NOT DELETE
  
  #--------------------------------------------------------------------------
  # Set the stat increases for when each command is selected.
  # Increases' order is the same as that of what's set in PARAMETERS.
  #--------------------------------------------------------------------------
  # For example:
  # With the default PARAMETERS, and given the fake command below:
  # ADD_DUM   = [150, 10, 4, 3, -12, -8, 0, 0]
  # Selecting that command will have these effects:
  #
  #   MHP + 150    DEF + 3     AGI + 0
  #   MMP + 10     MAT - 12    LUK + 0
  #   ATK + 4      MDF - 8
  #
  #--------------------------------------------------------------------------
  # Default Order:  mhp  mmp  at  df  ma  md  ag  lk
  #--------------------------------------------------------------------------
  ADD_MHP    = [100, 0, 0, 3, 0, 0, 0, 0]
  ADD_MMP    = [0, 35, 0, 0, 2, 1, 0, 0]
  ADD_ATK    = [0, 0, 8, 0, 3, 0, 3, 0]
  ADD_DEF    = [25, 0, 0, 8, 0, 3, 0, 0]
  ADD_MAT    = [5, 10, 3, 0, 8, 0, 0, 0]
  ADD_MDF    = [10, 5, 0, 0, 3, 8, 0, 3]
  ADD_AGI    = [0, 0, 1, 0, 1, 0, 14, 0]
  ADD_LUK    = [5, 0, 1, 1, 1, 1, 1, 1]
  
  end
end
# END OF CUSTOMIZATION OPTIONS

#==============================================================================
#  @> Scene_StatAlloc
#    - Starts a simple scene that allows the player to allocate points to
#      parameters; somewhat based on Scene_Equip.
#==============================================================================

class Scene_StatAlloc < Scene_MenuBase
  #--------------------------------------------------------------------------
  # * Start Processing
  #--------------------------------------------------------------------------
  def start
    super
    @idx = $game_variables[KS::StatAllocSys::VARIABLE]
    @template = [0]
    @actor = $game_party.members[@idx]
    create_header_window
    create_stats_window
    create_choice_window
    @choice_window.activate
    @choice_window.select(0)
    @header_window.display_text(@actor.name)
  end
  #--------------------------------------------------------------------------
  # * Defines Stat Increases
  #--------------------------------------------------------------------------
  def stat_increases(stat)
    case stat
      when :mhp
        return KS_StatAllocSys::ADD_MHP
      when :mmp
        return KS_StatAllocSys::ADD_MMP
      when :atk
        return KS_StatAllocSys::ADD_ATK
      when :def
        return KS_StatAllocSys::ADD_DEF
      when :mat
        return KS_StatAllocSys::ADD_MAT
      when :mdf
        return KS_StatAllocSys::ADD_MDF
      when :agi
        return KS_StatAllocSys::ADD_AGI
      when :luk
        return KS_StatAllocSys::ADD_LUK
      else
        return Array.new(KS::StatAllocSys::PARAMETERS.size) { 0 }
    end
  end
  #--------------------------------------------------------------------------
  # * Create Stats Display Window
  #--------------------------------------------------------------------------
  def create_stats_window
    x = @header_window.x
    y = @header_window.y + 48
    w = @header_window.width - 160
    h = 24 * (KS::StatAllocSys::PARAMETERS.size + 1)
    @stats_window = Window_AllocStats.new(x, y, w, h, @actor)
    @stats_window.set_handler(:ok,       method(:sconfirm))
    @stats_window.set_handler(:cancel,   method(:scancel))
  end
  #--------------------------------------------------------------------------
  # * Create Parameter Choice Window
  #--------------------------------------------------------------------------
  def create_choice_window
    x = @stats_window.x + @stats_window.width
    y = @stats_window.y
    @choice_window = Window_AllocParam.new(x, y)
    for command in KS::StatAllocSys::COMMANDS
      @choice_window.set_handler(command[0], method(:add_stat))
    end
  end
  #--------------------------------------------------------------------------
  # * Create Header Window
  #--------------------------------------------------------------------------
  def create_header_window
    @header_window = Window_Header.new(1, 80, 72, Graphics.width - 160)
  end
  #--------------------------------------------------------------------------
  # * Set Parameters
  #--------------------------------------------------------------------------
  def set_params(src)
    jj = 0
    for id in KS::StatAllocSys::PARAMETERS
      $game_actors[@idx + 1].add_param(id, src[jj])
      jj += 1
    end
  end
  #--------------------------------------------------------------------------
  # * On Stats Window Confirm
  #--------------------------------------------------------------------------
  def sconfirm
    Sound.play_ok
    set_params(@stats_window.temp_params)
    $game_actors[@idx + 1].recover_all
    return_scene
  end
  #--------------------------------------------------------------------------
  # * On Stats Window Canel
  #--------------------------------------------------------------------------
  def scancel
    @stats_window.reset
    @stats_window.unselect
    @choice_window.activate
  end
  #--------------------------------------------------------------------------
  # * Add Stat
  #--------------------------------------------------------------------------
  def add_stat
    @stats_window.activate
    added = stat_increases(@choice_window.current_symbol)
    @stats_window.set_temp_params(added)
    @stats_window.refresh(true)
  end
end


#==============================================================================
#  @> Window_AllocParam
#    - Handles stat selection
#==============================================================================

class Window_AllocParam < Window_Command
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize(x, y)
    super(x, y)
    self.openness = 0
    open
  end
  #--------------------------------------------------------------------------
  # * Window Dimensions
  #--------------------------------------------------------------------------
  def window_width
    return 160
  end
  #--------------------------------------------------------------------------
  # * Create Command List
  #--------------------------------------------------------------------------
  def make_command_list
    comm = KS::StatAllocSys::COMMANDS.size
    para = KS::StatAllocSys::PARAMETERS.size
    for command in KS_StatAllocSys::COMMANDS
      add_command(command[1], command[0])
    end
    return unless comm < para
    for x in 0...(para-comm)
      add_command("", :nil)
    end
  end
  #--------------------------------------------------------------------------
  # * Draw Commands (used so that the command names will be centred)
  #--------------------------------------------------------------------------
  def draw_item(index)
    change_color(normal_color, command_enabled?(index))
    draw_text(item_rect_for_text(index), command_name(index), 1)
  end
end


#==============================================================================
# @> Window_AllocStats
#    - Displays Player's stats and changes to it; Based on Window_EquipStatus
#==============================================================================

class Window_AllocStats < Window_Selectable
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize(x, y, w, h, actor)
    super(x, y, w, h)
    @actor = actor
	  @params = []
	  @temp_params = @template
    set_params
    reset
  end
  #--------------------------------------------------------------------------
  # * Set Params Value
  #--------------------------------------------------------------------------
  def set_params
    for id in KS::StatAllocSys::PARAMETERS
      @params.push(@actor.param(id))
    end
  end
  #--------------------------------------------------------------------------
  # * Return Temp Params List
  #--------------------------------------------------------------------------
  def temp_params
    return @temp_params
  end
  #--------------------------------------------------------------------------
  # * Set Temp Params Values
  #--------------------------------------------------------------------------
  def set_temp_params(lise)
    @temp_params = lise
  end
  #--------------------------------------------------------------------------
  # * Reset Window
  #--------------------------------------------------------------------------
  def reset
    @temp_params = @template
    refresh
  end
  #--------------------------------------------------------------------------
  # * Refresh
  #--------------------------------------------------------------------------
  def refresh(n=false)
    contents.clear
    i = 0
    for par in KS::StatAllocSys::PARAMETERS
      draw_item(0, line_height * i, par)
      i+= 1
    end
    return unless n
    @params.length.times{|i|
      change_color(param_change_color(@temp_params[i]))
      draw_text(150, line_height * i, 32, line_height, @temp_params[i] + @params[i], 2)
    }
  end
  
  #--------------------------------------------------------------------------
  # * Draw Item
  #--------------------------------------------------------------------------
  def draw_item(x, y, param_id)
    draw_param_name(x + 4, y, param_id)
    draw_param_value(x + 94, y, param_id)
    draw_right_arrow(x + 126, y)
  end
  #--------------------------------------------------------------------------
  # * Draw Parameter Name
  #--------------------------------------------------------------------------
  def draw_param_name(x, y, param_id)
    change_color(system_color)
    draw_text(x, y, 80, line_height, Vocab::param(param_id))
  end
  #--------------------------------------------------------------------------
  # * Draw Current Parameter
  #--------------------------------------------------------------------------
  def draw_param_value(x, y, param_id, color=normal_color)
    change_color(color)
    draw_text(x, y, 32, line_height, @actor.param(param_id), 2)
  end
  #--------------------------------------------------------------------------
  # * Draw Right Arrow
  #--------------------------------------------------------------------------
  def draw_right_arrow(x, y)
    change_color(system_color)
    draw_text(x, y, 22, line_height, "→", 1)
  end
end

#==========================================================================
#  @> Window_Header
#    - Displays Text
#==========================================================================

class Window_Header < Window_Base
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize(lines, x, y, w)
    super(x, y, w, fitting_height(lines))
  end
  #--------------------------------------------------------------------------
  # * Display Specified Text
  #--------------------------------------------------------------------------
  def display_text(text)
    contents.clear
    draw_text(contents.rect, text, 1)
  end
end