class SumSum < Hash
  def initialize(*args)
    @parent = args.pop if args[-1].is_a?(self.class)
    @name = args.shift
    @args = args.compact.dup
    @count = 0
    super()
  end
  
  attr_reader :name, :args, :count, :parent
  
  def add(hash, increase_by=1)
    key = hash[name]
    @count = @count + increase_by
    unless bottom?
      self[key] ||= SumSum.new(*args, self)
      self[key].add(hash, increase_by)
    end
    self
  end
  
  def share
    root? ? 1.0 : count/parent.count.to_f
  end
  
  def sort!
    values.each(&:sort!) unless bottom?
    to_a.tap do |array|
      array.reverse!(&:count)
      clear
      array.each{|k, v| self[k] = v }
    end
    self
  end
  
  def root?
    parent.nil?
  end
  
  def bottom?
    name.nil?
  end
  
  def inspect
    bottom? ? "#{count}" : "{#{name}:#{count} #{super.gsub(/^\{|\}$/, "")}}"
  end
end