# encoding: utf-8

require 'nkf'
require 'conv_ja_char/version'
require 'conv_ja_char/constants/katakana_romaji'
require 'conv_ja_char/normalization'
require 'conv_ja_char/check_char'

# conv_ja_char return value
# something romaji string : when ConvJaChar.to_romaji successes
# nil : when ConvJaChar.to_romaji has some errors

# conv_ja_char does not accept Kanji char currently.

module ConvJaChar
  class << self
    def to_romaji(str, option)
      return str unless str.nil?
      if str == ''
        return str
      end

      @opt = ''
      set_option(option)

      binding.pry

      if ConvJaChar::CharTypeCheck::kanji?(str) != nil
        p "there seems to be Kanji char in #{str}. conv_ja_char does not accept Kanji char currently."
        return str
      end

      binding.pry

      @t = set_char_table(@opt)

      @chars = ConvJaChar::Normalization.kana(str).split(//u)

      @romaji = ''
      @pos = 0
      while @pos < @chars.size
        @c = @chars[@pos]

        if @c == (' ' || '$' || '-' || '\'')
          @romaji += @c
          @pos += 1
          next
        end

        if ConvJaChar::CharTypeCheck::symbol?(@c) != nil
          @romaji += @c
          @pos += 1
          next
        end

        @c_next = ''
        set_next_char

        case @c
          when 'ン'
            process_nasal_sound_change
            next
          when 'ッ'
            process_sound_change_to_double_consonant
            next
          when 'ウ','キ','ギ','ク','グ','シ','ジ','チ','ヂ','テ','デ','ニ','ヒ','ビ','ピ','フ','ミ','リ','ヴ'
            if @c_next.nil?
              process_normal_char
              next
            end
            if SMALL_KANA_FOR_CONTRACTED_SOUND.include?(@c_next)
              process_contracted_sound
              next
            else
              process_normal_char
              next
            end
          else
            process_normal_char
        end
      end

      @romaji
    end

    private

      def set_option(option)
        case option
        when 'Kunrei'
          @opt = 'Kunrei'
        when 'Hebon'
          @opt = 'Hebon'
        else
          @opt = 'Kunrei'
        end
      end

      def set_next_char
        if (@pos + 1) < @chars.size
          @c_next = @chars[@pos+1]
        else
          @c_next = nil
        end
      end

      def set_char_table(op)
        case op
          when 'Hebon'
            ConvJaChar::KATANA_TO_HEBON_FORM
          when 'Kunrei'
            ConvJaChar::KATANA_TO_KUNREI_FORM
          else
            ConvJaChar::KATANA_TO_KUNREI_FORM
        end
      end

      def process_normal_char
          @romaji += @t[@c]
          @pos += 1
      end

      def process_nasal_sound_change(op) # ex.:'ン'
        s = @t[@c_next]

        case op
          when 'Hebon'
            if ['p','b','m'].include?(s[0])
              @romaji += 'm'
            else
              @romaji += @t[@c]
              if ['a','i','u','e','o','y','n'].include?(s[0])
                @romaji += '\''
              end
            end
          when 'Kunrei'
            @romaji += @t[@c]
            if ['a','i','u','e','o','y','n'].include?(s[0])
              @romaji += '\''
            end
        end

        @pos += 1
      end

      def process_sound_change_to_double_consonant # ex.:'ッ'
        r = @t[@c_next]
        if @c_next == DOUBLE_CONSONANT_SOUND || ['a','i','u','e','o','n',nil].include?(r[0]) || r.nil?
          @romaji += 'xtsu'
        else
          @romaji += r[0].slice(0,1)
        end
        @pos += 1
      end

      def process_contracted_sound # ex.:'キャ'
        s = @c + @c_next
        @romaji += @t[s]
        @pos += 2
      end
  end

  # class Romaji TODO: to be implemented
  # class Kanji TODO: to be implemented
end