#encoding: UTF-8
class Action
	attr_accessor :from_player, :msg
  attr_accessor :id
  def initialize(from_player=true, msg=nil)
    @id = @@id
    @from_player = from_player
    @msg = msg
    @@id += 1 if @from_player
  end
  def player_field
    @from_player ? $game.player_field : $game.opponent_field
  end
  def opponent_field
    @from_player ? $game.opponent_field : $game.player_field
  end
  def run
    #子类定义
  end
  class Reset < Action
    def run
      player_field.reset
      super
    end
  end

  class Deck < Action;  end
  class Side < Deck;  end
  class Go < Reset
    def run
      super
      player_field.hand = player_field.deck.shift(5)
      #player_field.hand.each{|card|card.position = :set}
    end
  end
  class FirstToGo < Go;  end
  class SecondToGo < Go;  end
  class Chat < Action; end
  class Shuffle < Action
    def run
      player_field.deck.shuffle!
      super
    end
  end
  class Note < Action
    attr_reader :card
    def initialize(from_player, msg, card)
      super(from_player, msg)
      @card = card
    end
  end
  class Coin < Action
    attr_reader :result
    def initialize(from_player, result=rand(1)==0, msg=nil)
      super(from_player, msg)
      @result = result
    end
  end
  class Dice < Action
    attr_reader :result
    def initialize(from_player, result=rand(6)+1, msg=nil)
      super(from_player, msg)
      @result = result
    end
  end
  class ChangePhase < Action
    attr_reader :phase
    def initialize(from_player, phase)
      super(from_player)
      @phase = phase
    end
    def run
      $game.phase = phase
      super
    end
  end
  class Move < Action
    attr_reader :from_pos, :to_pos, :card, :position
    def initialize(from_player, from_pos, to_pos=nil, card=Card::Unknown, msg=nil, position=nil)
      super(from_player, msg)
      @from_pos = from_pos
      @to_pos = to_pos
      @card = card
      @position = position
    end
    def run
      from_field = case @from_pos
      when 0..10
        player_field.field
      when Integer, :hand
        player_field.hand
      when :field
        player_field.field
      when :graveyard
        player_field.graveyard
      when :deck
        player_field.deck
      when :extra
        player_field.extra
      when :removed
        player_field.removed
      else
        $log.warn __FILE__,  '奇怪的from_field'
      end
      
      from_pos = if @from_pos.is_a? Integer
        if @from_pos > 10
          @from_pos - 11
        else
          @from_pos
        end
      elsif @card == :deck
        0
      else
        (@card.is_a?(Game_Card) ? from_field.index(@card) : from_field.index{|card|card.card == @card}) || from_field.index{|card|!card.known?}
      end
      to_field = case @to_pos
      when Integer
        player_field.field
      when :hand
        player_field.hand
      when :graveyard
        player_field.graveyard
      when :deck, :deckbottom
        player_field.deck
      when :extra
        player_field.extra
      when :removed
        player_field.removed
      end
      if from_pos && from_field[from_pos]
        card = case @card
        when Game_Card
          from_field[from_pos] = @card
        when nil, Card::Unknown
          from_field[from_pos]
        when Card
          from_field[from_pos].card = @card
          from_field[from_pos]
        when :deck
          player_field.deck.first
        end
        if @to_pos
          if from_field == player_field.field
            from_field[from_pos] = nil
          else
            from_field.delete_at from_pos
          end
        end
      else
        card = @card == :deck ?  player_field.deck.first : Game_Card.new(@card)
        $log.warn("似乎凭空产生了卡片？"){self.inspect}
      end
      if @position
        if @position == :"face-up"
          if card.position != :attack and (6..10).include?(@to_pos || @from_pos) #里侧表示的怪兽
            card.position = :defense
          else
            card.position = :attack
          end
        else
          card.position = @position
        end
      end
      if @to_pos
        if @to_pos.is_a? Integer
          to_field[@to_pos] = card
        elsif @to_pos == :hand or @to_pos == :deckbottom
          to_field << card
        else
          to_field.unshift card
        end
      end
      super
    end
  end
  class Set < Move
    def initialize(from_player, from_pos, to_pos, card)
      super(from_player, from_pos, to_pos, card, nil, :set)
    end
  end
  class Activate < Move
    def initialize(from_player, from_pos, to_pos, card)
      super(from_player, from_pos, to_pos, card, nil, :attack)
    end
  end
  class Summon < Move
    def initialize(from_player, from_pos, to_pos, card, msg=nil)
      super(from_player, from_pos, to_pos, card, msg, :attack)
    end
  end
  class SpecialSummon < Move
    def initialize(from_player, from_pos, to_pos, card, msg=nil, position=:attack)
      super(from_player, from_pos, to_pos, card, msg, position)
    end
  end
  class SendToGraveyard < Move
    def initialize(from_player, from_pos, card)
      super(from_player, from_pos, :graveyard, card, nil, :attack)
    end
  end
  class Remove < Move
    def initialize(from_player, from_pos, card)
      super(from_player, from_pos, :removed, card, nil, :attack)
    end
  end
  class ReturnToHand < Move
    def initialize(from_player, from_pos, card)
      super(from_player, from_pos, :hand, card, nil, :set)
    end
  end
  class ReturnToDeck < Move
    def initialize(from_player, from_pos, card)
      super(from_player, from_pos, :deck, card, nil, :set)
    end
  end
  class ReturnToDeckBottom < Move
    def initialize(from_player, from_pos, card)
      super(from_player, from_pos, :deckbottom, card, nil, :set)
    end
  end
  class ReturnToExtra < Move
    def initialize(from_player, from_pos, card)
      super(from_player, from_pos, :extra, card, nil, :set)
    end
  end
  class Control < Move
    def initialize(from_player, from_pos, card)
      super(from_player, from_pos, :opponent, card)
    end
  end
  class Tribute < SendToGraveyard;  end
  class Discard < SendToGraveyard;  end
  class ChangePosition < Move
    def initialize(from_player, from_pos, card, position)
      super(from_player, from_pos, from_pos, card, nil, position)
    end
  end
  class Flip < ChangePosition
    def initialize(from_player, from_pos, card, position=:defense)
      super(from_player, from_pos, card, position)
    end
  end
  class FlipSummon < Flip
    def initialize(from_player, from_pos, card)
      super(from_player, from_pos, card, :attack)
    end
  end
  class Draw < Move
    def initialize(from_player=true, msg=nil)
      @from_player = from_player
      super(from_player, :deck, :hand, :deck, msg, :set)
    end
  end
  class MultiDraw < Action
    def initialize(from_player, count, msg=nil)
      super(from_player, msg)
      @count = count
    end
    def run
      super
      player_field.hand += player_field.deck.shift(@count)
    end
  end
  class RefreshField < Action
    attr_reader :field
    def initialize(from_player, field, msg=nil)
      super(from_player, msg)
      @field = field
    end
    def run
      super
      return if @field.is_a? Game_Field #本地信息，无需处理。
      player_field.lp = @field[:lp]
      if player_field.hand.size > @field[:hand]
        player_field.hand.pop(player_field.hand.size-@field[:hand])
      elsif player_field.hand.size < @field[:hand]
        (@field[:hand]-player_field.hand.size).times{player_field.hand.push Game_Card.new(Card::Unknown)}
      end
      if player_field.deck.size > @field[:deck]
        player_field.deck.pop(player_field.deck.size-@field[:deck])
      elsif player_field.deck.size < @field[:deck]
        (@field[:deck]-player_field.deck.size).times{player_field.deck.push Game_Card.new(Card::Unknown)}
      end
      if player_field.graveyard.size > @field[:graveyard]
        player_field.graveyard.pop(player_field.graveyard.size-@field[:graveyard])
      elsif player_field.graveyard.size < @field[:graveyard]
        (@field[:graveyard]-player_field.graveyard.size).times{player_field.graveyard.push Game_Card.new(Card::Unknown)}
      end
      (0..10).each do |pos|
        if @field[pos]
          player_field.field[pos] ||= Game_Card.new(@field[pos][:card])
          player_field.field[pos].card = @field[pos][:card]
          player_field.field[pos].position = @field[pos][:position]
        else
          player_field.field[pos] = nil
        end
      end
    end
  end

  class TurnEnd < RefreshField
    attr_reader :turn
    def initialize(from_player, field, turn, msg=nil)
      super(from_player, field, msg)
      @turn = turn
    end
    def run
      $game.phase = :DP
      $game.turn = @turn.next
      $game.turn_player = !from_player
      super
    end
  end
  class Show < Move
    attr_reader :from_pos, :card
    def initialize(from_player, from_pos, card)
      super(from_player, from_pos, nil, card)
      @from_pos = from_pos
      @card = card
    end
  end
  class MultiShow < Action
    def initialize(from_player, cards)
      super(from_player, nil)
      @cards = cards
    end
  end
  class EffectActivate < Move
    def initialize(from_player, from_pos, card)
      @from_player = from_player
      if (0..10).include?(from_pos)
        position = :"face-up"
      else
        position = nil
      end
      super(from_player, from_pos, nil, card, nil, position)
    end
  end
  class ViewDeck < Action;  end
  class LP < Action
    attr_accessor :operator, :value
    def initialize(from_player, operator, value)
      super(from_player)
      @operator = operator
      @value = value
    end
    def run
      case operator
      when :lose
        player_field.lp -= @value
      when :increase
        player_field.lp += @value
      when :become
        player_field.lp = @value
      end
    end
  end
  class Unknown < Action
    def initialize(str)
      @str = str
      $log.info  'unkonwn action ' + str
    end
    def run
      $log.info  'unkonwn action run ' + @str
    end
  end
  def self.reset
    @@id=1
  end
  reset
end