require "optparse"

require "color/rgb/jp"
require "color/rgb/jp/compiler/compiler"

class Color::RGB::JP::Compiler::Command

  def self.dispatch
    output = $stdout
    encoding = Color::RGB::JP::Base::Encode::INTERNAL_ENCODING
    pallet = "jis"
    prefix = "##"
    do_compile = true
    generator = "#{$0} #{ARGV * " "}"

    ARGV.options do |opt|
      opt.program_name = "color-japanese"
      opt.version = Color::RGB::JP::VERSION::STRING
      opt.banner = "Usage: jcolorc [options] <source file>"
      opt.separator ""
      opt.separator "  Options:"
      opt.on("-o <output file>", "--output",
             "output file (default: stdout)") {|v| output = v}
      opt.on("-p <color pallet>", "--pallet",
             "color pallet (jis or traditional).",
             "(default: #{pallet})") {|v| pallet = v }
      opt.on("-K<kcode>",
             "specifies KANJI code-set (default: #{encoding})") {|v| encoding = parse_kcode(v) }
      opt.on("-E",
             "output preprocessed ERB script") { do_compile = false }
      opt.on("--prefix=<directive prefix>",
             "prefix the pre-processor directive.",
             "(default: #{prefix})") {|v| prefix = v}
      opt.separator ""
      opt.on_tail("-v", "--version", "print the version"){
        puts opt.ver
        exit 0
      }
      opt.on_tail("-h", "--help", "print this message"){
        puts opt
        exit 0
      }
      opt.parse!
    end

    pallet = parse_pallet(pallet)
    input = parse_input(ARGV)

    check_not_blank(prefix, "Error: no prefix.")
    check_not_blank(output, "Error: no output file.")

    $KCODE = encoding

    jcolorc = Color::RGB::JP::Compiler::Compiler.new(pallet, encoding, prefix, generator)
    jcolorc.execute(input, output, do_compile)
  end

  def self.check_not_blank(v, msg)
    error_exit(msg, 1) if v.nil? or v == ""
  end

  def self.parse_input(args)
    case args.length
    when 0
      $stdin
    when 1
      ARGV.shift
    else
      error_exit("Error: too many source file.", 1)
    end
  end

  def self.parse_kcode(kcode)
    case kcode.downcase
    when "e", "euc", /\Aeuc[_-]?jp/
      "EUC-JP"
    when "s", "sjis", /\Ashift[_-]?jis\z/
      "Shift_JIS"
    when "u", /\Autf[_-]?8\z/
      "UTF-8"
    else
      error_exit("invalid KCODE #{kcode.dump}", 1)
    end
  end

  def self.parse_pallet(pallet_name)
    case pallet_name
    when /\Ajis/i
      Color::RGB::JP::JISZ8102
    when /\Atrad/i
      Color::RGB::JP::Traditional
    else
      error_exit("invalid pallet name `#{pallet_name}': jis or traditional", 1)
    end
  end

  def self.error_exit(msg, status)
    $stderr.puts msg if msg
    $stderr.puts ARGV.options
    exit status
  end
end
