#==============================================================================
# ■ VXAce-RGSS3-31 和風レイアウト <file>          by Claimh
#------------------------------------------------------------------------------
# ファイル画面変更
#==============================================================================
 
#==============================================================================
# ■ SaveActor  : セーブファイル用のダミーアクター
#==============================================================================
class SaveActor
  #--------------------------------------------------------------------------
  # ● 公開インスタンス変数
  #--------------------------------------------------------------------------
  attr_reader :name
  attr_reader :level
  attr_reader :hp
  attr_reader :mp
  attr_reader :mhp
  attr_reader :mmp
  attr_reader :face_name
  attr_reader :face_index
  #--------------------------------------------------------------------------
  # ● オブジェクト初期化
  #--------------------------------------------------------------------------
  def initialize(actor)
    @name = actor.name
    @level = actor.level
    @hp = actor.hp; @mhp = actor.mhp
    @mp = actor.mp; @mmp = actor.mmp
    @face_name = actor.face_name
    @face_index = actor.face_index
    @dead = actor.dead?
  end
  #--------------------------------------------------------------------------
  # ● 戦闘不能判定
  #--------------------------------------------------------------------------
  def dead?
    @dead
  end
  #--------------------------------------------------------------------------
  # ● HP の割合を取得
  #--------------------------------------------------------------------------
  def hp_rate
    @hp.to_f / @mhp
  end
  #--------------------------------------------------------------------------
  # ● MP の割合を取得
  #--------------------------------------------------------------------------
  def mp_rate
    @mmp > 0 ? @mp.to_f / @mmp : 0
  end
end
 
#==============================================================================
# ■ Game_Party
#==============================================================================
class Game_Party < Game_Unit
  #--------------------------------------------------------------------------
  # ● セーブファイル表示用の顔グラフィック画像情報
  #--------------------------------------------------------------------------
  def member_for_savefile
    members.collect { |actor| SaveActor.new(actor) }
  end
end
 
#==============================================================================
# ■ DataManager
#==============================================================================
class << DataManager
  #--------------------------------------------------------------------------
  # ● セーブヘッダの作成
  #--------------------------------------------------------------------------
  alias make_save_header_faces make_save_header
  def make_save_header
    header = make_save_header_faces
    header[:actors] = $game_party.member_for_savefile
    header
  end
end
 
 
#==============================================================================
# ■ Window_J_SaveFile
#------------------------------------------------------------------------------
#  セーブ画面およびロード画面で表示する、セーブファイルのウィンドウです。
#==============================================================================
 
class Window_J_SaveFile < Window_J_Base
  #--------------------------------------------------------------------------
  # ● 公開インスタンス変数
  #--------------------------------------------------------------------------
  attr_reader   :selected                 # 選択状態
  #--------------------------------------------------------------------------
  # ● オブジェクト初期化
  #     index : セーブファイルのインデックス
  #--------------------------------------------------------------------------
  def initialize(index)
    lw = fitting_width(1)
    dx = Graphics.width - lw
    super(dx - index * lw - lw, 0, lw, window_height)
    @file_index = index
    refresh
    @selected = false
  end
  #--------------------------------------------------------------------------
  # ● ウィンドウ高さ
  #--------------------------------------------------------------------------
  def window_height
    return 200
  end
  #--------------------------------------------------------------------------
  # ● リフレッシュ
  #--------------------------------------------------------------------------
  def refresh
    contents.clear
    change_color(normal_color)
    name = Vocab::File + " " + ConvJnum.conv(@file_index + 1)
    draw_text(0, 4, line_width, contents_height, name)
  end
  #--------------------------------------------------------------------------
  # ● 選択状態の設定
  #--------------------------------------------------------------------------
  def selected=(selected)
    @selected = selected
    update_cursor
  end
  #--------------------------------------------------------------------------
  # ● カーソルの更新
  #--------------------------------------------------------------------------
  def update_cursor
    if @selected
      cursor_rect.set(0, 0, line_width, contents_height)
    else
      cursor_rect.empty
    end
  end
end
 
 
#==============================================================================
# ■ Window_J_SaveInfo
#==============================================================================
class Window_J_SaveInfo < Window_J_Selectable
  #--------------------------------------------------------------------------
  # ● オブジェクト初期化
  #--------------------------------------------------------------------------
  def initialize(dw, dh)
    @actors = []
    super(0, dh, Graphics.width - dw, Graphics.height - dh)
    self.file_index = index
  end
  #--------------------------------------------------------------------------
  # ● 行の幅を取得
  #--------------------------------------------------------------------------
  def line_width
    110
  end
  #--------------------------------------------------------------------------
  # ● 項目の高さを取得
  #--------------------------------------------------------------------------
  def item_height
    contents_height
  end
  #--------------------------------------------------------------------------
  # ● ウィンドウ内容の高さを計算
  #--------------------------------------------------------------------------
  def contents_height
    height - standard_padding * 2
  end
  #--------------------------------------------------------------------------
  # ● 項目数の取得
  #--------------------------------------------------------------------------
  def item_max
    return [@actors.size, 4].min
  end
  #--------------------------------------------------------------------------
  # ● ファイル変更
  #--------------------------------------------------------------------------
  def file_index=(index)
    return if @file_index == index
    @file_index = index
    header = DataManager.load_header(@file_index)
    @actors   = !header.nil? ? header[:actors] : []
    create_contents
    refresh
  end
  #--------------------------------------------------------------------------
  # ● 項目の描画
  #--------------------------------------------------------------------------
  def draw_item(index)
    return if @actors.empty? or @actors.nil?
    actor = @actors[index]
    rect = item_rect(index)
    draw_actor_name_l(actor, rect.x+4, rect.y, line_width)
    draw_actor_face(actor, rect.x+(line_width-96)/2, rect.y+line_height*1, !actor.dead?)
    draw_actor_level_l(actor, rect.x+4, rect.y+96+line_height*1)
    draw_actor_hp_l(actor, rect.x+4, rect.y+96+line_height*2, line_width-8)
    draw_actor_mp_l(actor, rect.x+4, rect.y+96+line_height*3, line_width-8)
  end
  #--------------------------------------------------------------------------
  # ● レベルの描画
  #--------------------------------------------------------------------------
  def draw_actor_level(actor, x, y)
    change_color(system_color)
    contents.draw_text(x, y, 32, line_height, Vocab::level_a)
    change_color(normal_color)
    contents.draw_text(x + 32, y, 24, line_height, actor.level, 2)
  end
end
 
 
#==============================================================================
# ■ Scene_File
#------------------------------------------------------------------------------
#  セーブ画面とロード画面の共通処理を行うクラスです。
#==============================================================================
 
class Scene_File < Scene_MenuBase
  #--------------------------------------------------------------------------
  # ● ヘルプウィンドウの作成
  #--------------------------------------------------------------------------
  def create_help_window
    @help_window = Window_J_Help.new(1)
    @help_window.x = Graphics.width - @help_window.width
    @help_window.set_text(help_window_text)
  end
  #--------------------------------------------------------------------------
  # ● セーブファイルビューポートの作成
  #--------------------------------------------------------------------------
  def create_savefile_viewport
    @savefile_viewport = Viewport.new
    @savefile_viewport.rect.width -= @help_window.width
  end
  #--------------------------------------------------------------------------
  # ● セーブファイルウィンドウの作成
  #--------------------------------------------------------------------------
  def create_savefile_windows
    @savefile_windows = Array.new(item_max) do |i|
      Window_J_SaveFile.new(i)
    end
    @savefile_windows.each {|window| window.viewport = @savefile_viewport }
 
    @info_window = Window_J_SaveInfo.new(@help_window.width, @savefile_windows[0].height)
  end
  #--------------------------------------------------------------------------
  # ● 選択状態の初期化
  #--------------------------------------------------------------------------
  def init_selection
    @index = first_savefile_index
    @savefile_windows[@index].selected = true
    self.top_index = @index - visible_max / 2
    ensure_cursor_visible
    @info_window.file_index = @index
  end
  #--------------------------------------------------------------------------
  # ● 項目数の取得
  #--------------------------------------------------------------------------
  def item_max
    DataManager.savefile_max
  end
  #--------------------------------------------------------------------------
  # ● 画面内に表示するセーブファイル数を取得
  #--------------------------------------------------------------------------
  def visible_max
    @savefile_viewport.rect.width / @help_window.width
  end
  #--------------------------------------------------------------------------
  # ● セーブファイルウィンドウの幅を取得
  #--------------------------------------------------------------------------
  def savefile_width
    @savefile_windows[0].width
  end
  #--------------------------------------------------------------------------
  # ● 最初に選択状態にするファイルインデックスを取得
  #--------------------------------------------------------------------------
  def first_savefile_index
    return 0
  end
  #--------------------------------------------------------------------------
  # ● 現在のインデックスの取得
  #--------------------------------------------------------------------------
  def index
    @index
  end
  #--------------------------------------------------------------------------
  # ● 先頭のインデックスの取得
  #--------------------------------------------------------------------------
  def top_index
    (@savefile_viewport.ox - @savefile_viewport.rect.width) / savefile_width
  end
  #--------------------------------------------------------------------------
  # ● 先頭のインデックスの設定
  #--------------------------------------------------------------------------
  def top_index=(index)
    index = 0 if index < 0
    index = item_max - visible_max if index > item_max - visible_max
    @savefile_viewport.ox = @help_window.width - (index+1) * savefile_width
  end
  #--------------------------------------------------------------------------
  # ● 末尾のインデックスの取得
  #--------------------------------------------------------------------------
  def bottom_index
    top_index + visible_max - 1
  end
  #--------------------------------------------------------------------------
  # ● 末尾のインデックスの設定
  #--------------------------------------------------------------------------
  def bottom_index=(index)
    self.top_index = index - (visible_max - 1)
  end
  #--------------------------------------------------------------------------
  # ● セーブファイル選択の更新
  #--------------------------------------------------------------------------
  def update_savefile_selection
    return on_savefile_ok     if Input.trigger?(:C)
    return on_savefile_cancel if Input.trigger?(:B)
    update_cursor
  end
  #--------------------------------------------------------------------------
  # ● セーブファイル[決定]
  #--------------------------------------------------------------------------
  def on_savefile_ok
  end
  #--------------------------------------------------------------------------
  # ● セーブファイル[キャンセル]
  #--------------------------------------------------------------------------
  def on_savefile_cancel
    Sound.play_cancel
    return_scene
  end
  #--------------------------------------------------------------------------
  # ● カーソルの更新
  #--------------------------------------------------------------------------
  def update_cursor
    last_index = @index
    cursor_l(Input.trigger?(:LEFT))   if Input.repeat?(:LEFT)
    cursor_r(Input.trigger?(:RIGHT))  if Input.repeat?(:RIGHT)
    cursor_pagedown   if Input.trigger?(:L)
    cursor_pageup     if Input.trigger?(:R)
    if @index != last_index
      Sound.play_cursor
      @savefile_windows[last_index].selected = false
      @savefile_windows[@index].selected = true
    end
    @info_window.file_index = @index
  end
  #--------------------------------------------------------------------------
  # ● カーソルを左に移動
  #--------------------------------------------------------------------------
  def cursor_l(wrap)
    @index = (@index + 1) % item_max if @index < item_max - 1 || wrap
    ensure_cursor_visible
  end
  #--------------------------------------------------------------------------
  # ● カーソルを右に移動
  #--------------------------------------------------------------------------
  def cursor_r(wrap)
    @index = (@index - 1 + item_max) % item_max if @index > 0 || wrap
    ensure_cursor_visible
  end
  #--------------------------------------------------------------------------
  # ● カーソルを 1 ページ後ろに移動
  #--------------------------------------------------------------------------
  def cursor_pagedown
    if top_index + visible_max < item_max
      self.top_index += visible_max
      @index = [@index + visible_max, item_max - 1].min
    end
  end
  #--------------------------------------------------------------------------
  # ● カーソルを 1 ページ前に移動
  #--------------------------------------------------------------------------
  def cursor_pageup
    if top_index > 0
      self.top_index -= visible_max
      @index = [@index - visible_max, 0].max
    end
  end
  #--------------------------------------------------------------------------
  # ● カーソル位置が画面内になるようにスクロール
  #--------------------------------------------------------------------------
  def ensure_cursor_visible
    self.top_index = index if index < top_index
    self.bottom_index = index if index > bottom_index
  end
end