class Infobar::Counter

def done?

def done?
  @current >= @total
end

def eta

def eta
  if @finished
    @finished
  else
    Time.now + time_remaining
  end
end

def finish

def finish
  @finished = Time.now
  self
end

def finished?

def finished?
  @finished
end

def initialize

def initialize
  reset
end

def progress(by: 1, as: nil)

def progress(by: 1, as: nil)
  if !finished? && by >= 1
    now = Time.now
    @start ||= now
    @timer.add(now, by)
    @current += by
    @as[as] += by
  end
  self
end

def progressed

def progressed
  if @total.zero?
    0.0
  else
    @current / @total.to_f
  end
end

def reset(total: 0, current: 0)

def reset(total: 0, current: 0)
  @current  = current
  @as       = Hash.new(0).update(nil => current)
  @total    = total
  @start    = nil
  @finished = false
  @timer    = Infobar::Timer.new
  self
end

def started?

def started?
  @start
end

def time_elapsed

def time_elapsed
  case
  when @finished && @start
    @finished - @start
  when @start
    Time.now - @start
  else
    0.0
  end
end

def time_remaining

def time_remaining
  if @finished
    0.0
  else
    average_time * to_go
  end
end

def to_go

def to_go
  [ total - current, 0 ].max
end

def to_go?

def to_go?
  to_go.nonzero?
end

def to_s

def to_s
  n = -> k { k.nil? ? 'default' : k.to_s }
  width = -@as.keys.map(&n).max_by(&:size).to_i
  @as.map { |key, value| "%#{width}s: %d" % [ n.(key), value ] }.join(?\n)
end

def total_time

def total_time
  time_elapsed + time_remaining
end