#==============================================================================
# ■ PLAY_CARD vol.1.02
#------------------------------------------------------------------------------
# ※トランプカードを用いたスクリプトに必須
# 『Poker_Game vol.5.00』『Baccarat vol.1.00』『BlackJack vol.1.00』
# 12/02/03
#==============================================================================
module HIDE_PLAY_CARD
  #==============================================================================
  # ■ デバッグ(開発者用)
  #==============================================================================
  DEBUG = false                    # [true/false]
  DEBUG_CARD = {0=>10,1=>7,2=>1,3=>15,4=>26,5=>27,6=>15,7=>23}
  
  #==============================================================================
  # S=1スペード D=2ダイヤ C=3クラブ H=4ハート W=ワイルドカード
  #==============================================================================
  # 【0 = SW】【1 = S1】【2 = S2】【3 = S3】【4 = S4】【5 = S5】【6 = S6】
  # 【7 = S7】【8 = S8】【9 = S9】【10=S10】【11=S11】【12=S12】【13=S13】
  #==============================================================================
  # 【14= DW】【15= D1】【16= D2】【17= D3】【18= D4】【19= D5】【20= D6】
  # 【21= D7】【22= D8】【23= D9】【24=D10】【25=D11】【26=D12】【27=D13】
  #==============================================================================
  # 【28= CW】【29= C1】【30= C2】【31= C3】【32= C4】【33= C5】【34= C6】
  # 【35= C7】【36= C8】【37= C9】【38=C10】【39=C11】【40=C12】【41=C13】
  #==============================================================================
  # 【42= HW】【43= H1】【44= H2】【45= H3】【46= H4】【47= H5】【48= H6】
  # 【49= H7】【50= H8】【51= H9】【52=H10】【53=H11】【54=H12】【55=H13】
  #==============================================================================
  # 【56=  W】
  #==============================================================================
  # ■ カード設定
  #==============================================================================
  SPEED = 2                        # カードのめくり速度(大=遅)
  MOVE = 4                         # カード移動速度(大=速い)
  #==============================================================================
  # ■ グラフィック設定 ※Windowskinsフォルダ内のファイル名を指定
  #==============================================================================
  CARD_S = "card0"                 # カード画像(スペード) 5x5=25
  CARD_D = "card1"                 # カード画像(ダイヤ)   5x5=25
  CARD_C = "card2"                 # カード画像(クラブ)   5x5=25
  CARD_H = "card3"                 # カード画像(ハート)   5x5=25
  CARD_J = "card4"                 # カード画像(表/影)    5x1=5
  WIDTH = 96                       # カード1枚の幅(8で割れる値)
  HEIGHT = 136                     # カード1枚の高さ
  #==============================================================================
  # ■ 音の設定 ※ファイル名を指定 ※Audioフォルダ内 #()のファイル名
  #==============================================================================
  CHENGE_SE = "046-Book01"         # カードめくりの効果音(SE)
end
#==============================================================================
# ■ Window_Play_Cards
#==============================================================================
class Window_Play_Cards
  include HIDE_PLAY_CARD
  #--------------------------------------------------------------------------
  # ■ 公開インスタンス変数
  #--------------------------------------------------------------------------
  attr_accessor :play_card
  attr_accessor :card
  attr_accessor :values
  attr_accessor :keys
  attr_accessor :cards
  attr_accessor :numbers
  attr_accessor :marks
  attr_accessor :move
  attr_accessor :distance
  attr_accessor :x_es
  attr_accessor :y_es
  attr_accessor :loop_cards
  #--------------------------------------------------------------------------
  # ■ オブジェクト初期化
  #--------------------------------------------------------------------------
  def initialize(size = 1,joker = false,five = false)
    @size = size
    @joker = joker ; @five = five
    @select = {} ; @old_card = []
    @viewports = [] ; @play_card = []
    @card = {} ; @marks = {} ; @values = {} ; @keys = {}
    @speed = HIDE_PLAY_CARD::SPEED
    @distance = HIDE_PLAY_CARD::MOVE
    @width = HIDE_PLAY_CARD::WIDTH
    @height = HIDE_PLAY_CARD::HEIGHT
    @x_es = {} ; @y_es = {}
    #…………………………………………………………………………………………………
    # ■カードを作成
    #…………………………………………………………………………………………………
    for i in 0...@size
      @card[i] = nil ; @marks[i] = nil ; @keys[i] = true
      @select[i] = 8 ; @values[i] = 8
      @viewports[i] = Viewport.new(0,0,@width,@height)
      @play_card[i] = Sprite.new(@viewports[i])
      @play_card[i].bitmap = Bitmap.new(@width,@height*16)
      @play_card[i].visible = false
      position(i,0,0)
    end
    @plus = 0
    @loop_cards = false
    # □既に引いたカードを初期化
    card_reset
    # □カードの初期化
    card_clear
    card_select?(@select)
    # □カードの更新
    make_card?(@card,[8]*@size)
  end
  #--------------------------------------------------------------------------
  # ■ カードを追加
  #--------------------------------------------------------------------------
  def plus_card(x,y)
    @plus += 1
    n = @size
    @old_card = []
    @card[n] = nil ; @marks[n] = nil ; @keys[n] = true
    @select[n] = 8 ; @values[n] = 8
    @viewports[n] = Viewport.new(x,y,@width,@height)
    @play_card[n] = Sprite.new(@viewports[n])
    @play_card[n].bitmap = Bitmap.new(@width,@height*16)
    @play_card[n].visible = false
    @play_card[n].oy = @height*8
    position(n,x,y)
    @size += 1
    card_select?({@size-1=>8})
  end
  #--------------------------------------------------------------------------
  # ■ 追加カードを開放
  #--------------------------------------------------------------------------
  def minus_card
    if @plus != 0
      s = @size - @plus
      for i in s...@size
        @viewports[i].dispose
        @play_card[i].bitmap.dispose
        @play_card[i].dispose
        @card[i] = nil ; @marks[i] = nil ; @keys[i] = true
        @select[i] = 8 ; @values[i] = 8
      end
      @size -= @plus
      select = {} ; viewports = [] ; play_card = []
      card = {} ; marks = {} ; values = {} ; keys = {}
      for i in 0...@size
        card[i] = @card[i] ; marks[i] = @marks[i] ; keys[i] = @keys[i]
        select[i] = @select[i] ; values[i] = @values[i]
        play_card[i] = @play_card[i]
      end
      @select = select
      @viewports = viewports ; @play_card = play_card
      @card = card ; @marks = marks ; @values = values ; @keys = keys
      @plus = 0
    end
  end
  #--------------------------------------------------------------------------
  # ■ Z座標の更新
  #--------------------------------------------------------------------------
  def z=(z)
    @play_card.each{|a| a.viewport.z = z }
  end
  #--------------------------------------------------------------------------
  # ■ カードの選択(既に引いたカードを除外)
  #--------------------------------------------------------------------------
  def card_select?(nums = @select,d = 0)
    if @loop_cards = true
      @loop_cards = false
    end
    for i in nums.keys
      if nums[i] == 8
        @card[i] = nil
      end
      while @card[i] == nil
        max = @joker ? 57 : 56
        c = rand(max)
        # □デバッグ(カードを直接指定)
        if HIDE_PLAY_CARD::DEBUG
          if @debug_card[d] != nil
            c = @debug_card[d] ; d += 1
          end
        end
        if ! @cards.include?(c)
          @cards.push(c)
          @cards = @cards.uniq
          @card[i] = c
          @marks[i] = mark?(c)
        end
        # □既に引いたカードのループ
        if @cards.size >= (max - @plus - @size)
          @cards = @cards.reverse
          cards = @joker ? [] : [0,14,28,42,57]
          for n in 0...@size
            cards.push(@cards[n])
          end
          @cards = cards.uniq
          @loop_cards = true
        end
      end
    end
    # □カードの描画
    draw_card?(@card)
  end
  #--------------------------------------------------------------------------
  # ■ 既に引いたカードを初期化
  #--------------------------------------------------------------------------
  def card_reset
    @cards = @joker ? [] : [0,14,28,42,57]
  end
  #--------------------------------------------------------------------------
  # ■ カードの初期化(カード交換)
  #--------------------------------------------------------------------------
  def card_clear
    # □デバッグ(カードを直接指定)
    if HIDE_PLAY_CARD::DEBUG
      @debug_card = HIDE_PLAY_CARD::DEBUG_CARD
    else
      @debug_card = {}
    end
    @numbers = []
    @mark = [0]*@size
    @datas = []
    all_hash?(@select,8)
    @card_open = true
    @move = false
    @se_play = false
    all_hash?(@keys,true)
    # □アニメカウントの初期化
    count_zero?
    # □カードの初期状態(裏向き=8)
    all_hash?(@values,8)
  end
  #--------------------------------------------------------------------------
  # ■ ハッシュの更新
  #--------------------------------------------------------------------------
  def all_hash?(hash,key)
    for i in hash.keys
      hash[i] = key
    end
  end
  #--------------------------------------------------------------------------
  # ■ 座標の更新
  #--------------------------------------------------------------------------
  def position(id,x = 0,y = 0)
    unless @play_card[id] == nil
      @x_es[id] = x ; @y_es[id] = y
      @play_card[id].viewport.rect.x = x
      @play_card[id].viewport.rect.y = y
    end
  end
  #--------------------------------------------------------------------------
  # ■ アニメカウントの初期化
  #--------------------------------------------------------------------------
  def count_zero?(count = 8*@speed)
    @card_count = count
  end
  #--------------------------------------------------------------------------
  # ■ カードが表向きの場合trueを返す
  #--------------------------------------------------------------------------
  def open?(id)
    if @play_card[id] == nil
      return false
    end
    if @play_card[id].oy == 0
      return true
    else
      return false
    end
  end
  #--------------------------------------------------------------------------
  # ■ カードのマークを取得
  #--------------------------------------------------------------------------
  def mark?(i)
    case i
    when 0..13  # スペード(0=ワイルドカード)
      return 1
    when 14..27 # ダイヤ(14=ワイルドカード)
      return 2
    when 28..41 # クラブ(28=ワイルドカード)
      return 3
    when 42..55 # ハート(42=ワイルドカード)
      return 4
    when 56     # ジョーカー(ワイルドカード)
      return 0
    end
  end
  #--------------------------------------------------------------------------
  # ■ カードの取得
  #--------------------------------------------------------------------------
  def check_card?(i)
    case @card[i]
    when 0..13 # スペード
      pic = RPG::Cache.windowskin(HIDE_PLAY_CARD::CARD_S)
      num = @card[i]
      @mark[0] += 1
    when 14..27 # ダイヤ
      pic = RPG::Cache.windowskin(HIDE_PLAY_CARD::CARD_D)
      num = @card[i]-14
      @mark[1] += 1
    when 28..41 # クラブ
      pic = RPG::Cache.windowskin(HIDE_PLAY_CARD::CARD_C)
      num = @card[i]-28
      @mark[2] += 1
    when 42..55 # ハート
      pic = RPG::Cache.windowskin(HIDE_PLAY_CARD::CARD_H)
      num = @card[i]-42
      @mark[3] += 1
    when 56 # ジョーカー(ワイルドカード)
      pic = RPG::Cache.windowskin(HIDE_PLAY_CARD::CARD_J)
      num = 0
      @mark[4] = 1
      @mark[0] += 1 ; @mark[1] += 1 ;@mark[2] += 1 ;@mark[3] += 1
    end
    @datas[num] = num
    @numbers.push(num)
    return [pic,num]
  end
  #--------------------------------------------------------------------------
  # ■ カードの描画
  #--------------------------------------------------------------------------
  def draw_card?(card)
    @card = card
    card_clear
    # □カードの描画
    for i in 0...@size
      # □マークの取得
      check = check_card?(i)
      pic = check[0]
      num = check[1]
      case num
      when 0..4
        rx = @width*num ; ry = @height*0
      when 5..9
        rx = @width*(num-5) ; ry = @height*1
      when 10..13
        rx = @width*(num-10) ; ry = @height*2
      end
      #…………………………………………………………………………………………………
      # ■ カードの描画の再描画(17枚)
      #…………………………………………………………………………………………………
      if @card[i] != @old_card[i]
        @play_card[i].bitmap.clear
        @old_card[i] = @card[i]
        w2 = @width/2 ; w4 = @width/4 ; w8 = @width/8
        
        shadow = RPG::Cache.windowskin(HIDE_PLAY_CARD::CARD_J)
        
        # □カードの描画 0(裏)
        @play_card[i].bitmap.blt(0,0,pic,Rect.new(rx,ry,@width,@height))
        # □カードの描画 1,2,3(裏右斜め)
        for n in 1..3
          rect = Rect.new(w8*n,@height*n,@width-n*w4,@height)
          @play_card[i].bitmap.stretch_blt(rect,pic,Rect.new(rx,ry,@width,@height))
          @play_card[i].bitmap.stretch_blt(rect,shadow,Rect.new(@width*2,0,@width,@height))
        end
        # □カードの描画 4(裏縦)
        rect = Rect.new(w2-1,@height*4,2,@height)
        @play_card[i].bitmap.stretch_blt(rect,shadow,Rect.new(@width*4,0,@width,@height))
        # □カードの描画 5,6,7(表左斜め)
        for n in 1..3
          rect = Rect.new(w8*(4-n),@height*(n+4),@width-(4-n)*w4,@height)
          @play_card[i].bitmap.stretch_blt(rect,shadow,Rect.new(@width,0,@width,@height))
          @play_card[i].bitmap.stretch_blt(rect,shadow,Rect.new(@width*3,0,@width,@height))
        end
        # □カードの描画 8(縦)
        @play_card[i].bitmap.blt(0,@height*8,shadow,Rect.new(@width,0,@width,@height))
        # □カードの描画 9,10,11(表右斜め)
        for n in 1..3
          rect = Rect.new(w8*n,@height*(n+8),@width-n*w4,@height)
          @play_card[i].bitmap.stretch_blt(rect,shadow,Rect.new(@width,0,@width,@height))
          @play_card[i].bitmap.stretch_blt(rect,shadow,Rect.new(@width*2,0,@width,@height))
        end
        # □カードの描画 12(表縦)
        rect = Rect.new(w2-1,@height*12,2,@height)
        @play_card[i].bitmap.stretch_blt(rect,shadow,Rect.new(@width*4,0,@width,@height))
        # □カードの描画 13,14,15(裏左斜め)
        for n in 1..3
          rect = Rect.new(w8*(4-n),@height*(n+12),@width-(4-n)*w4,@height)
          @play_card[i].bitmap.stretch_blt(rect,pic,Rect.new(rx,ry,@width,@height))
          @play_card[i].bitmap.stretch_blt(rect,shadow,Rect.new(@width*3,0,@width,@height))
        end
        # □カードの描画 16(表)
        @play_card[i].bitmap.blt(0,@height*16,pic,Rect.new(rx,ry,@width,@height))
      end
    end
  end
  #--------------------------------------------------------------------------
  # ■ カードの更新
  #--------------------------------------------------------------------------
  def make_card?(card,type = [8]*@size)
    for i in 0...@size
      case type[i]
      when 16
        if @keys[i]
          @play_card[i].oy = 0
        end
      else
        if @keys[i]
          @play_card[i].oy = @height*type[i]
        end
      end
    end
  end
  #--------------------------------------------------------------------------
  # ■ カードのアニメーションを実行
  #--------------------------------------------------------------------------
  def card_anim?(close = true)
    #…………………………………………………………………………………………………
    # ■ 裏から表
    #…………………………………………………………………………………………………
    if close
      card_pos = @speed * 16
    #…………………………………………………………………………………………………
    # ■ 表から裏
    #…………………………………………………………………………………………………
    else
      card_pos = @speed * 8
    end
    #…………………………………………………………………………………………………
    # ■ カードめくりSEを演奏
    #…………………………………………………………………………………………………
    unless @move
      if @keys != se_play?
        $game_system.se_play(RPG::AudioFile.new(HIDE_PLAY_CARD::CHENGE_SE))
      end
    end
    #…………………………………………………………………………………………………
    # ■ アニメーションを実行
    #…………………………………………………………………………………………………
    if @card_count != card_pos
      @card_count += 1
      if @card_count % @speed == 0
        for i in @keys.keys
          if @keys[i] == true
            @values[i] = @card_count/@speed
          end
        end
        @move = true
        make_card?(@keys,@values)
      end
    elsif @card_count >= card_pos
      @move = false
      return true
    end
    return false
  end
  #--------------------------------------------------------------------------
  # ■ カードめくりSEを演奏を許可？
  #--------------------------------------------------------------------------
  def se_play?
    se = {}
    for i in 0...@size
      se[i] = false
    end
    return se
  end
  #--------------------------------------------------------------------------
  # ■ カードの移動を実行
  #--------------------------------------------------------------------------
  def card_move?(cards,new_x,new_y,old_x = @x_es,old_y = @y_es)
    #…………………………………………………………………………………………………
    # ■ アニメーションを実行
    #…………………………………………………………………………………………………
    for i in cards
      x = @distance*1.00
      y = @distance*1.00
      # □X座標の更新
      if old_x[i] - x > new_x[i]
        nx = old_x[i] - x
      elsif old_x[i] + x < new_x[i]
        nx = old_x[i] + x
      else
        nx = new_x[i]
      end
      # □Y座標の更新
      if old_y[i] - y > new_y[i]
        ny = old_y[i] - y
      elsif old_y[i] + y < new_y[i]
        ny = old_y[i] + y
      else
        ny = new_y[i]
      end
      # □XY座標の更新
      position(i,nx,ny)
    end
    x_es = {}
    for k in new_x.keys
      x_es[k] = @x_es[k]
    end
    y_es = {}
    for k in new_y.keys
      y_es[k] = @y_es[k]
    end
    if new_x == x_es && new_y == y_es
      return true
    else
      return false
    end
  end
  #--------------------------------------------------------------------------
  # ■ 解放
  #--------------------------------------------------------------------------
  def dispose
    @viewports.each{ |a| a.dispose }
    @play_card.each{ |a| a.bitmap.dispose }
    @play_card.each{ |a| a.dispose }
  end
end