# )--------------------------------------------------(
# )--     Author:     Mr Trivel                    --(
# )--     Name:       Open Shops                   --(
# )--     Created:    2014-06-10                   --(
# )--     Version:    1.0                          --(
# )--------------------------------------------------(
# )--     Requires:   None                         --(
# )--------------------------------------------------(
# )--             Description                      --(
# )--  Instead of talking to the store clerk, you  --(
# )--  can just buy the item you see on the table. --(
# )--------------------------------------------------(
# )--             Instructions                     --(
# )--  Call the item buy by using:                 --(
# )--  SceneManager.call(MrTS_Open_Shop_Scene)     --(
# )--  SceneManager.scene.prepare(type, id, price) --(
# )--  type is: 0 - item, 1 - weapon, 2 - armor    --(
# )--  id is item's ID in the database             --(
# )--  price - at what value you want to sell the  --(
# )--  item to the player. Don't enter it to use   --(
# )--  default value.                              --(
# )--  E.g: SceneManager.call(MrTS_Open_Shop_Scene)--(
# )--       SceneManager.scene.prepare(1,24)       --(
# )--  Will ask if you want to buy Tyrfang sword   --(
# )--  for default price.                          --(
# )--------------------------------------------------(
# )--             LICENSE INFO                     --(
# )--[url]http://mrtrivelvx.wordpress.com/terms-of-use/[/url] --(
# )--------------------------------------------------(

module MrTS
  module Open_Shop
    # )---------------------------(
    # )--  Opacity of the shop  --(
    # )---------------------------(
    OPACITY = 192
  end
end

# )-----------------------------------(
# )--  Class: MrTS_Open_Shop_Scene  --(
# )-----------------------------------(
class MrTS_Open_Shop_Scene < Scene_Base
  
  # )---------------------(
  # )--  Method: start  --(
  # )---------------------(
  def start
    create_background
    create_main_viewport
  end
  
  # )-------------------------(
  # )--  Method: terminate  --(
  # )-------------------------(
  def terminate
    super
    dispose_background
    dispose_all_windows
  end
  
  # )---------------------------------(
  # )--  Method: create_background  --(
  # )---------------------------------(
  def create_background
    @background_sprite = Sprite.new
    @background_sprite.bitmap = SceneManager.background_bitmap
  end
  
  # )----------------------------------(
  # )--  Method: dispose_background  --(
  # )----------------------------------(
  def dispose_background
    @background_sprite.dispose
  end
  
  # )----------------------------------(
  # )--  Method: create_all_windows  --(
  # )----------------------------------(
  def create_all_windows
    create_gold_window
    create_command_window
    create_input_window
    create_stat_window
  end
  
  # )----------------------------------(
  # )--  Method: create_stat_window  --(
  # )----------------------------------(
  def create_stat_window
    wx = 0
    wh =  @info_window.line_height*6 + @info_window.standard_padding*2
    wy = Graphics.height - @info_window.height - wh
    ww = 160
    @stat_window = Window_Base.new(wx,wy,ww,wh)
    6.times do |i| 
      @stat_window.change_color(@stat_window.system_color)
      @stat_window.draw_text(0, @stat_window.line_height*i, 120, @stat_window.line_height, Vocab::param(i+2))
      @stat_window.change_color(@stat_window.normal_color)
      @stat_window.draw_text(0, @stat_window.line_height*i, @stat_window.contents.width, @stat_window.line_height, @item.params[i+2], 2) 
    end
  end
  
  # )----------------------------------(
  # )--  Method: create_gold_window  --(
  # )----------------------------------(
  def create_gold_window
    @gold_window = Window_Gold.new
    @gold_window.viewport = @viewport
    @gold_window.x = Graphics.width - @gold_window.width
    @gold_window.y = 0
  end
  
  # )-----------------------(
  # )--  Method: prepare  --(
  # )-----------------------(
  def prepare(type, index, price = -1)
    case type
    when 0
      @item = $data_items[index]
    when 1
      @item = $data_weapons[index]
    when 2
      @item = $data_armors[index]
    end 
    @info_window = MrTS_Open_Shop.new(type, index, price)
    create_all_windows
  end 
  
  # )-------------------------------------(
  # )--  Method: create_command_window  --(
  # )-------------------------------------(
  def create_command_window
    @command_window = MrTS_Open_Shop_Command.new
    @command_window.set_handler(:on_buy,   method(:on_buy))
    @command_window.set_handler(:on_leave, method(:on_leave))
    @command_window.set_handler(:cancel,   method(:return_scene)) 
    @command_window.start
  end
  
  # )----------------------(
  # )--  Method: on_buy  --(
  # )----------------------(
  def on_buy
    @input_window.open
    @input_window.activate
    @input_window.set_item(@item)
  end
  
  # )------------------------(
  # )--  Method: on_leave  --(
  # )------------------------(
  def on_leave
    return_scene
  end
  
  # )-----------------------------------(
  # )--  Method: create_input_window  --(
  # )-----------------------------------(
  def create_input_window
    wx = Graphics.width - 164 - @command_window.width
    ww = 164
    wh = @info_window.line_height + @info_window.standard_padding*2
    wy = Graphics.height - @info_window.height - wh
    @input_window = MrTS_Open_Shop_Input.new(wx, wy, ww, wh)
    @input_window.openness = 0
    @input_window.set_handler(:ok,   method(:on_buy_ok))
    @input_window.set_handler(:cancel,   method(:on_buy_cancel)) 
  end
  
  # )-------------------------(
  # )--  Method: on_buy_ok  --(
  # )-------------------------(
  def on_buy_ok
    total_sum = @input_window.get_number * @item.price
    if $game_party.gold > total_sum
      Sound.play_shop
      $game_party.lose_gold(total_sum)
      $game_party.gain_item(@item, @input_window.get_number)
      return_scene
    else
      on_buy_cancel
      Sound.play_buzzer
    end
  end
  
  # )-----------------------------(
  # )--  Method: on_buy_cancel  --(
  # )-----------------------------(
  def on_buy_cancel
    @input_window.close
    @input_window.deactivate
    @command_window.activate
  end
end

# )-----------------------------(
# )--  Class: MrTS_Open_Shop  --(
# )-----------------------------(
class MrTS_Open_Shop < Window_Base
  
  # )-----------------------------(
  # )--  Method: initialize  --(
  # )-----------------------------(
  def initialize(type, index, price = -1)
    dh = line_height*4.5 + standard_padding*2
    y = Graphics.height - dh
    width = Graphics.width
    super(0, y, width, dh)
    
    case type
    when 0
      @item = $data_items[index]
    when 1
      @item = $data_weapons[index]
    when 2
      @item = $data_armors[index]
    end 
    
    @price = price == -1 ? @item.price : price
    
    self.back_opacity = MrTS::Open_Shop::OPACITY
    
    create_contents
    refresh
  end
  
  # )-----------------------(
  # )--  Method: refresh  --(
  # )-----------------------(
  def refresh
    contents.clear
    draw_item_name(@item, 0, 0)
    draw_currency_value(@price, Vocab::currency_unit, 172, 0, 160)
    change_color(normal_color)
    pose = Vocab::Possession + ": "
    pose_width = text_size(pose).width+32
    draw_text(172+160+16, 0, pose_width, line_height, pose)
    draw_text(172+160+16+pose_width, 0, 64, line_height, $game_party.item_number(@item))
    draw_text_ex(0, line_height, @item.description)
    
    i = 0
    if @item.is_a?(RPG::EquipItem)
      $game_party.members.each do |member|
        if member.equippable?(@item)
          draw_actor_graphic(member, 16+96*i, 32+line_height*3)
          draw_actor_equip_info(32+96*i, line_height*3, member)
        else
          i -= 1
        end #if
      i += 1
      end #do
    end#if
  end
  
  # )-------------------------------------(
  # )--  Method: draw_actor_equip_info  --(
  # )-------------------------------------(
  def draw_actor_equip_info(x, y, actor)
    enabled = actor.equippable?(@item)
    change_color(normal_color, enabled)
    item1 = current_equipped_item(actor, @item.etype_id)
    draw_actor_param_change(x, y+line_height/2, actor, item1) if enabled
  end
  
  # )-------------------------------------(
  # )--  Method: current_equipped_item  --(
  # )-------------------------------------(
  def current_equipped_item(actor, etype_id)
    list = []
    actor.equip_slots.each_with_index do |slot_etype_id, i|
      list.push(actor.equips[i]) if slot_etype_id == etype_id
    end
    list.min_by {|item| item ? item.params[param_id] : 0 }
  end
  
  # )---------------------------------------(
  # )--  Method: draw_actor_param_change  --(
  # )---------------------------------------(
  def draw_actor_param_change(x, y, actor, item1)
    rect = Rect.new(x, y, contents.width - 4 - x, line_height)
    change = @item.params[param_id] - (item1 ? item1.params[param_id] : 0)
    change_color(param_change_color(change))
    draw_text(rect, sprintf("%+d", change))
  end
  
  # )------------------------(
  # )--  Method: param_id  --(
  # )------------------------(
  def param_id
    @item.is_a?(RPG::Weapon) ? 2 : 3
  end  
end

# )-------------------------------------(
# )--  Class: MrTS_Open_Shop_Command  --(
# )-------------------------------------(
class MrTS_Open_Shop_Command < Window_Command
  
  # )--------------------------(
  # )--  Method: initialize  --(
  # )--------------------------(
  def initialize
    super(Graphics.width-window_width, Graphics.height-line_height*6-standard_padding*4)
    self.back_opacity = MrTS::Open_Shop::OPACITY
  end
  
  # )---------------------(
  # )--  Method: start  --(
  # )---------------------(
  def start
    refresh
    select(0)
    activate
  end
  
  # )---------------------------------(
  # )--  Method: make_command_list  --(
  # )---------------------------------(
  def make_command_list
    super
    add_command("Buy",    :on_buy)
    add_command("Leave",  :on_leave)
  end
end

# )-----------------------------------(
# )--  Class: MrTS_Open_Shop_Input  --(
# )-------------------------------------(
class MrTS_Open_Shop_Input < Window_Selectable
  
  # )--------------------------(
  # )--  Method: initialize  --(
  # )--------------------------(
  def initialize(*args)
    super(*args)
    @number = 1
  end
  
  # )------------------------(
  # )--  Method: set_item  --(
  # )------------------------(
  def set_item(item, price=-1)
    @item = item
    @price = price == -1 ? item.price : price
    @max = $game_party.max_item_number(@item) - $game_party.item_number(@item)
    @number = @max if @number > @max
    refresh
  end
  
  # )-----------------------(
  # )--  Method: col_max  --(
  # )-----------------------(
  def col_max
    return 1
  end
  
  # )----------------------(
  # )--  Method: update  --(
  # )----------------------(
  def update
    super
    if active
      last_number = @number
      update_number
      if @number != last_number
        Sound.play_cursor
        refresh
      end
    end
  end
  
  # )-----------------------------(
  # )--  Method: update_number  --(
  # )-----------------------------(
  def update_number
    change_number(1)   if Input.repeat?(:RIGHT)
    change_number(-1)  if Input.repeat?(:LEFT)
    change_number(10)  if Input.repeat?(:UP)
    change_number(-10) if Input.repeat?(:DOWN)
  end
  
  # )-----------------------------(
  # )--  Method: change_number  --(
  # )-----------------------------(
  def change_number(amount)
    @number += amount
    @number = 1 if @number < 1
    @number = @max if @number > @max
  end
  
  # )---------------------------(
  # )--  Method: draw_number  --(
  # )---------------------------(
  def draw_number
    change_color(normal_color)
    draw_text(12, 0, 64, line_height, @number)
  end
  
  # )-----------------------(
  # )--  Method: refresh  --(
  # )-----------------------(
  def refresh
    contents.clear
    draw_text(0, 0, 64, line_height, "x")
    t_price = @price * @number
    draw_text(contents.width-120, 0, 120, line_height, t_price.to_s + Vocab::currency_unit, 2)
    draw_number
  end
  
  # )--------------------------(
  # )--  Method: get_number  --(
  # )--------------------------(
  def get_number
    return @number
  end
end