/*
 * $Id: touroku.c,v 1.2 2001/06/14 18:16:13 ura Exp $
 */

/*
 * FreeWnn is a network-extensible Kana-to-Kanji conversion system.
 * This file is part of FreeWnn.
 * 
 * Copyright Kyoto University Research Institute for Mathematical Sciences
 *                 1987, 1988, 1989, 1990, 1991, 1992
 * Copyright OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1999
 * Copyright ASTEC, Inc. 1987, 1988, 1989, 1990, 1991, 1992
 * Copyright 1991, 1992 by Massachusetts Institute of Technology
 *
 * Author: OMRON SOFTWARE Co., Ltd. <freewnn@rd.kyoto.omronsoft.co.jp>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Emacs; see the file COPYING.  If not, write to the
 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * Commentary:
 *
 * Change log:
 *
 * Last modified date: 8,Feb.1999
 *
 * Code:
 *
 */
/*      Version 4.0
 */
#include <stdio.h>
#include "jslib.h"
#include "commonhd.h"
#include "sdefine.h"
#include "xjutil.h"
#include "sxheader.h"
#include "rk_spclval.h"
#include "rk_fundecl.h"
#include "xext.h"

static int touroku_start, touroku_end;
/* these are used only for making yomi string for registered kanji */


int touroku_mode = 0;

static void
freeze_messages ()
{
  register int i;

  for (i = 0; i < JCLIENTS; i++)
    {
      freeze_box (cur_root->jutil->mes_button[i]);
    }
}

static void
unfreeze_messages ()
{
  register int i;

  for (i = 0; i < JCLIENTS; i++)
    {
      unfreeze_box (cur_root->jutil->mes_button[i]);
    }
}

static int
change_mode (mode)
     int mode;
{
  int ret = EXECUTE;

  if (mode == MESSAGE1)
    {
      ret = KANJI_IN_START;
    }
  else if (mode == MESSAGE2)
    {
      ret = YOMI_IN;
    }
  else if (mode == MESSAGE3)
    {
      ret = HINSI_IN;
    }
  else if (mode == MESSAGE4)
    {
      ret = JISHO_IN;
    }
  return (ret);
}

static void
redraw_old_message (mode)
     int mode;
{
  register JutilRec *jutil = cur_root->jutil;

  if (mode == MESSAGE0)
    {
      unfreeze_box (jutil->button[EXEC_W]);
      if (jutil->button[EXEC_W]->in)
        {
          reverse_box (jutil->button[EXEC_W], jutil->button[EXEC_W]->invertgc);
          jutil->button[EXEC_W]->in = 0;
        }
    }
  else
    {
      changecolor_box (jutil->mes_button[mode], 0, 0, cur_root->bg, BoxBorderPixel);
      jutil->mes_button[mode]->in = (char) 0;
    }
}

static void
redraw_new_message (mode)
     int mode;
{
  register JutilRec *jutil = cur_root->jutil;

  if (mode == MESSAGE0)
    {
      if (!jutil->button[EXEC_W]->in)
        {
          reverse_box (jutil->button[EXEC_W], jutil->button[EXEC_W]->invertgc);
          jutil->button[EXEC_W]->in = 1;
        }
      freeze_box (jutil->button[EXEC_W]);
    }
  else
    {
      changecolor_box (jutil->mes_button[mode], 0, 0, cur_root->fg, BoxBorderPixel);
      jutil->mes_button[mode]->in = (char) 1;
    }
}

static void
xw_exec_mode ()
{
  unsigned int c1;
  int ret;
  JutilRec *jutil = cur_root->jutil;

  jutil->mes_mode = MESSAGE0;
  redraw_new_message (jutil->mes_mode);
  freeze_box (jutil->button[EXEC_W]);
  for (;;)
    {
      c1 = keyin ();
      if (xjutil->sel_ret == -2)
        {
          touroku_mode = CANCEL;
          xjutil->sel_ret = -1;
          break;
        }
      else if (xjutil->sel_ret == 0)
        {
          touroku_mode = TOUROKU_GO;
          xjutil->sel_ret = -1;
          break;
        }
      else if (xjutil->sel_ret == 1)
        {
          touroku_mode = change_mode (jutil->mode);
          xjutil->sel_ret = -1;
          break;
        }
      else if ((c1 < 256) && (main_table[9][c1] != NULL))
        {
          if ((ret = (*main_table[9][c1]) ()) == 1)
            {
              if (jutil->mes_mode == MESSAGE0)
                {
                  touroku_mode = TOUROKU_GO;
                }
              else
                {
                  jutil->mode = jutil->mes_mode;
                  touroku_mode = change_mode (jutil->mes_mode);
                }
              break;
            }
          else if (ret == -1)
            {
              touroku_mode = CANCEL;
              break;
            }
        }
      else
        {
          ring_bell ();
        }
    }
  redraw_old_message (jutil->mes_mode);
  if (jutil->mes_mode == MESSAGE0)
    {
      unfreeze_box (jutil->button[EXEC_W]);
    }
/*
        if (cur_root->jutil->button[EXEC_W]->in) {
            reverse_box(jutil->button[EXEC_W], jutil->button[EXEC_W]->invertgc);
            jutil->button[EXEC_W]->in = 0;
        }
    }
*/
}

int
hani_settei_normal (c_b)
     ClientBuf *c_b;
{
  c_b->hanten = 0x04;
  c_b->t_c_p = 0;
  hanten_jutil_mes_title (MESSAGE1, 1);
  c_b->t_m_start = -1;

  c_b->key_table = main_table[5];
  c_b->rk_clear_tbl = romkan_clear_tbl[5];
  c_b->key_in_fun = NULL;
  c_b->redraw_fun = redraw_nisemono;
  c_b->ctrl_code_fun = NULL;
  init_screen ();
  return (0);
}

#ifdef  CHINESE
int
hani_settei_yincod (c_b)
     ClientBuf *c_b;
{
  c_b->hanten = 0x04 | 0x40;
  c_b->t_c_p = 0;
  hanten_jutil_mes_title (MESSAGE1, 1);
  c_b->t_b_st = c_b->t_c_p;
  c_b->t_b_end = c_b->t_c_p + 1;
  c_b->t_m_start = c_b->t_c_p + 1;
  kk_cursor_invisible ();

  c_b->key_table = main_table[5];
  c_b->rk_clear_tbl = romkan_clear_tbl[5];
  c_b->key_in_fun = NULL;
  c_b->redraw_fun = redraw_nisemono;
  c_b->ctrl_code_fun = NULL;
  init_screen ();
  c_b->t_m_start = -1;
  return (0);
}
#endif /* CHINESE */

static int
xw_hani_settei (buffer, buflen)
     w_char *buffer;
     int buflen;
{
  ClientBuf *c_btmp, c_b1;

  c_btmp = c_b;
  c_b = &c_b1;

  c_b->buffer = buffer;
  c_b->buflen = buflen;

  c_b->maxlen = Strlen (buffer);

  freeze_messages ();
  (*hani_settei_func) (c_b);
  if (buffer_in () == -1)
    {
      if (touroku_mode == KANJI_IN_START || touroku_mode == KANJI_IN_END)
        touroku_mode = CANCEL;
      c_b = c_btmp;
      return (-1);
    }
  unfreeze_messages ();
  if (xjutil->sel_ret == -2)
    {
      touroku_mode = CANCEL;
      xjutil->sel_ret = -1;
      c_b = c_btmp;
      return (-1);
    }
  else if (xjutil->sel_ret == 0)
    {
      touroku_mode = TOUROKU_GO;
      xjutil->sel_ret = -1;
      c_b = c_btmp;
      return (0);
    }
  else if (xjutil->sel_ret == 1)
    {
      touroku_mode = change_mode (cur_root->jutil->mode);
      if (touroku_mode == KANJI_IN_START)
        {
          c_b = c_btmp;
          return (0);
        }
    }
  else
    {
      touroku_mode = EXECUTE;
    }
  Strncpy (buffer, buffer + c_b->t_m_start, c_b->t_c_p - c_b->t_m_start);
  buffer[c_b->t_c_p - c_b->t_m_start] = 0;
  touroku_start = c_b->t_m_start;
  touroku_end = c_b->t_c_p;
  c_b = c_btmp;
  return (c_b1.t_c_p - c_b1.t_m_start);
}

void
touroku ()
{
  int i;
  int ud_no, save_ud_no = -1, ud_table[WNN_MAX_JISHO_OF_AN_ENV];
  w_char yomibuf[LENGTHYOMI + 1];
  char *message[4];
  char *message1[4];
  w_char hani_buffer[1024];
  w_char get_buffer[1024];
  char dic_name_heap[2048];
  char save_text[WNN_HINSI_NAME_LEN];
  char *hp = dic_name_heap;
  int hinsi = -1, save_hinsi = -1;
  int tmp;
  char *dict_name[JISHOKOSUU];
  static int current_dic = -1;
  int current = 0;
  int size;
  int kanji_set = 0, yomi_set = 0, hinsi_set = 0, jisho_set = 0;

  cur_bnst_ = get_touroku_data (get_buffer);
  if (update_dic_list () == -1)
    {
      errorkeyin ();
      return;
    }
  for (i = 0, size = 0; i < dic_list_size; i++)
    {
      if ((dicinfo[i].type == WNN_UD_DICT || dicinfo[i].type == WNN_REV_DICT || dicinfo[i].type == CWNN_REV_DICT) && dicinfo[i].rw == 0)
        {
          if (*dicinfo[i].comment)
            {
              sStrcpy (hp, dicinfo[i].comment);
              dict_name[size] = hp;
              hp += strlen (hp) + 1;
            }
          else
            {
              dict_name[size] = dicinfo[i].fname;
            }
          ud_table[size] = i;
          if (current_dic != -1 && dicinfo[i].dic_no == current_dic)
            current = size;
          size++;
        }
    }
  if (size == 0)
    {
      print_msg_getc (msg_get (cd, 99, default_message[99], xjutil->lang), NULL, NULL, NULL);
      return;
    }
  save_ud_no = 0;

  if ((hinsi = get_default_hinsi (save_text)) != -1)
    save_hinsi = hinsi;

  message[0] = msg_get (cd, 93, default_message[93], xjutil->lang);
  message[1] = msg_get (cd, 95, default_message[95], xjutil->lang);
  message[2] = msg_get (cd, 96, default_message[96], xjutil->lang);
  message[3] = msg_get (cd, 97, default_message[97], xjutil->lang);
  message1[0] = message1[1] = message1[2] = message1[3] = NULL;
#ifdef nodef
  message1[2] = hinsi_name;
#endif
  if (size == 1)
    {
      ud_no = 0;
      message1[3] = dict_name[ud_no];
    }

  init_jutil (msg_get (cd, 92, default_message[92], xjutil->lang), msg_get (cd, 92, default_message[92], xjutil->lang), 4, message, message1);
  touroku_mode = KANJI_IN_START;

repeat:
  for (;;)
    {
      switch (touroku_mode)
        {
        case KANJI_IN_START:
          kanji_set = 0;
          change_cur_jutil (MESSAGE1);
          change_mes_title (MESSAGE1, msg_get (cd, 93, default_message[93], xjutil->lang), 1);
          kk_cursor_invisible ();
          JWMline_clear (0);
          kk_cursor_normal ();
          hani_buffer[0] = 0;
          Strcpy (hani_buffer, get_buffer);
          if ((tmp = xw_hani_settei (hani_buffer, 1024)) < 0)
            break;
          if ((tmp = Strlen (hani_buffer)) >= 64)
            {
              print_msg_getc (msg_get (cd, 100, default_message[100], xjutil->lang), NULL, NULL, NULL);
              touroku_mode = KANJI_IN_START;
            }
          else if (tmp > 0)
            {
              kanji_set = 1;
            }
          kk_cursor_invisible ();
          break;
        case YOMI_IN:
          yomi_set = 0;
          for (i = 0; i < LENGTHYOMI + 1; i++)
            {
              yomibuf[i] = 0;
            }
          change_cur_jutil (MESSAGE2);
          hanten_jutil_mes_title (MESSAGE2, 1);
          JWMline_clear (0);
          kk_cursor_normal ();
          xjutil->sel_ret = -1;
          freeze_messages ();
          tmp = kana_in ((0x08 | 0x20), yomibuf, LENGTHYOMI);
          unfreeze_messages ();
          if (Strlen (yomibuf) > 0)
            yomi_set = 1;
          if (tmp == -1 || xjutil->sel_ret == -2)
            {
              touroku_mode = CANCEL;
            }
          else if (xjutil->sel_ret == 0)
            {
              touroku_mode = TOUROKU_GO;
            }
          else if (xjutil->sel_ret == 1)
            {
              touroku_mode = change_mode (cur_root->jutil->mode);
            }
          else
            {
              touroku_mode = EXECUTE;
            }
          hanten_jutil_mes_title (MESSAGE2, 0);
          kk_cursor_invisible ();
          break;
        case HINSI_IN:
          hinsi_set = 0;
          change_cur_jutil (MESSAGE3);
          hanten_jutil_mes_title (MESSAGE3, 1);
          JWMline_clear (0);
          kk_cursor_invisible ();
          if ((hinsi = hinsi_in (save_text)) == -1)
            {
              if (save_hinsi != -1)
                {
                  hinsi = save_hinsi;
                  JWMline_clear (0);
                  xw_jutil_write_msg (save_text);
                  hinsi_set = 1;
                }
            }
          else
            {
              save_hinsi = hinsi;
              hinsi_set = 1;
            }
          hanten_jutil_mes_title (MESSAGE3, 0);
          if (touroku_mode == HINSI_IN)
            touroku_mode = EXECUTE;
          break;
        case JISHO_IN:
          if (size == 1)
            {
              touroku_mode = EXECUTE;
              jisho_set = 1;
              break;
            }
          jisho_set = 0;
          change_cur_jutil (MESSAGE4);
          hanten_jutil_mes_title (MESSAGE4, 1);
          JWMline_clear (0);
          kk_cursor_invisible ();
          ud_no = xw_select_one_element_call (dict_name, size, current, msg_get (cd, 98, default_message[98], xjutil->lang));
          if (ud_no == -1)
            {
              if (save_ud_no != -1)
                {
                  ud_no = save_ud_no;
                  JWMline_clear (0);
                  xw_jutil_write_msg (dict_name[ud_no]);
                  jisho_set = 1;
                }
            }
          else
            {
              save_ud_no = ud_no;
              xw_jutil_write_msg (dict_name[ud_no]);
              jisho_set = 1;
            }
          hanten_jutil_mes_title (MESSAGE4, 0);
/*
                if (ud_no == -3) {
                        touroku_mode = EXECUTE;
                } else if (ud_no == -1) {
                        touroku_mode = CANCEL;
                } else {
                        xw_jutil_write_msg(dict_name[ud_no]);
                }
*/
          if (touroku_mode == JISHO_IN)
            touroku_mode = EXECUTE;
          break;
        case EXECUTE:
        case TOUROKU_GO:
          if (!kanji_set)
            {
              touroku_mode = KANJI_IN_START;
              break;
            }
          else if (!yomi_set)
            {
              touroku_mode = YOMI_IN;
              break;
            }
          else if (!hinsi_set)
            {
              touroku_mode = HINSI_IN;
              break;
            }
          else if (!jisho_set)
            {
              touroku_mode = JISHO_IN;
              break;
            }
          if (touroku_mode == EXECUTE)
            {
              xw_exec_mode ();
            }
          else
            {
              goto do_touroku;
            }
          break;
        case CANCEL:
          end_jutil ();
          return;
        }
    }

do_touroku:
  current_dic = dicinfo[ud_table[ud_no]].dic_no;

  if (js_word_add (cur_env, current_dic, yomibuf, hani_buffer, "", hinsi, 0) == -1)
    {
      if_dead_disconnect (cur_env, -1);
      errorkeyin ();
      touroku_mode = EXECUTE;
      goto repeat;
    }
  end_jutil ();
  return;
}


static int
find_end_of_tango (c)
     int c;
{
  int k;
  int jisyu;                    /* 0: katakana 1: hiragana 2:ascii 3:kanji */

  if (KATAP (c_b->buffer[c]))
    jisyu = 0;
  else if (HIRAP (c_b->buffer[c]))
    jisyu = 1;
  else if (ASCIIP (c_b->buffer[c]))
    jisyu = 2;
  else if (KANJIP (c_b->buffer[c]))
    jisyu = 3;
  else
    return (c + 1);

  for (k = c + 1; k < c_b->maxlen; k++)
    {
      if (jisyu == 0)
        {
          if (!KATAP (c_b->buffer[k]))
            break;
        }
      else if (jisyu == 1)
        {
          if (!HIRAP (c_b->buffer[k]))
            break;
        }
      else if (jisyu == 2)
        {
          if (!ASCIIP (c_b->buffer[k]))
            break;
        }
      else if (jisyu == 3)
        {
          if (!KANJIP (c_b->buffer[k]))
            break;
        }
    }
  return (k);
}

int
t_markset ()
{
  if (xjutil->sel_ret == -2)
    {
      touroku_mode = CANCEL;
      hanten_jutil_mes_title (MESSAGE1, 0);
      xjutil->sel_ret = -1;
      return (-1);
    }

  if (c_b->t_m_start == -2)
    {
      hanten_jutil_mes_title (MESSAGE1, 0);
      return (0);
    }
  if (c_b->t_m_start == -1)
    {
      if (cur_root->jutil->mode != MESSAGE1)
        {
          touroku_mode = KANJI_IN_START;
          change_mes_title (MESSAGE1, msg_get (cd, 93, default_message[93], xjutil->lang), 1);
          return (0);
        }
      if (c_b->t_c_p == c_b->maxlen)
        {
          touroku_mode = KANJI_IN_END;
          change_mes_title (MESSAGE1, msg_get (cd, 94, default_message[94], xjutil->lang), 1);
          return (0);
        }
      c_b->t_m_start = c_b->t_c_p;
      touroku_mode = KANJI_IN_END;
      change_mes_title (MESSAGE1, msg_get (cd, 94, default_message[94], xjutil->lang), 1);
      call_t_redraw_move_1 (find_end_of_tango (c_b->t_c_p), c_b->t_c_p, find_end_of_tango (c_b->t_c_p), 0, 0, 0, 2);
      kk_cursor_invisible ();
      return (0);
    }
  else
    {
      if (c_b->t_m_start == c_b->t_c_p)
        {
          c_b->t_m_start = -1;
          touroku_mode = KANJI_IN_START;
          change_mes_title (MESSAGE1, msg_get (cd, 93, default_message[93], xjutil->lang), 1);
          kk_cursor_normal ();
          return (-1);
        }
      else
        {
          if (cur_root->jutil->mode == MESSAGE1)
            cur_root->jutil->mode = MESSAGE2;
          hanten_jutil_mes_title (MESSAGE1, 0);
          return (1);
        }
    }
}

int
xw_next_message ()
{
  register JutilRec *jutil = cur_root->jutil;

  redraw_old_message (jutil->mes_mode);
  if (jutil->mes_mode == MESSAGE4)
    {
      jutil->mes_mode = MESSAGE0;
    }
  else
    {
      jutil->mes_mode += 1;
    }
  redraw_new_message (jutil->mes_mode);
  return (0);
}

int
xw_previous_message ()
{
  register JutilRec *jutil = cur_root->jutil;

  redraw_old_message (jutil->mes_mode);
  if (jutil->mes_mode == MESSAGE0)
    {
      jutil->mes_mode = MESSAGE4;
    }
  else
    {
      jutil->mes_mode -= 1;
    }
  redraw_new_message (jutil->mes_mode);
  return (0);
}
