#==============================================================================
# ■ HIDE_MESSAGE vol.3.00β版(分割定義3)
#------------------------------------------------------------------------------
# ※『Window_digits_number 5.40以上』必須
# 11/09/25
#==============================================================================

#==============================================================================
# ■ Window_InputNumber
#==============================================================================
class Window_InputNumber < Window_Base
  #--------------------------------------------------------------------------
  # ■ カーソルの矩形更新(再定義)
  #--------------------------------------------------------------------------
  def update_cursor_rect
    self.cursor_rect.set(@index * @cursor_width-6, 0, @cursor_width-4+12, 32)
  end
  #--------------------------------------------------------------------------
  # ■ リフレッシュ(再定義※更新しない)
  #--------------------------------------------------------------------------
  def refresh
    return
  end
end
#==============================================================================
# ■ Window_Message
#==============================================================================
class Window_Message < Window_Selectable
  include HIDE_MESSAGE
  #--------------------------------------------------------------------------
  # ■ オブジェクト初期化
  #--------------------------------------------------------------------------
  if !$@;alias hidesp_message_initialize initialize;end
  def initialize
    # □元の処理を開始
    hidesp_message_initialize
    @case_opa = false
    @case_width = 0
  end
  #--------------------------------------------------------------------------
  # ■ メッセージウィンドウ背景のデータを取得
  #--------------------------------------------------------------------------
  def make_window_data?(text)
    self.opacity = 0
    self.back_opacity = 0
    # □最大文字幅を取得する配列の初期化
    @widths = []
    @aligns = []
    #…………………………………………………………………………………………………
    # ■数値入力の先読み
    #…………………………………………………………………………………………………
    if $game_temp.num_input_variable_id > 0
      # □数値入力の文字幅を取得
      i_max = $game_temp.num_input_digits_max
      @num_width = self.contents.text_size("0").width + 8
      @widths.push(@num_width * i_max)
      # □数値を１桁の配列に変換
      max = $game_temp.num_input_digits_max
      num = $game_variables[$game_temp.num_input_variable_id]
      @digits = make_digits?(num,max)
    end
    #…………………………………………………………………………………………………
    # ■イベントを取得
    #…………………………………………………………………………………………………
    @event = return_event?($game_map.tail_id)
    #…………………………………………………………………………………………………
    # ■テール表示位置XYの基本値を取得
    #…………………………………………………………………………………………………
    if event_type?(@event)
      screen_x = @event.screen_x - 16
      screen_y = @event.screen_y - 32
    else
      screen_x = @event.x * 32
      screen_y = @event.y * 32
    end
    event_x = screen_x
    event_y = screen_y - image_height?(@event)
    #…………………………………………………………………………………………………
    # ■ ウィンドウZ座標を取得
    #…………………………………………………………………………………………………
    self.z = 5000 + @event.message.z + @event.message.number + 2
    #…………………………………………………………………………………………………
    # ■１行に含まれる文字列から最大幅を取得(制御文字を全て削除)
    #…………………………………………………………………………………………………
    text_dup = text_dup2 = text.each_line{|a| a.gsub!(/\n/){""}}
    textes = []
    text_dup.each{|a| 
    a.gsub!(/\000/) {"\\"}
    a.gsub!(/\001\[([0-9]+)\]/) {""}
    a.gsub!(/\002/) {""}
    a.gsub!(/\003\[([0-9]+)\]/) {""}
    a.gsub!(/\004\[([0-9]+)\]/) {""}
    a.gsub!(/\005\[([0-9]+)\]/) {""}
    a.gsub!(/\006\[([0-9]+)\]/) {""}
    a.gsub!(/\007\[(.*?)\]/) {""}
    a.gsub!(/\010\[([0-9]+)\]/) {""} 
    @widths.push(self.contents.text_size(a).width )
    @aligns.push($1.to_i) }
    
    text_dup2.each{|a| 
    textes.push(a.gsub!(/\n/){""}) 
    a.gsub!(/\003\[([0-9]+)\]/) {"\icon"}
    a.gsub!(/\004\[([0-9]+)\]/) {"\icon"}
    a.gsub!(/\005\[([0-9]+)\]/) {"\icon"}
    a.gsub!(/\006\[([0-9]+)\]/) {"\icon"}
    a.gsub!(/\007\[(.*?)\]/) {"\icon"} 
    a.gsub!(/\010\[([0-9]+)\]/) {""} }
    #…………………………………………………………………………………………………
    # ■最大幅の補正(アイコン有り//数値入力)
    #…………………………………………………………………………………………………
    icon_w = []
    textes.each{|a| icon_w[icon_w.size] = a.scan(/\icon/)}
    for i in 0...@widths.size
      if icon_w[i] != nil
        @widths[i] += (icon_w[i].size*28)
      end
      if $game_temp.num_input_variable_id > 0
        @widths[i] += 4
      end
      @widths[i] += 40
    end
    #…………………………………………………………………………………………………
    # ■ウィンドウ幅//高さの変更(最大文字幅//行数)
    #…………………………………………………………………………………………………
    self.width = @widths.max
    self.height = @widths.size * 32 + 32
    @px = 0
    if self.width < 96
      @px = (96 - self.width)/2
      self.width = 96
      @widths = [96]*@widths.size
    end
    #…………………………………………………………………………………………………
    # ■1行のテキスト幅の配列を格納
    #…………………………………………………………………………………………………
    @event.message.text_widths = @widths
    @event.message.text_aligns = @aligns
    #…………………………………………………………………………………………………
    # ■ウィンドウ幅//高さが指定されている場合
    #…………………………………………………………………………………………………
    unless @event.message.width.nil?
      self.width = @event.message.width
    end
    unless @event.message.height.nil?
      self.height = @event.message.height
    end
    #…………………………………………………………………………………………………
    # ■最大文字幅(ウィンドウ幅)を格納
    #…………………………………………………………………………………………………
    @case_width = self.width
    #…………………………………………………………………………………………………
    # ■XY座標の変更(テールを上に描画)
    #…………………………………………………………………………………………………
    x = screen_x - (self.width/2) + 16
    y = event_y - self.height
    cx = self.width/2 - 16
    cy = 0
    @event.message.cy = 32
    #…………………………………………………………………………………………………
    # ■XY座標のスクロールが有効の場合
    #…………………………………………………………………………………………………
    unless event_type?(@event)
      if $game_map.display_x > 0
        x -= ($game_map.display_x/4)
      end
      if $game_map.display_y > 0
        y -= ($game_map.display_y/4)
      end
    end
    #…………………………………………………………………………………………………
    # ■テールX座標の自動判定(中央固定フラグがOFFの場合)
    #…………………………………………………………………………………………………
    unless @event.message.center
      if event_type?(@event)
        max = 640
        max_x = 640 - self.width
      else
        max = ($game_map.width - 1) * 32
        max_x = ($game_map.width * 32 - self.width - ($game_map.display_x/4))
      end
      #…………………………………………………………………………………………………
      # ■座標XがMapX以上の場合
      #…………………………………………………………………………………………………
      if screen_x + (self.width/2) >= max
        cx = x
        x = max_x
        cx -= x
        cx += self.width/2 - 16
      end
      #…………………………………………………………………………………………………
      # ■座標Xが0以下の場合
      #…………………………………………………………………………………………………
      if screen_x - (self.width/2) < 0
        cx = screen_x
        x = 0
      end
    end
    #…………………………………………………………………………………………………
    # ■基本XY座標の取得
    #…………………………………………………………………………………………………
    @event.message.sx = x
    @event.message.sy = y
    #…………………………………………………………………………………………………
    # ■上部固定フラグがOFFの場合
    #…………………………………………………………………………………………………
    unless @event.message.top
      if event_type?(@event)
        min = ((y * 32) + event_y) - (self.height + 32)
      else
        min = ((y * 32) + event_y) - (self.height + 32)
      end
      #…………………………………………………………………………………………………
      # ■座標Yが0以下/下部固定フラグがONの場合(テールを下に描画)
      #…………………………………………………………………………………………………
      if min < 0 or @event.message.under
        #…………………………………………………………………………………………………
        # ■戦闘中の場合
        #…………………………………………………………………………………………………
        if event_type?(@event)
          if @event.message.under
            if @event.is_a?(Game_Actor)
              # □アクター画像の表示領域(Y320:Y480)
              bwh = 480
            elsif @event.is_a?(Game_Enemy)
              # □エネミー画像の表示領域(Y0:Y320)
              bwh = 320
            end
            # □下部固定フラグがONの場合
            if @event.message.under
              if bwh <= @event.screen_y + image_height?(@event) + 32 + 16
                y = bwh - self.height
              else
                y = @event.screen_y + 16
              end
            else
              y = bwh - self.height
            end
            cy = -(self.height+16)
            @event.message.cy = 64
          else
            y += 16
            @event.message.cy = 96
          end
        #…………………………………………………………………………………………………
        # ■Mapイベントの場合
        #…………………………………………………………………………………………………
        else
          y += self.height + 32
          cy = -(self.height+16)
          @event.message.cy = 0
        end
      end
    end
    #…………………………………………………………………………………………………
    # ■ウィンドウの補正Xの取得
    #…………………………………………………………………………………………………
    @event.message.cx = cx + 16
    #…………………………………………………………………………………………………
    # ■ウィンドウXY座標の取得
    #…………………………………………………………………………………………………
    self.x = x
    self.y = y
    #…………………………………………………………………………………………………
    # ■ウィンドウXY座標が指定されている場合
    #…………………………………………………………………………………………………
    unless @event.message.x.nil?
      self.x = @event.message.x
    end
    unless @event.message.y.nil?
      self.y = @event.message.y + 32
    end
    #…………………………………………………………………………………………………
    # ■XY座標が自動設定の場合、自動設定位置と同じ場合
    #…………………………………………………………………………………………………
    if @event.message.sx == self.x
      @event.message.sx = nil
    end
    # □テールが下の場合
    if @event.message.sy == self.y && @event.message.cy == 0
      @event.message.sy = nil
    end
    #…………………………………………………………………………………………………
    # ■ウィンドウ情報を取得
    #…………………………………………………………………………………………………
    @event.message.x = self.x
    @event.message.y = self.y - 32
    @event.message.width = self.width
    @event.message.height = self.height
    @event.message.rect_x = cx
    @event.message.rect_y = cy
    @event.message.text = text.dup
    #…………………………………………………………………………………………………
    # ■メッセージウィンドウ背景の作成
    #…………………………………………………………………………………………………
    make_window_back?(@event)
    #…………………………………………………………………………………………………
    # ■ポーズサインの位置を調整(0=左,1=真中,2=右)
    #…………………………………………………………………………………………………
    if @event.message.pause != nil
      case @event.message.pause
      when 0 # 左に表示
        pux = 0 ; puw = 64
      when 1 # 中央に表示
        pux = 0 ; puw = self.width
      when 2 # 右に表示
        pux = -56 ; puw = self.width*2
      end
      self.contents = Bitmap.new(puw+pux-32, self.height-32)
      self.width = puw+pux
      # □選択肢/数値入力以外の場合
      if $game_temp.choice_max <= 0 && $game_temp.num_input_variable_id <= 0
        self.pause = true
      end
    else
      self.contents = Bitmap.new(self.width-32, self.height-32)
      self.pause = false
    end
  end
  #--------------------------------------------------------------------------
  # ■ 背景ウィンドウの解放
  #--------------------------------------------------------------------------
  def back_end
    #…………………………………………………………………………………………………
    # ■描画したウィンドウをコピーして格納
    #…………………………………………………………………………………………………
    if @event != nil
      if @event.message.copy
        if @back != nil
          #…………………………………………………………………………………………………
          # ■コピーデータを取得
          #…………………………………………………………………………………………………
          unless event_type?(@event)
            @event.message.event_id = @event.id
          end
          #…………………………………………………………………………………………………
          # ■コピーメッセージを作成
          #…………………………………………………………………………………………………
          copy = Sprite_Copy_Window.new(@event.message_viewport,@back.bitmap.dup)
          copy.visible = @event.message.visible
          # □コピーメッセージの位置を設定
          make_copy_window_set?(copy,@event.message)
          # □数値入力をコピー
          if @digits_window != nil
            dx = @copy_dx - self.x
            dy = @copy_dy - self.y + 32 + 16
            # □数値入力XY座標を取得
            @event.message.dx = dx
            @event.message.dy = dy
            @event.message.digits = @digits.dup
            # □数値入力の値をコピーウィンドウに描画
            make_copy_digits?(copy.bitmap,@digits,dx,dy)
          end
          # □関連付けるコピーウィンドウの配列番号を格納
          if @event.message_other.gold != nil
            @event.message_other.key = @event.message_copy_base.size
          end
          @event.message_copies.push(copy)
          @event.message_copy_base.push(@event.message.dup)
        end
      end
      #…………………………………………………………………………………………………
      # ■ゴールドウィンドウを解放
      #…………………………………………………………………………………………………
      unless @event.message.copy
        other_dispose?(@event)
      end
    end
    #…………………………………………………………………………………………………
    # ■ウィンドウ背景を解放
    #…………………………………………………………………………………………………
    if @back != nil
      if @back.bitmap != nil
        @back.bitmap.dispose
      end
      @back.dispose
      @back = nil
    end
    #…………………………………………………………………………………………………
    # ■点滅選択肢ウィンドウを解放
    #…………………………………………………………………………………………………
    if @blink_window != nil
      @blink_window .dispose
      @blink_window  = nil
    end
    #…………………………………………………………………………………………………
    # ■数値入力ウィンドウを解放
    #…………………………………………………………………………………………………
    if @digits_window != nil
      @digits_window.dispose
      @digits_window = nil
    end
    #…………………………………………………………………………………………………
    # ■点滅数値入力ウィンドウを解放
    #…………………………………………………………………………………………………
    if @blink_digits != nil
      @blink_digits.dispose
      @blink_digits = nil
    end
    #…………………………………………………………………………………………………
    # ■スキップカウントを解放
    #…………………………………………………………………………………………………
    if @count_window != nil
      @count_window.dispose
      @count_window = nil
      @event.message.skip_count = nil
    end
  end
  #--------------------------------------------------------------------------
  # ■ メッセージ終了処理
  #--------------------------------------------------------------------------
  if !$@;alias hidesp_message_terminate_message terminate_message;end
  def terminate_message
    # □元の処理を開始
    hidesp_message_terminate_message
    # □背景ウィンドウの解放
    back_end
  end
  #--------------------------------------------------------------------------
  # ■ リフレッシュ(再定義)
  #--------------------------------------------------------------------------
  def refresh
    self.contents.clear
    @cursor_width = 0
    # 表示待ちのメッセージがある場合
    if $game_temp.message_text != nil
      text = $game_temp.message_text
      # 制御文字処理
      begin
        last_text = text.clone
        text.gsub!(/\\[Vv]\[([0-9]+)\]/) { $game_variables[$1.to_i] }
      end until text == last_text
      text.gsub!(/\\[Nn]\[([0-9]+)\]/) do
        if $game_actors[$1.to_i] != nil
          $game_actors[$1.to_i].name
        else
          # □先頭のアクター名を表示
          $game_actors[$game_party.actors[0].id].name
        end
      end
      #…………………………………………………………………………………………………
      # ■語彙変換
      #…………………………………………………………………………………………………
      if HIDE_MESSAGE::Word_end
        plus = HIDE_MESSAGE::Text_Plus.new
        text.gsub!(/\\word([0-9]+)\[([0-9]+)\]/) {plus.word($1.to_i,$2.to_i).to_s }
        text.gsub!(/\\word\[([0-9]+)\]/) { plus.word($game_party.actors[0].id,$1.to_i).to_s }
        text.gsub!(/\\text\[([0-9]+)\]/) { plus.text($1.to_i).to_s }
      end
      # 便宜上、"\\\\" を "\000" に変換
      text.gsub!(/\\\\/) { "\000" }
      # "\\C" を "\001" に、"\\G" を "\002" に変換
      text.gsub!(/\\[Cc]\[([0-9]+)\]/) { "\001[#{$1}]" }
      text.gsub!(/\\[Gg]/) { "\002" }
      #…………………………………………………………………………………………………
      # ■アイテム/武器/防具/スキル名+アイコンに変換
      #…………………………………………………………………………………………………
      text.gsub!(/\\[Ii]\[([0-9]+)\]/) { "\003[#{$1}]" + $data_items[$1.to_i].name }
      text.gsub!(/\\[Ww]\[([0-9]+)\]/) { "\004[#{$1}]" + $data_weapons[$1.to_i].name }
      text.gsub!(/\\[Aa]\[([0-9]+)\]/) { "\005[#{$1}]" + $data_armors[$1.to_i].name }
      text.gsub!(/\\[Ss]\[([0-9]+)\]/) { "\006[#{$1}]" + $data_skills[$1.to_i].name }
      text.gsub!(/\\icon\[(.*?)\]/) { "\007[#{$1}]" }
      #…………………………………………………………………………………………………
      # ■0=左揃え  1=中央揃え  2=右揃え
      #…………………………………………………………………………………………………
      text.gsub!(/\\pos\[([0-9]+)\]/) { "\010[#{$1}]" }
      #…………………………………………………………………………………………………
      # ■Map名に変換(0の場合、現在のMap名に変換)
      #…………………………………………………………………………………………………
      map_name = load_data("Data/MapInfos.rxdata")
      text.scan(/\\map\[([0-9]+)\]/)
      if $1.to_i == 0
        text.gsub!(/\\map\[([0-9]+)\]/) { map_name[$game_map.map_id].name }
      else
        text.gsub!(/\\map\[([0-9]+)\]/) { map_name[$1.to_i].name }
      end
      #…………………………………………………………………………………………………
      # ■メッセージウィンドウ背景のデータを取得
      #…………………………………………………………………………………………………
      make_window_data?(text)
      #…………………………………………………………………………………………………
      # ■ テキストの描画
      #…………………………………………………………………………………………………
      make_draw_text?(text,@back,@blink_window)
    end
    #…………………………………………………………………………………………………
    # ■選択肢の場合
    #…………………………………………………………………………………………………
    if $game_temp.choice_max > 0
      @item_max = $game_temp.choice_max
      self.active = true
      self.index = 0
    end
    #…………………………………………………………………………………………………
    # ■数値入力の場合
    #…………………………………………………………………………………………………
    if $game_temp.num_input_variable_id > 0
      digits_max = $game_temp.num_input_digits_max
      number = $game_variables[$game_temp.num_input_variable_id]
      @input_number_window = Window_InputNumber.new(digits_max)
      @input_number_window.number = number
      @input_number_window.x = self.x + 8
      @input_number_window.y = self.y + $game_temp.num_input_start * 32
      if @blink_digits != nil
        @blink_digits.z = @input_number_window.z
        input_number_updata?
      end
    end
  end
  #--------------------------------------------------------------------------
  # ■ 数値入力の文字位置を更新
  #--------------------------------------------------------------------------
  def input_number_updata?
    if @input_number_window != nil
      max = $game_temp.num_input_digits_max
      num = @input_number_window.number
      @digits = make_digits?(num,max)
      # □カーソルindexを取得
      e = (@input_number_window.cursor_rect.x+6)/((@input_number_window.width-32-12)/max)
      if @blink_digits != nil
        @blink_digits.x = @digits_window.x_es[e]
        @blink_digits.y = @digits_window.y_es[e]
        @blink_digits.blink_refresh(@digits[e],0,true)
      end
      @digits_window.refresh(num)
    end
  end
  #--------------------------------------------------------------------------
  # ■ フレーム更新
  #--------------------------------------------------------------------------
  if !$@;alias hidesp_message_update update;end
  def update
    #…………………………………………………………………………………………………
    # ■キー入力を待たない場合
    #…………………………………………………………………………………………………
    if @event != nil
      #…………………………………………………………………………………………………
      # ■skip_countが設定されている場合、カウント後にキー入力をスキップ
      #…………………………………………………………………………………………………
      if @event.message.skip_count != nil && @event.message.skip == false
        if @count_window != nil
          
          if @count_window.count_down(@event.message.skip_count,0)
            @old_time = nil
            @event.message.skip = true
          end
        end
      end
      #…………………………………………………………………………………………………
      # ■キー入力を待たない場合
      #…………………………………………………………………………………………………
      if @event.message.skip && @event.message.copy
        if @contents_showing
          self.pause = false
          # □選択肢の表示中の場合
          if $game_temp.choice_max > 0
            $game_system.se_play($data_system.decision_se)
            $game_temp.choice_proc.call(self.index)
          end
          # □数値入力中の場合
          if @input_number_window != nil
            # □数値入力の文字位置を更新
            input_number_updata?
            $game_system.se_play($data_system.decision_se)
            $game_variables[$game_temp.num_input_variable_id] =
            @input_number_window.number
            $game_map.need_refresh = true
            # 数値入力ウィンドウを解放
            @input_number_window.dispose
            @input_number_window = nil
          end
          # □メッセージの終了
          terminate_message
          return
        end
      elsif @event.message.skip
        terminate_message
        return
      end
    end
    # □元の処理を開始
    hidesp_message_update
    #…………………………………………………………………………………………………
    # ■ポーズサインを非表示
    #…………………………………………………………………………………………………
    if @event != nil
      if @event.message.pause.nil?
        self.pause = false
      end
    end
    #…………………………………………………………………………………………………
    # ■数値入力の文字位置を更新
    #…………………………………………………………………………………………………
    input_number_updata?
  end
  #--------------------------------------------------------------------------
  # ■ カーソルの矩形更新(再定義)
  #--------------------------------------------------------------------------
  def update_cursor_rect
    if @index >= 0
      n = $game_temp.choice_start + @index
      self.cursor_rect.set(0, n * 32, @cursor_w, 32)
    else
      self.cursor_rect.empty
      return
    end
    # □点滅文字ウィンドウの更新
    if BLINK_WINDOW
      set_blink_window?(self.index + $game_temp.choice_start)
    end
  end
end
#==============================================================================
# ■ Interpreter
#==============================================================================
class Interpreter
  include HIDE_MESSAGE
  #--------------------------------------------------------------------------
  # ■ メッセージの一括設定(※イベントスクリプトに記述)
  #--------------------------------------------------------------------------
  def message_window?(id = nil,event_id = nil,x = nil,y = nil,z = 0,w = nil,h = nil,
    opa = 255,number = 0,cx = 0,cy = 0,tail_x = 0,tail_width = 0,sx = 0,sy = 0,
    skip = false,skip_count = nil,break_count = nil,scroll = true,top = false,
    under = false,center = false,tail = true,copy = false,visible = true,
    text = "",digits = [],dx = 0,dy = 0,back_name = BACK_NAME,tail_name = TAIL_NAME,
    rect_x = 0,rect_y = 0,text_widths = [],text_aligns = [],pause = 2)
    
    # □イベントを取得
    event = return_event?(id)
    event.message = HIDE_MESSAGE::Make_Window.new(@event_id,id,x,y,z,w,h,opa,
    number,cx,cy,sx,sy,tail_x,tail_width,skip,skip_count,break_count,scroll,
    top,under,center,tail,copy,visible,text,digits,dx,dy,
    back_name,tail_name,rect_x,rect_y,text_widths,text_aligns,pause)
  end
  #--------------------------------------------------------------------------
  # ■ 指定したのイベント(ID)に対して、コピーウィンドウの[表示/非表示]
  #--------------------------------------------------------------------------
  def one_copy_visible?(id = nil,n = 0,key = true)
    event = return_event?(id)
    if n == 0
      for ev in 0...event.message_copies.size
        if event.message_copies[ev] != nil
          event.message_copy_base[ev].visible = key
        end
      end
    elsif event.message_copies[n-1] != nil
      event.message_copy_base[n-1].visible = key
    end
    return
  end
  #--------------------------------------------------------------------------
  # ■ 全てのイベントに対して、コピーウィンドウの[表示/非表示]
  #--------------------------------------------------------------------------
  def all_copy_visible?(n = 0,key = true)
    for event in $game_map.events.values
      one_copy_visible?(event.id,n,key)
    end
    one_copy_visible?(0,n,key)
  end
  #--------------------------------------------------------------------------
  # ■ 指定したのイベント(ID)に対して、コピーウィンドウの削除
  #--------------------------------------------------------------------------
  def one_copy_dispose?(id = nil,n = 0)
    event = return_event?(id)
    if n == 0
      all_dispose?(event)
      event.message_copy_base = []
    elsif event.message_copies[n-1] != nil
      one_dispose?(event.message_copies,event.message_copy_base,n-1)
    end
    return
  end
  #--------------------------------------------------------------------------
  # ■ 全てのイベントに対して、コピーウィンドウの削除
  #--------------------------------------------------------------------------
  def all_copy_dispose?(n = 0)
    for event in $game_map.events.values
      one_copy_dispose?(event.id,n)
    end
    one_copy_dispose?(0,n)
  end
end
