#!/usr/bin/env ruby

require 'nkf'

class String; def ord; self.unpack('U*') end end

$singlebyte = Array.new(256, 0)
$doublebyte_1st = Array.new(256, 0)
$doublebyte_2nd = Array.new(256, 0)

def is_singlebyte(c)
    return $singlebyte[c] == 1
end

def is_doublebyte(c1, c2)
    return $doublebyte_1st[c1] == 1 && $doublebyte_2nd[c2] == 1
end

def print_mb2ucs_one_char(mb, ucs)
    mblen = mb.length
    ucslen = ucs.length

    if mblen == 0
        mblen = 1
        ucslen = 1
    end

    for i in 0..(mblen - 1)
        printf("\\x%02X", mb[i])
    end
    print " "
    for i in 0..(ucslen - 1)
        printf("<U%04X>", ucs[i])
    end
    print "\n"
end

def dump_mb2ucs_iso2022_1(nkf_opt, escseq)
    for c in 0x00..0xFF
        mb = escseq + c.chr
        ucs = NKF.nkf(nkf_opt, mb)
        if ucs.length > 0
            print_mb2ucs_one_char(
                    mb[escseq.length, mb.length - escseq.length], ucs.ord)
            $singlebyte[c] = 1
        end
    end
end

def dump_mb2ucs_iso2022_2(nkf_opt, escseq)
    for c1 in 0x21..0x7E
        if is_singlebyte(c1)
            next
        end
        for c2 in 0x21..0x7E
            mb = escseq + c1.chr + c2.chr
            ucs = NKF.nkf(nkf_opt, mb)
            if ucs.length > 0
                print_mb2ucs_one_char(
                      mb[escseq.length, mb.length - escseq.length], ucs.ord)
                $doublebyte_1st[c1] = 1
                $doublebyte_2nd[c2] = 1
            end
        end
   end 
end

def dump_mb2ucs_iso2022(codeset, escseq)
    nkf_opt = '--ic='+codeset+' --oc=UTF-8 -x'

    if escseq[1] == '('.ord[0]
        dump_mb2ucs_iso2022_1(nkf_opt, escseq)
    elsif escseq[1] == '$'.ord[0]
        dump_mb2ucs_iso2022_1(nkf_opt, escseq)
        dump_mb2ucs_iso2022_2(nkf_opt, escseq)
    else
        STDERR.print "Unknown escape sequence.\n"
        exit 1
    end
end

if ARGV.size != 2
    STDERR.print "Usage: mb2ucs_iso2022_ruby <codeset> <escape sequence>\n"
    exit 1
else
    codeset = ARGV[0]
    escseq  = ARGV[1]
    escseq = escseq.gsub(/ESC/,"\x1B")
    dump_mb2ucs_iso2022(codeset, escseq)
end

exit 0
