module AR::Game::AttackBehavior 
  MISS = "miss"
  HIT = "hit"
  CRIT = "crit"
  HIT_THRESHOLD = 7
  
  #add attr_accessor properties here... 
  #if you don't need them serialized on save

  #...initialize them here
  def self.init ar_object 
    ar_object.class.attr_serializeable :attack_techniques do |techs, kase|
      case kase
      when :load
        techs.map.map{|t| Object.const_get(t.to_s).new}
      when :unload
        techs.map(&:class)
      end
    end

    ar_object.class.attr_serializeable :unarmed_damage_dice 
    ar_object.unarmed_damage_dice = 4
    ar_object.attack_techniques=[]
  end

  def self.hit_contest hitter, hitee

    base =  hitter.gauge("accuracy").modified_value
    r = rand(1..20)
    hit_roll = base + r
    avoidance = hitee.gauge("avoidance").modified_value
    diff = hit_roll - avoidance
    result = nil

    if diff > HIT_THRESHOLD 
      result = HIT
      
      crit_gauge = hitter.gauge("critical_hit")
      unless crit_gauge.nil?
        crit_roll = rand(1..100)
        weak_point_bonus = hitter.weak_points_for hitee

        threshold = crit_gauge.modified_current + weak_point_bonus
        AR.log("CRIT ROLL: (#{crit_roll} < #{threshold}?) for #{hitter.tag}")
        if crit_roll <= threshold 
          result = CRIT
        end
      end

    else
      result = MISS
    end

    AR.log("HIT ROLL (#{hitter.name} vs #{hitee.name}): (#{r}+#{base}) - #{avoidance} = #{diff} (#{result})")
    result
  end

  def self.do_hit_on_hit_success
    AR::Events::Resolution.new when: AR::Events::HitSuccess, as: "hitter" do |e|
      hitter = e.hitter
      hitee = e.hitee
      tech  = e.technique
      results = tech.perform(performer: hitter, target: hitee)
      dmg_evt = nil

      if results.class == Array
        dmg_evt = results.select{|e| e.class==AR::Events::DamageReceived}.last
      else
        dmg_evt = results if results.class==AR::Events::DamageReceived
      end
      dmg_bonus = hitter.gauge("melee_dmg_bonus")

      if !dmg_bonus.nil? and !dmg_evt.nil?
        AR.log("ATTACK: adding melee dmg modifier: #{dmg_bonus.modified_current}")
        dmg_evt.damage_amount += dmg_bonus.modified_current
      end


      if e.is_critical
        AR.log("ATTACK: damage doubling for critical")
        dmg_evt.damage_amount += dmg_evt.damage_amount
      end

      
      results 
    end
  end

  def self.do_contest_on_hit_attempt
    AR::Events::Resolution.new when: AR::Events::HitAttempt, as: "hitter" do |e|
      hitter = e.hitter
      hitee = e.hitee
      tech  = e.technique
      
      case hit_contest(hitter, hitee)
      when CRIT 
        AR::Events::HitSuccess.new hitter: hitter, hitee: hitee, technique: tech, is_critical: true
      when HIT
        AR::Events::HitSuccess.new hitter: hitter, hitee: hitee, technique: tech
      when MISS
        AR::Events::HitFailure.new hitter: hitter, hitee: hitee, technique: tech
      end 
    end
  end

  def self.extended ar_object
    self.init ar_object
    ar_object.resolutions.push do_contest_on_hit_attempt
    ar_object.resolutions.push do_hit_on_hit_success
  end 




end
