=begin
      RGSS3
      
      ★ 方向キー入力型選択肢 ★
 
      選択肢の形式をコマンド選択型から方向キー入力型に変更します。
      決定キーは使用せず、選択肢のある方向に対応した方向キーを入力することで、
      選択肢を選びます。
      
      あまり長い文字列がある選択肢には向かない・・
      
      ● 機能と使用法 ●==================================================
      使用方法はデフォルトのイベントコマンド「選択肢の表示」とほぼ同じです。
      --------------------------------------------------------------------
      [デフォルトと異なる点]
      デフォルトでは例えば2択の選択肢を作りたい場合、
      イベントコマンド「選択肢の表示」で選択肢1と選択肢2の欄に文字列を設定します。
      
      このスクリプトを導入して同じことを実現しようとした場合、
      「選択肢1と選択肢3の欄を使う」「選択肢3と選択肢4の欄を使う」といったことが
      可能になります。
      選択肢の1~4の欄は、選択肢が表示される位置を意味するようになり、
      何も入力されていない欄は選択肢として判定されません。
      --------------------------------------------------------------------
      選択肢1~4の位置関係は以下のとおりです。
       選択肢 1 : 左に選択肢が表示されます。
       選択肢 2 : 右に選択肢が表示されます。
       選択肢 3 : 上に選択肢が表示されます。
       選択肢 4 : 下に選択肢が表示されます。
      --------------------------------------------------------------------
      ↓ 即席:設定例の図
      [url]http://kaisou-ryouiki.sakura.ne.jp/material/manual/img/choice_manual.png[/url]
      ====================================================================
      
      ver1.00
 
      Last Update : 2014/01/07
      01/07 : 新規
      
      ろかん   [url]http://kaisou-ryouiki.sakura.ne.jp/[/url]
=end
 
$rsi ||= {}
$rsi["方向キー入力型選択肢"] = true
 
class Sprite_ChoiceItem < Sprite
  #--------------------------------------------------------------------------
  # ● オブジェクト初期化
  #--------------------------------------------------------------------------
  def initialize(index, parent)
    super(nil)
    @index = index
    @parent = parent
    setup
  end
  #--------------------------------------------------------------------------
  # ● 初期設定
  #--------------------------------------------------------------------------
  def setup
    create_basebitmep
    self.z = 500
    self.ox = @base_bitmap.width / 2
    self.oy = @base_bitmap.height / 2
    self.visible = false
    case @index
    when 0
      self.x = Graphics.width / 4 - 10
      self.y = Graphics.height / 2
    when 1
      self.x = Graphics.width / 4 * 3 + 10
      self.y = Graphics.height / 2
    when 2
      self.x = Graphics.width / 2
      self.y = Graphics.height / 4 - 10
    when 3
      self.x = Graphics.width / 2
      self.y = Graphics.height / 4 * 3 + 10
    end
  end
  #--------------------------------------------------------------------------
  # ● ベースビットマップの作成
  #--------------------------------------------------------------------------
  def create_basebitmep
    @base_bitmap = Bitmap.new(170, 22)
    @base_bitmap.gradient_fill_rect(0, 0, 85, 22, gradient_color2, gradient_color1)
    @base_bitmap.gradient_fill_rect(85, 0, 85, 22, gradient_color1, gradient_color2)
    @base_bitmap.font.size = 20
  end
  #--------------------------------------------------------------------------
  # ● 背景グラデーションカラーの取得1
  #--------------------------------------------------------------------------
  def gradient_color1
    Color.new(0, 0, 80, 180)
  end
  #--------------------------------------------------------------------------
  # ● 背景グラデーションカラーの取得2
  #--------------------------------------------------------------------------
  def gradient_color2
    Color.new(0, 0, 80, 20)
  end
  #--------------------------------------------------------------------------
  # ● リフレッシュ
  #--------------------------------------------------------------------------
  def refresh
    self.bitmap.dispose if self.bitmap
    self.bitmap = @base_bitmap.dup
    if $game_message.choices[@index] && !$game_message.choices[@index].empty?
      self.visible = true
      draw_text_ex 0,0,$game_message.choices[@index]
      #self.bitmap.draw_text(0, 1, 170, 22, convert_escape_characters($game_message.choices[@index]), 1)
    else
      self.visible = false
    end
    self.opacity = 0
    self.zoom_x = 1
    self.zoom_y = 1
  end
  #--------------------------------------------------------------------------
  # ● 解放
  #--------------------------------------------------------------------------
  def dispose
    @base_bitmap.dispose
    self.bitmap.dispose if self.bitmap
    super
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新
  #--------------------------------------------------------------------------
  def update
    super
    if @parent.active
      self.opacity += 28
    else
      unless self.opacity.zero?
        if @parent.index == @index
          self.zoom_x += 0.08
          self.zoom_y += 0.03
          self.opacity -= 13
        else
          self.opacity -= 28
        end
      end
    end
  end
  def contents
    self.bitmap
  end
    #--------------------------------------------------------------------------
  # ● 获取文字颜色
  #     n : 文字颜色编号(0..31)
  #--------------------------------------------------------------------------
  def text_color(n)
    windowskin = Cache.system("Window")
    windowskin.get_pixel(64 + (n % 8) * 8, 96 + (n / 8) * 8)
  end
 
  #--------------------------------------------------------------------------
  # ● 获取各种文字颜色
  #--------------------------------------------------------------------------
  def normal_color;      text_color(0);   end;    # 普通
  def system_color;      text_color(16);  end;    # 系统
  def crisis_color;      text_color(17);  end;    # 危险
  def knockout_color;    text_color(18);  end;    # 无法战斗
  def gauge_back_color;  text_color(19);  end;    # 值槽背景
  def hp_gauge_color1;   text_color(20);  end;    # HP 值槽 1
  def hp_gauge_color2;   text_color(21);  end;    # HP 值槽 2
  def mp_gauge_color1;   text_color(22);  end;    # MP 值槽 1
  def mp_gauge_color2;   text_color(23);  end;    # MP 值槽 2
  def mp_cost_color;     text_color(23);  end;    # 消费 TP
  def power_up_color;    text_color(24);  end;    # 能力值提升(更换装备时)
  def power_down_color;  text_color(25);  end;    # 能力值降低(更换装备时)
  def tp_gauge_color1;   text_color(28);  end;    # TP 值槽 1
  def tp_gauge_color2;   text_color(29);  end;    # TP 值槽 2
  def tp_cost_color;     text_color(29);  end;    # 消费 TP
  #--------------------------------------------------------------------------
  # ● 获取保留项目的背景色
  #--------------------------------------------------------------------------
  #--------------------------------------------------------------------------
  # ● 更改内容绘制颜色
  #     enabled : 有效的标志。false 的时候使用半透明效果绘制
  #--------------------------------------------------------------------------
  def change_color(color, enabled = true)
    contents.font.color.set(color)
    contents.font.color.alpha = translucent_alpha unless enabled
  end
  #--------------------------------------------------------------------------
  # ● 绘制带有控制符的文本内容
  #--------------------------------------------------------------------------
  def draw_text_ex(x, y, text)
    reset_font_settings
    text = convert_escape_characters(text)
    size = text.size * self.bitmap.font.size
    if text.include?("\eI")
    size -= (6 * self.bitmap.font.size - 32)
    elsif text.include?("\e")
    size -= 6 * self.bitmap.font.size
    end
    x += 85
    x -= size / 2
    pos = {:x => x, :y => y, :new_x => x, :height => calc_line_height(text)}
    process_character(text.slice!(0, 1), text, pos) until text.empty?
  end
  #--------------------------------------------------------------------------
  # ● 重置字体设置
  #--------------------------------------------------------------------------
  def reset_font_settings
    change_color(normal_color)
    contents.font.size = Font.default_size
    contents.font.bold = false
    contents.font.italic = false
  end
  #--------------------------------------------------------------------------
  # ● 进行控制符的事前变换
  #    在实际绘制前、将控制符替换为实际的内容。
  #    为了减少歧异,文字「\」会被首先替换为转义符(\e)。
  #--------------------------------------------------------------------------
  def convert_escape_characters(text)
    result = text.to_s.clone
    result.gsub!(/\\/)            { "\e" }
    result.gsub!(/\e\e/)          { "\\" }
    result.gsub!(/\eV\[(\d+)\]/i) { $game_variables[$1.to_i] }
    result.gsub!(/\eV\[(\d+)\]/i) { $game_variables[$1.to_i] }
    result.gsub!(/\eN\[(\d+)\]/i) { actor_name($1.to_i) }
    result.gsub!(/\eP\[(\d+)\]/i) { party_member_name($1.to_i) }
    result.gsub!(/\eG/i)          { Vocab::currency_unit }
    result
  end
  #--------------------------------------------------------------------------
  # ● 获取第 n 号角色的名字
  #--------------------------------------------------------------------------
  def actor_name(n)
    actor = n >= 1 ? $game_actors[n] : nil
    actor ? actor.name : ""
  end
  #--------------------------------------------------------------------------
  # ● 获取第 n 号队伍成员的名字
  #--------------------------------------------------------------------------
  def party_member_name(n)
    actor = n >= 1 ? $game_party.members[n - 1] : nil
    actor ? actor.name : ""
  end
  #--------------------------------------------------------------------------
  # ● 文字的处理
  #     c    : 文字
  #     text : 绘制处理中的字符串缓存(字符串可能会被修改)
  #     pos  : 绘制位置 {:x, :y, :new_x, :height}
  #--------------------------------------------------------------------------
  def process_character(c, text, pos)
    case c
    when "\r"   # 回车
      return
    when "\n"   # 换行
      process_new_line(text, pos)
    when "\f"   # 翻页
      process_new_page(text, pos)
    when "\e"   # 控制符
      process_escape_character(obtain_escape_code(text), text, pos)
    else        # 普通文字
      process_normal_character(c, pos)
    end
  end
    #--------------------------------------------------------------------------
  # ● 绘制内容
  #     args : 与 Bitmap#draw_text 相同
  #--------------------------------------------------------------------------
  def draw_text(*args)
    contents.draw_text(*args)
  end
 
  #--------------------------------------------------------------------------
  # ● 处理普通文字
  #--------------------------------------------------------------------------
  def process_normal_character(c, pos)
    text_width = text_size(c).width
    draw_text(pos[:x], pos[:y], text_width * 2, pos[:height], c)
    pos[:x] += text_width
  end
    #--------------------------------------------------------------------------
  # ● 获取内容尺寸
  #--------------------------------------------------------------------------
  def text_size(str)
    contents.text_size(str)
  end
 
  #--------------------------------------------------------------------------
  # ● 处理换行文字
  #--------------------------------------------------------------------------
  def process_new_line(text, pos)
    pos[:x] = pos[:new_x]
    pos[:y] += pos[:height]
    pos[:height] = calc_line_height(text)
  end
  #--------------------------------------------------------------------------
  # ● 处理翻页文字
  #--------------------------------------------------------------------------
  def process_new_page(text, pos)
  end
  #--------------------------------------------------------------------------
  # ● 获取控制符的实际形式(这个方法会破坏原始数据)
  #--------------------------------------------------------------------------
  def obtain_escape_code(text)
    text.slice!(/^[\$\.\|\^!><\{\}\\]|^[A-Z]+/i)
  end
  #--------------------------------------------------------------------------
  # ● 获取控制符的参数(这个方法会破坏原始数据)
  #--------------------------------------------------------------------------
  def obtain_escape_param(text)
    text.slice!(/^\[\d+\]/)[/\d+/].to_i rescue 0
  end
  #--------------------------------------------------------------------------
  # ● 控制符的处理
  #     code : 控制符的实际形式(比如“\C[1]”是“C”)
  #     text : 绘制处理中的字符串缓存(字符串可能会被修改)
  #     pos  : 绘制位置 {:x, :y, :new_x, :height}
  #--------------------------------------------------------------------------
  def process_escape_character(code, text, pos)
    case code.upcase
    when 'C'
      change_color(text_color(obtain_escape_param(text)))
    when 'I'
      process_draw_icon(obtain_escape_param(text), pos)
    when '{'
      make_font_bigger
    when '}'
      make_font_smaller
    end
  end
  #--------------------------------------------------------------------------
  # ● 处理控制符指定的图标绘制
  #--------------------------------------------------------------------------
  def process_draw_icon(icon_index, pos)
    draw_icon(icon_index, pos[:x], pos[:y])
    pos[:x] += 24
  end
  #--------------------------------------------------------------------------
  # ● 放大字体尺寸
  #--------------------------------------------------------------------------
  def make_font_bigger
    contents.font.size += 8 if contents.font.size <= 64
  end
  #--------------------------------------------------------------------------
  # ● 缩小字体尺寸
  #--------------------------------------------------------------------------
  def make_font_smaller
    contents.font.size -= 8 if contents.font.size >= 16
  end
    #--------------------------------------------------------------------------
  # ● 获取行高
  #--------------------------------------------------------------------------
  def line_height
    return 24
  end
  #--------------------------------------------------------------------------
  # ● 获取标准的边距尺寸
  #--------------------------------------------------------------------------
  def standard_padding
    return 12
  end
 
  #--------------------------------------------------------------------------
  # ● 计算行高
  #     restore_font_size : 计算完成后是否恢复原本的字体尺寸?
  #--------------------------------------------------------------------------
  def calc_line_height(text, restore_font_size = true)
    result = [line_height, contents.font.size].max
    last_font_size = contents.font.size
    text.slice(/^.*$/).scan(/\e[\{\}]/).each do |esc|
      make_font_bigger  if esc == "\e{"
      make_font_smaller if esc == "\e}"
      result = [result, contents.font.size].max
    end
    contents.font.size = last_font_size if restore_font_size
    result
  end
  #--------------------------------------------------------------------------
  # ● 绘制值槽
  #     rate   : 比率(1.0 为满值)
  #     color1 : 渐变色的左端
  #     color2 : 渐变色的右端
  #--------------------------------------------------------------------------
  def draw_gauge(x, y, width, rate, color1, color2)
    fill_w = (width * rate).to_i
    gauge_y = y + line_height - 8
    contents.fill_rect(x, gauge_y, width, 6, gauge_back_color)
    contents.gradient_fill_rect(x, gauge_y, fill_w, 6, color1, color2)
  end
  #--------------------------------------------------------------------------
  # ● 绘制图标
  #     enabled : 有效的标志。false 的时候使用半透明效果绘制
  #--------------------------------------------------------------------------
  def draw_icon(icon_index, x, y, enabled = true)
    bitmap = Cache.system("Iconset")
    rect = Rect.new(icon_index % 16 * 24, icon_index / 16 * 24, 24, 24)
    contents.blt(x, y, bitmap, rect, enabled ? 255 : translucent_alpha)
  end
  #--------------------------------------------------------------------------
  # ● 绘制角色肖像图
  #     enabled : 有效的标志。false 的时候使用半透明效果绘制
  #--------------------------------------------------------------------------
  def draw_face(face_name, face_index, x, y, enabled = true)
    bitmap = Cache.face(face_name)
    rect = Rect.new(face_index % 4 * 96, face_index / 4 * 96, 96, 96)
    contents.blt(x, y, bitmap, rect, enabled ? 255 : translucent_alpha)
    bitmap.dispose
  end
  #--------------------------------------------------------------------------
  # ● 绘制人物行走图
  #--------------------------------------------------------------------------
  def draw_character(character_name, character_index, x, y)
    return unless character_name
    bitmap = Cache.character(character_name)
    sign = character_name[/^[\!\$]./]
    if sign && sign.include?('$')
      cw = bitmap.width / 3
      ch = bitmap.height / 4
    else
      cw = bitmap.width / 12
      ch = bitmap.height / 8
    end
    n = character_index
    src_rect = Rect.new((n%4*3+1)*cw, (n/4*4)*ch, cw, ch)
    contents.blt(x - cw / 2, y - ch, bitmap, src_rect)
  end
  #--------------------------------------------------------------------------
  # ● 绘制名字
  #--------------------------------------------------------------------------
  def draw_actor_name(actor, x, y, width = 112)
    change_color(hp_color(actor))
    draw_text(x, y, width, line_height, actor.name)
  end
  #--------------------------------------------------------------------------
  # ● 绘制职业
  #--------------------------------------------------------------------------
  def draw_actor_class(actor, x, y, width = 112)
    change_color(normal_color)
    draw_text(x, y, width, line_height, actor.class.name)
  end
  #--------------------------------------------------------------------------
  # ● 绘制称号
  #--------------------------------------------------------------------------
  def draw_actor_nickname(actor, x, y, width = 180)
    change_color(normal_color)
    draw_text(x, y, width, line_height, actor.nickname)
  end
  #--------------------------------------------------------------------------
  # ● 绘制等级
  #--------------------------------------------------------------------------
  def draw_actor_level(actor, x, y)
    change_color(system_color)
    draw_text(x, y, 32, line_height, Vocab::level_a)
    change_color(normal_color)
    draw_text(x + 32, y, 24, line_height, actor.level, 2)
  end
  #--------------------------------------------------------------------------
  # ● 绘制强化/弱化状态的图标
  #--------------------------------------------------------------------------
  def draw_actor_icons(actor, x, y, width = 96)
    icons = (actor.state_icons + actor.buff_icons)[0, width / 24]
    icons.each_with_index {|n, i| draw_icon(n, x + 24 * i, y) }
  end
end
 
class Spriteset_DirectionChoice
  #--------------------------------------------------------------------------
  # ● 公開インスタンス変数
  #--------------------------------------------------------------------------
  attr_reader   :active
  attr_reader   :index
  #--------------------------------------------------------------------------
  # ● オブジェクト初期化
  #--------------------------------------------------------------------------
  def initialize
    @active = false
    @index = -1
    create_sprites
  end
  #--------------------------------------------------------------------------
  # ● 選択肢スプライトの作成
  #--------------------------------------------------------------------------
  def create_sprites
    @command_sprites = []
    4.times{|i| @command_sprites << Sprite_ChoiceItem.new(i, self)}
  end
  #--------------------------------------------------------------------------
  # ● 入力処理の開始
  #--------------------------------------------------------------------------
  def start
    @active = true
    @index = -1
    @command_sprites.each{|sprite| sprite.refresh}
  end
  #--------------------------------------------------------------------------
  # ● 入力処理の終了
  #--------------------------------------------------------------------------
  def terminate
    @active = false
  end
  #--------------------------------------------------------------------------
  # ● 選択肢が完全に閉じているか
  #--------------------------------------------------------------------------
  def close?
    @command_sprites.all?{|sprite| sprite.opacity.zero?} 
  end
  #--------------------------------------------------------------------------
  # ● 解放
  #--------------------------------------------------------------------------
  def dispose
    @command_sprites.each{|sprite| sprite.dispose}
  end
  #--------------------------------------------------------------------------
  # ● キャンセル処理の有効状態を取得
  #--------------------------------------------------------------------------
  def cancel_enabled?
    $game_message.choice_cancel_type > 0
  end
  #--------------------------------------------------------------------------
  # ● 選択肢の有効判定
  #--------------------------------------------------------------------------
  def active_choice?(i)
    $game_message.choices[i] && !$game_message.choices[i].empty?
  end
  #--------------------------------------------------------------------------
  # ● 選択肢の選択後処理
  #--------------------------------------------------------------------------
  def choiced_process(index)
    @index = index
    $game_message.choice_proc.call(index)
    @command_sprites[index].flash(Color.new(255, 255, 255, 200), 35)
    Sound.play_ok
    Input.update
    terminate
  end
  #--------------------------------------------------------------------------
  # ● フレーム更新
  #--------------------------------------------------------------------------
  def update
    @command_sprites.each{|sprite| sprite.update}
    if @active
      if cancel_enabled? && Input.trigger?(:B)
        $game_message.choice_proc.call($game_message.choice_cancel_type - 1)
        Sound.play_cancel
        Input.update
        terminate
      else
        if Input.trigger?(:DOWN)
          choiced_process(3) if active_choice?(3)
        elsif Input.trigger?(:LEFT)
          choiced_process(0) if active_choice?(0)
        elsif Input.trigger?(:RIGHT)
          choiced_process(1) if active_choice?(1)
        elsif Input.trigger?(:UP)
          choiced_process(2) if active_choice?(2)
        end
      end
    end
  end
 
 
end
 
class Window_Message < Window_Base
  #--------------------------------------------------------------------------
  # ● 全ウィンドウの作成
  #--------------------------------------------------------------------------
  alias _create_all_windows_recreate_choice create_all_windows
  def create_all_windows
    _create_all_windows_recreate_choice
    @choice_window.dispose
    @choice_window = Spriteset_DirectionChoice.new
  end
end