#!/usr/bin/ruby
#
# Ducksay
#
# A response to Ruby Quiz of the Week #52 [ruby-talk:161834]
#
# It's a script that generates funny talking animals, like the one at
# http://www.cowsay.net/
#
# From the command line, use --help for usage info.
# Basically, you can give some parameters, and you have to give the duck's
# speech on STDIN.
#
# Create a new template by subclassing Duck.
#
# You can also use it from inside Ruby -- use the say method of Duck, etc.
#
# Author: Dave Burt <dave at burt.id.au>
#
# Created: 23 Oct 2005
#
# Last modified: 24 Oct 2005
#
# Fine print: Provided as is. Use at your own risk. Unauthorized copying is
#             not disallowed. Credit's appreciated if you use my code. I'd
#             appreciate seeing any modifications you make to it.

class String
  def width
    inject(0) {|w, line| [w, line.chomp.size].max }
  end
  def height
    to_a.size
  end
  def top
    to_a.first
  end
  def middle
    to_a.values_at(1..-1)
  end
  def bottom
    to_a.last
  end
end

class Duck
  def self.say(speech="quack?", *args)
    balloon(speech) + body(*args)
  end

  def self.balloon(speech)
    " _#{ '_' * speech.width }_\n" +
      if speech.chomp =~ /\n/
        "/ %-#{ speech.width }s \\\n" % speech.top.chomp +
        speech.middle.map do |line|
          "| %-#{ speech.width }s |\n" % line.chomp
        end.join +
        "\\ %-#{ speech.width }s /\n" % speech.bottom.chomp
      else
        "< #{ speech.chomp } >\n"
      end +
    " -#{ '-' * speech.width }-\n"
  end

  def self.body(thoughts='\\', eyes='cc', tongue='  ')
"       #{thoughts}
        #{thoughts}
        _   ___
       / \\ /   \\
       \\. |: #{eyes}|
        (.|:,---,
        (.|: \\( |
        (.    y-'
         \\ _ / #{tongue}
          m m
"
  end
end

class Cow < Duck
  def self.body(thoughts='\\', eyes='oo', tongue='  ')
"  #{thoughts}   ^__^
   #{thoughts}  (#{eyes})\\_______
      (__)\\       )\\/\\
       #{tongue} ||----w |
          ||     ||
"
  end
end

class DuckOnWater < Duck
  def self.body(thoughts='\\', eyes=', tongue='>')
"    #{thoughts}
     ` #{tongue[0, 1]}(#{eyes[0, 1]})____,
        (` =~~/
~^~^~^~^~`---'^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~^~
"
  end
end

if $0 == __FILE__
  if ARGV.include?("--help")
    puts "usage: #$0 animal thoughts eyes tongue <speech\n"
    puts "animals: Duck Cow DuckOnWater\n"
    puts "e.g.: #$0 DuckOnWater o x ) </etc/fortune\n"
  else
    animal = Object.const_get(ARGV.shift) rescue Duck
    puts animal.say(STDIN.read, *ARGV)
  end
end