module AR
  class Gauge
    attr_accessor :value
    attr_accessor :max_value
    attr_accessor :modifiers


    def initialize params={}
      self.value = params[:value] || 0
      self.max_value = params[:max_value] || 0
      self.modifiers = params[:modifiers] || []
    end

    def add_modifier mod
      raise "cant add another mod from the same source" if find_modifier_by_source(mod.source)
      self.modifiers.push mod
    end

    def unload_data
      ret = {value: self.value, max_value: self.max_value, modifiers: []}
      self.modifiers.each do |m|
        tmp = {value: 0, source: ""}
        tmp[:value] = m.value
        tmp[:source] = m.source
        ret[:modifiers].push tmp
      end
      ret
    end

    def load_data d
      self.value = d["value"] || d[:value]
      self.max_value = d["max_value"] || d[:max_value]
      mods = d["modifiers"] || d[:modifiers]

      mods.each do |m|
        v  = m["value"] || m[:value]
        s = m[:source] || m["source"]
        self.modify v, s
      end
      self
    end

    def find_modifier_by_source s
      self.modifiers.select{|m| m.source == s}.last
    end


    def delete_modifier_by_source s
      mod = find_modifier_by_source s
      return if mod.nil? 
      self.modifiers.delete mod
      mod
    end

    def modified_value
      modified_amount self.value
    end

    def modified_max
      modified_amount self.max_value
    end


    def change_current v
      self.value += v
    end 
    
    def change_max v
      self.max_value += v
    end


    def change_current_and_max v
      self.change_current v
      self.change_max v
    end



    def modify value, source
      m = (Modifier.new value, source)
      self.add_modifier m 
      m
    end




    class Modifier
      attr_accessor :value
      attr_accessor :source

      def initialize params
        self.value = params[:value]
        self.source = params[:source]
      end

    end

     
    private
    def modified_amount v
      amount = modifiers.map{|m| m.value }.reduce(:+)
      unless amount.nil?
        v + amount 
      else
        v
      end
    end


  end
end
