class Infobar

def self.busy(**opts, &block)

def self.busy(**opts, &block)
  instance.busy(**opts, &block)
end

def self.call(**opts)

def self.call(**opts)
  instance.call(**opts)
end

def self.convert_to_message(message)

def self.convert_to_message(message)
  instance.convert_to_message(message)
end

def self.display

def self.display
  infobar.display
end

def busy(frames: :circle1, **opts, &block)

def busy(frames: :circle1, **opts, &block)
  block_given? or raise ArgumentError, 'block is required as an argument'
  duration = opts.delete(:sleep) || 0.1
  reset
  call(**opts | {
    total: Float::INFINITY,
    message: { format: ' %l %te %s ', '%s' => { frames: frames } },
  })
  ib = Thread.new {
    loop do
      +infobar
      sleep duration
    end
  }
  r = nil
  t = Thread.new { r = yield }
  t.join
  ib.kill
  r
end

def call(

def call(
  total:,
  current:   0,
  label:     cc.infobar?&.label || 'Infobar',
  message:   cc.infobar?&.message?&.to_h,
  show:      cc.infobar?&.show?,
  style:     cc.infobar?&.style?&.to_h&.symbolize_keys_recursive,
  as_styles: cc.infobar?&.as_styles?&.to_h&.symbolize_keys_recursive,
  frequency: cc.infobar?&.frequency?,
  update:    false,
  input:     $stdin,
  output:    $stdout
)
  self.label = label
  counter.reset(total: total, current: current)
  display.reset clear: false
  @message = convert_to_message(
    message.full? || '%l %c/%t in %te, ETA %e @%E %s'
  )
  show.nil? or self.show = show
  frequency.nil? or display.frequency = frequency
  style.nil? or self.style = style
  self.as_styles = as_styles
  self.input     = input
  self.output    = output
  update and update(message: @message, force: true)
  self
end

def convert_to_message(message)

def convert_to_message(message)
  case message
  when Message
    message
  when Hash
    Message.new(message)
  when String
    Message.new({format: message})
  else
    @message
  end
end

def finish(message: nil)

def finish(message: nil)
  counter.finish
  @message = convert_to_message(message)
  display.update(message: @message, force: true, counter: counter)
  self
end

def initialize

def initialize
  @counter = Infobar::Counter.new
  @display = Infobar::Display.new
  reset display: false
end

def progress(by: 1, as: nil, message: nil, finish: true, force: false)

def progress(by: 1, as: nil, message: nil, finish: true, force: false)
  counter.progress(by: by, as: as)
  @message = convert_to_message(message)
  display.update(message: @message, force: force, counter: counter)
  finish && counter.done? and finish(message: finish)
  self
end

def reset(display: true)

def reset(display: true)
  @message = convert_to_message('%l %c/%t in %te, ETA %e @%E %s')
  counter.reset(total: 0, current: 0)
  display and self.display.reset
  self
end

def update(message: nil, force: true)

def update(message: nil, force: true)
  @message = convert_to_message(message)
  display.update(message: @message, counter: counter, force: force)
  self
end