const HIRA  = 0;
const KATA  = 1;
const KANJI_HIRA = 2;
const KANJI_KATA = 3;
const ALPHA = 4;
const MARK  = "▽";

var SKKDic = function(){
};
var Buffer = function(){
};
var InputMode = function(){
   this.input_mode = ALPHA;
};

var SKK = function(){
   this.r2k = new Roman2KanaConverter();
   this.input_mode = ALPHA;
   this.hiragana_buffer = "";
   this.okurigana = "";
   this.start_translation = false;
   this.last_translated_kanji_list = undefined;

   this.reset_me = function(){
      this.hiragana_buffer = "";
      this.r2k.reset_me("", hiragana_table);
   };
   this.is_kanji_mode = function(){
      return (this.input_mode == KANJI_HIRA ||
              this.input_mode == KANJI_KATA);
   };
   this.is_hira_kata_mode = function(){
      return (this.input_mode == HIRA || this.input_mode == KATA);
   };

   this.change_input_mode = function(c){
      switch(this.input_mode) {
      case HIRA:
         this.input_mode = KANJI_HIRA;
         this.start_translation = true;
         break;
      case KATA:
         this.input_mode = KANJI_KATA;
         this.start_translation = true;
         break;
      case KANJI_HIRA:
         this.input_mode = HIRA;
         this.okurigana = c;
         break;
      case KANJI_KATA:
         this.input_mode = KATA;
         this.okurigana = c;
         break;
      }
   };

   this.store_hiragana = function(kana){
      if (isAlpha(kana[kana.length-1]))
         this.hiragana_buffer += kana.slice(0,-1);
      else
         this.hiragana_buffer += kana;
   };
   this.input_hira_kata = function(textop, c){
      if (textop.kana && this.okurigana) {
         var kanji = this.translate();
         for (var i=0;i<this.last_translated_kanji_list.length;i++)
            this.last_translated_kanji_list[i] =
               (this.last_translated_kanji_list[i] + textop.kana);
         return {kana:kanji.kana+textop.kana, num:kanji.num+textop.num-1};
      } else {
         if (textop.num == 0) {
            return {kana:c, num:0};
         } else {
            if (this.input_mode == KATA)
               return {kana: hira2kata(textop.kana), num:textop.num-1};
            return {kana:textop.kana, num:textop.num-1};
         }
      }
   };
   this.input_kanji = function(textop, c){
      if (textop.num == 0) {
         if (this.start_translation){
            this.start_translation = false;
            return {kana:MARK+c, num:0};
         } else {
            return {kana:c, num:0};
         }
      } else {
         if (this.start_translation) {
            this.start_translation = false;
            return {kana:MARK+textop.kana, num:textop.num-1};
         } else {
            return {kana:textop.kana, num:textop.num-1};
         }
      }
   };
   this.input_char = function(c){
      if (this.input_mode == ALPHA)
         return {kana:c, num:0}

      if (isUpper(c)) {
         c = c.toLowerCase();
         if (!this.okurigana)
            this.change_input_mode(c);
      }

      textop = this.r2k.input_char(c);
      if (textop.kana && this.is_kanji_mode())
         this.store_hiragana(textop.kana);

      if (this.is_hira_kata_mode()) {
         return this.input_hira_kata(textop, c);
      } else if (this.is_kanji_mode()) {
         return this.input_kanji(textop, c);
      }
   };
   
   this.lookup_skkdic = function(){
      var kanji_list = [];
      if (this.okurigana) {
         var okurigana = this.okurigana;
         this.okurigana = "";
         kanji_list = skkdic_okuri[this.hiragana_buffer+okurigana];
      } else {
         this.hiragana_buffer += this.r2k.flush_buffer();
         kanji_list = skkdic_okurinashi[this.hiragana_buffer];
      }
      
      var result = [];
      for (var i=0;i < kanji_list.length;i++){
         if (typeof(kanji_list[i]) == "function")
            result = result.concat(kanji_list[i]());
         else
            result.push(kanji_list[i]);
      }
      return result;
   };
   this.translate = function(){
      if (this.input_mode == KANJI_HIRA)
         this.input_mode = HIRA;
      else if (this.input_mode == KANJI_KATA)
         this.input_mode = KATA;

      var kanji_list = this.lookup_skkdic();
      if (kanji_list == []) {
         return {kana:hits.hiragana_buffer,
            num:this.hiragana_buffer.length+MARK.length};
      }
      var removed_canas = this.hiragana_buffer.length;
      this.hiragana_buffer = "";
      this.last_translated_kanji_list = kanji_list;
      return {kana:kanji_list[0], num:removed_canas+MARK.length};
   };

   this.hit_backspace = function(){
      if (this.r2k.roman_buffer){
         this.r2k.roman_buffer = this.r2k.roman_buffer.slice(0,-1);
      }
      if (this.hiragana_buffer) {
         this.hiragana_buffer = this.hiragana_buffer.slice(0,-1);
         if (this.hiragana_buffer == ""){
            this.switch_to_hira();
            return {kana:"", num:1+MARK.length};
         }
      }
      return {kana:"", num:1};
   };
   this.hit_space = function(){
      if (this.is_kanji_mode())
         return this.translate();
      if (this.is_hira_kata_mode() && this.last_translated_kanji_list) {
         var kanji_list = this.last_translated_kanji_list;
         var num = kanji_list[0].length;

         kanji_list.push(kanji_list.shift());
         this.last_translated_kanji_list = kanji_list;
         return {kana:this.last_translated_kanji_list, num:num};
      }
      return {kana:" ", num:0};
   };

   this.switch_to_alpha = function(){
      this.input_mode = ALPHA;
   };
   this.switch_to_hira = function(){
      this.input_mode = HIRA;
      this.reset_me();
   };
   this.switch_to_kata = function(){
      this.input_mode = KATA;
      this.reset_me();
   };
}


