module Commander::UI

def applescript(script)

def applescript(script)
  `osascript -e "#{ script.gsub('"', '\"') }"`
end

def ask_editor(input = nil, preferred_editor = nil)

def ask_editor(input = nil, preferred_editor = nil)
  editor = available_editor preferred_editor
  program = Commander::Runner.instance.program(:name).downcase rescue 'commander'
  tmpfile = Tempfile.new program
  begin
    tmpfile.write input if input
    tmpfile.close
    system("#{editor} #{tmpfile.path.shellescape}") ? IO.read(tmpfile.path) : nil
  ensure
    tmpfile.unlink
  end
end

def available_editor(preferred = nil)

def available_editor(preferred = nil)
  [preferred, ENV['EDITOR'], 'mate -w', 'vim', 'vi', 'emacs', 'nano', 'pico']
    .compact
    .find { |name| system("hash #{name.split.first} 2>&-") }
end

def choose(message = nil, *choices, &block)

def choose(message = nil, *choices, &block)
  say message if message
  super(*choices, &block)
end

def color(*args)

def color(*args)
  say HighLine.default_instance.color(*args)
end

def converse(prompt, responses = {})

def converse(prompt, responses = {})
  i, commands = 0, responses.map { |_key, value| value.inspect }.join(',')
  statement = responses.inject '' do |inner_statement, (key, value)|
    inner_statement <<
    (
      (i += 1) == 1 ?
      %(if response is "#{value}" then\n) :
      %(else if response is "#{value}" then\n)
    ) <<
    %(do shell script "echo '#{key}'"\n)
  end
  applescript(
    %(
    tell application "SpeechRecognitionServer"
      set response to listen for {#{commands}} with prompt "#{prompt}"
      #{statement}
      end if
    end tell
    )
  ).strip.to_sym
end

def enable_paging

def enable_paging
  return unless $stdout.tty?
  return unless Process.respond_to? :fork
  read, write = IO.pipe
  # Kernel.fork is not supported on all platforms and configurations.
  # As of Ruby 1.9, `Process.respond_to? :fork` should return false on
  # configurations that don't support it, but versions before 1.9 don't
  # seem to do this reliably and instead raise a NotImplementedError
  # (which is rescued below).
  if Kernel.fork
    $stdin.reopen read
    write.close
    read.close
    Kernel.select [$stdin]
    ENV['LESS'] = 'FSRX' unless ENV.key? 'LESS'
    pager = ENV['PAGER'] || 'less'
    exec pager rescue exec '/bin/sh', '-c', pager
  else
    # subprocess
    $stdout.reopen write
    $stderr.reopen write if $stderr.tty?
    write.close
    read.close
  end
rescue NotImplementedError
ensure
  write.close if write && !write.closed?
  read.close if read && !read.closed?
end

def io(input = nil, output = nil, &block)

def io(input = nil, output = nil, &block)
  orig_stdin, orig_stdout = $stdin, $stdout
  $stdin = File.new(input) if input
  $stdout = File.new(output, 'r+') if output
  return unless block
  yield
  $stdin, $stdout = orig_stdin, orig_stdout
  reset_io
end

def log(action, *args)

def log(action, *args)
  say format('%15s  %s', action, args.join(' '))
end

def password(message = 'Password: ', mask = '*')

def password(message = 'Password: ', mask = '*')
  pass = ask(message) { |q| q.echo = mask }
  pass = password message, mask if pass.nil? || pass.empty?
  pass
end

def progress(arr, options = {})

def progress(arr, options = {})
  bar = ProgressBar.new arr.length, options
  bar.show
  arr.each { |v| bar.increment yield(v) }
end

def replace_tokens(str, hash) #:nodoc:

:nodoc:
def replace_tokens(str, hash) #:nodoc:
  hash.inject(str) do |string, (key, value)|
    string.gsub ":#{key}", value.to_s
  end
end

def say_error(*args)

def say_error(*args)
  args.each do |arg|
    say HighLine.default_instance.color(arg, :red)
  end
end

def say_ok(*args)

def say_ok(*args)
  args.each do |arg|
    say HighLine.default_instance.color(arg, :green)
  end
end

def say_warning(*args)

def say_warning(*args)
  args.each do |arg|
    say HighLine.default_instance.color(arg, :yellow)
  end
end

def speak(message, voice = :Alex, rate = 175)

def speak(message, voice = :Alex, rate = 175)
  Thread.new { applescript "say #{message.inspect} using #{voice.to_s.inspect} speaking rate #{rate}" }
end