/*
 * $Id: kuten.c,v 1.2 2001/06/14 18:16:16 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
 */
/*
**   programs for KUTEN NYUURYOKU
*/

#include <stdio.h>
#include "commonhd.h"
#include "sdefine.h"
#ifdef XJUTIL
#include "xjutil.h"
#include "sxheader.h"
#include "xext.h"
#else /* XJUTIL */
#include "xim.h"
#include "sheader.h"
#include "ext.h"
#endif /* XJUTIL */

#define MAX_TEN_LENGTH  94

#define RING(ret)       {ring_bell(); return(ret);}
#ifdef XJUTIL
#define MES0_NUM        117
#define MES1_NUM        115
#define MES2_NUM        116
#define MES3_NUM        8
#define SEL_RET         (xjutil->sel_ret)
#else /* XJUTIL */
#define MES0_NUM        26
#define MES1_NUM        24
#define MES2_NUM        25
#define MES3_NUM        19
#define SEL_RET         (xim->sel_ret)
#endif /* XJUTIL */

static int
get_ichiran (ku, in, multi, cs, lang)
     int ku;
     int in;
     int multi, cs;
     char *lang;
{
  static char buf[1024];
  static char *buf_ptr[MAX_TEN_LENGTH];
  static int i;
  static char *c;
  static char kuten_title[32];
  static int kuten_ichi_step = 0;
  static w_char code[2];

  if (kuten_ichi_step == 0)
    {
      code[1] = (w_char) 0;
      for (i = 0, c = buf; i < MAX_TEN_LENGTH; i++)
        {
          code[0] = (((ku + 32) << 8) | ((i + 1) + 32)) & 0x7f7f;
          code[0] |= get_cs_mask (cs);
          buf_ptr[i] = c;
          c += sStrcpy (c, code) + 1;
        }
      if (multi > 1)
        {
          sprintf (kuten_title, "%s %d.%2d %s", msg_get (cd, MES1_NUM, default_message[MES1_NUM], lang), cs, ku, msg_get (cd, MES0_NUM, default_message[MES0_NUM], lang));
        }
      else
        {
          sprintf (kuten_title, "%s %2d %s", msg_get (cd, MES1_NUM, default_message[MES1_NUM], lang), ku, msg_get (cd, MES0_NUM, default_message[MES0_NUM], lang));
        }
      kuten_ichi_step++;
    }
  if ((i = xw_select_one_element (buf_ptr, MAX_TEN_LENGTH, 0, kuten_title, KUTEN_IN, main_table[4], in)) == -1)
    {
      kuten_ichi_step = 0;
      return (-1);
    }
  else if (i == BUFFER_IN_CONT)
    {
      return (BUFFER_IN_CONT);
    }
  kuten_ichi_step = 0;
  code[0] = ((((ku + 32) << 8) | ((i + 1) + 32)) & 0x7f7f) | get_cs_mask (cs);
  return ((int) code[0]);
}

int
in_kuten (in)                   /*  returns code for a moji  */
     int in;
{
  static char buffer[7];
  static int code;
  static int c_p = 0;
  static int ret1, ret2;
  static int mode = -1, mode1 = -1;
#ifndef XJUTIL
  static WnnClientRec *c_c_sv = 0;
#endif /* !XJUTIL */
  static int kuten_step = 0;
  static char *lang;
  static int cs = 0, valid_cs[3], multi, os = 0;
  register int i, k;
  register char t_c, *start_p;
  unsigned char c;

#ifndef XJUTIL
  if (in == -99)
    {
      end_ichiran ();
      code = -1;
      goto LAST;
    }
  if (c_c_sv != 0 && c_c != c_c_sv)
    {
      RING (-1);
    }
#endif /* !XJUTIL */
  if (kuten_step == 0)
    {
#ifdef XJUTIL
      set_cswidth (xjutil->cswidth_id);
      lang = xjutil->lang;
#else /* XJUTIL */
      set_cswidth (cur_lang->cswidth_id);
      lang = cur_lang->lang;
      c_c_sv = c_c;
#endif /* !XJUTIL */
      for (multi = 0, i = 0; i < 3; i++)
        {
          multi += valid_cs[i] = (get_cswidth (i) == 2) ? 1 : 0;
          if (valid_cs[i])
            cs = i;
        }
      if (multi <= 0)
        {
          RING (-1);
        }
      if (multi > 1)
        {
          os = 2;
        }
      else
        {
          os = 0;
        }
      for (k = 0; k < os + 5; buffer[k++] = ' ');
      buffer[os + 5] = '\0';
      c_p = 0;
      mode = mode1 = -1;
      kuten_step++;
    }

start:
  if (kuten_step == 1)
    {
      if (init_ichiran ((unsigned char **) NULL, 0, -1,
                        (unsigned char *) msg_get (cd, MES1_NUM, default_message[MES1_NUM], lang),
                        (unsigned char *) msg_get (cd, MES2_NUM, default_message[MES2_NUM], lang),
                        (unsigned char *) msg_get (cd, MES3_NUM, default_message[MES3_NUM], lang), NULL, os + 5, NYUURYOKU) == -1)
        {
#ifndef XJUTIL
          c_c_sv = 0;
#endif /* !XJUTIL */
          RING (-1);
        }
      draw_nyuu_w ((unsigned char *) buffer, 1);
      kuten_step++;
      return (BUFFER_IN_CONT);
    }
  if (kuten_step == 2)
    {
      c = (unsigned char) (in & 0xff);
#ifdef XJUTIL
      if (!cur_root->ichi->map)
        return (BUFFER_IN_CONT);
#else /* XJUTIL */
      if (!xim->cur_j_c_root->ichi->map)
        return (BUFFER_IN_CONT);
#endif /* XJUTIL */
      if (SEL_RET == -2)
        {
          end_ichiran ();
          SEL_RET = -1;
          code = -1;
          goto LAST;
        }
      if ((c == ESC) || (t_quit == main_table[5][c]))
        {
          end_ichiran ();
          code = -1;
          goto LAST;
#ifndef XJUTIL
        }
      else if (henkan_off == main_table[5][c])
        {
          RING (BUFFER_IN_CONT);
#endif /* !XJUTIL */
        }
      if ((c <= '9' && c >= '0') || c == '.')
        {
          if (os > 0)
            {
              if (mode >= 0)
                {
                  if (mode1 >= 0)
                    {
                      if ((c_p - mode1) <= 2 && c != '.')
                        {
                          buffer[c_p++] = (char) c;
                          goto RET;
                        }
                    }
                  else
                    {
                      t_c = buffer[0];
                      if ((c_p - mode) <= 4 && c != '.')
                        {
                          buffer[c_p++] = c;
                          goto RET;
                        }
                      else if (mode == 1 && t_c >= '0' && t_c <= '2' && valid_cs[t_c - '0'] && (c_p - mode) <= 3 && (c_p - mode) >= 2 && c == '.')
                        {
                          mode1 = c_p;
                          buffer[c_p++] = c;
                          goto RET;
                        }
                    }
                  RING (BUFFER_IN_CONT);
                }
              else
                {
                  if (c == '.')
                    {
                      if (c_p > 0 && c_p <= 2)
                        {
                          mode = c_p;
                          buffer[c_p++] = c;
                          goto RET;
                        }
                    }
                  else
                    {
                      if (c_p < 4)
                        {
                          buffer[c_p++] = c;
                          goto RET;
                        }
                    }
                  RING (BUFFER_IN_CONT);
                }
            }
          else
            {
              if (c == '.')
                {
                  if ((mode == -1) && 0 < c_p && c_p <= 2)
                    {
                      mode = c_p;
                      buffer[c_p++] = c;
                      goto RET;
                    }
                }
              else
                {
                  if ((mode >= 0 ? (c_p - mode) <= 2 : c_p < 4))
                    {
                      buffer[c_p++] = c;
                      goto RET;
                    }
                }
              RING (BUFFER_IN_CONT);
            }
        }
      else if (c == rubout_code && c_p)
        {
          if (os > 0)
            {
              if (mode1 >= 0 && buffer[c_p - 1] == '.')
                {
                  mode1 = -1;
                }
              else if (mode >= 0 && buffer[c_p - 1] == '.')
                {
                  mode = -1;
                }
            }
          else
            {
              if (buffer[c_p - 1] == '.')
                mode = -1;
            }
          buffer[--c_p] = ' ';
        }
      else if (c == rubout_code && c_p == 0)
        {
          end_ichiran ();
          code = -1;
          goto LAST;
        }
      else if ((c == NEWLINE) || (c == CR))
        {
          if (os > 0)
            {
              if ((mode1 >= 0 && (buffer[c_p - 1] != '.')) || (mode1 == -1 && mode >= 0 && (c_p - mode) >= 2) || (mode == -1 && c_p >= 3))
                {
                  if (mode1 >= 0 || (mode == 1 && (c_p - mode) >= 4))
                    {
                      cs = buffer[0] - '0';
                      if (valid_cs[cs] == 0)
                        RING (BUFFER_IN_CONT);
                      start_p = &buffer[os];
                    }
                  else
                    {
                      cs = 0;
                      start_p = buffer;
                    }
                  if ((!(sscanf (start_p, "%d.%d", &ret1, &ret2) == 2) &&
                       !(((mode == -1) ? (c_p == 4) : (c_p == os + 4)) &&
                         sscanf (start_p, "%2d%2d", &ret1, &ret2) == 2) &&
                       !(((mode == -1) ? (c_p == 3) : (c_p == os + 3)) && sscanf (start_p, "%1d%2d", &ret1, &ret2) == 2)) || ret1 <= 0 || ret1 > 94 || ret2 <= 0 || ret2 > 94)
                    {
                      RING (BUFFER_IN_CONT);
                    }
                  code = (((ret1 + 32) << 8) | (ret2 + 32)) & 0x7f7f;
                  code |= get_cs_mask (cs);
                  end_ichiran ();
                  goto LAST;
                }
              else
                {
                  if (mode1 >= 0 && (buffer[c_p - 1] == '.'))
                    {
                      if (sscanf (&buffer[os], "%d.", &ret1) != 1 || (ret1 <= 0 || ret1 > 94))
                        {
                          RING (BUFFER_IN_CONT);
                        }
                    }
                  else if (mode == -1 && (c_p == 1 || c_p == 2))
                    {
                      if (sscanf (&buffer[0], "%d", &ret1) != 1 || (ret1 <= 0 || ret1 > 94))
                        {
                          RING (BUFFER_IN_CONT);
                        }
                    }
                  else
                    {
                      RING (BUFFER_IN_CONT);
                    }
                  end_ichiran ();
                  kuten_step++;
                  goto NEXT;
                }
              RING (BUFFER_IN_CONT);
            }
          else
            {
              if (c_p >= 3 && (buffer[c_p - 1] != '.'))
                {
                  start_p = buffer;
                  if ((!(sscanf (start_p, "%d.%d", &ret1, &ret2) == 2) &&
                       !((c_p == 4) &&
                         sscanf (start_p, "%2d%2d", &ret1, &ret2) == 2) && !((c_p == 3) && sscanf (start_p, "%1d%2d", &ret1, &ret2) == 2)) || ret1 <= 0 || ret1 > 94 || ret2 <= 0 || ret2 > 94)
                    {
                      RING (BUFFER_IN_CONT);
                    }
                  code = (((ret1 + 32) << 8) | (ret2 + 32)) & 0x7f7f;
                  code |= get_cs_mask (cs);
                  end_ichiran ();
                  goto LAST;
                }
              else if (c_p <= 2 && mode == -1)
                {
                  if (sscanf (buffer, "%d", &ret1) != 1 || (ret1 <= 0 || ret1 > 94))
                    {
                      RING (BUFFER_IN_CONT);
                    }
                  end_ichiran ();
                  kuten_step++;
                  goto NEXT;
                }
              RING (BUFFER_IN_CONT);
            }
        }
    RET:
      draw_nyuu_w ((unsigned char *) buffer, 1);
      return (BUFFER_IN_CONT);
    }
NEXT:
  if (kuten_step == 3)
    {
      if (os > 0)
        {
          if (mode1 >= 0)
            {
              cs = buffer[0] - '0';
            }
          else
            {
              cs = 0;
            }
        }
      if ((code = get_ichiran (ret1, in, multi, cs, lang)) == -1)
        {
          kuten_step = 0;
          goto start;
        }
      else if (code == BUFFER_IN_CONT)
        {
          return (BUFFER_IN_CONT);
        }
    }
LAST:
#ifndef XJUTIL
  c_c_sv = 0;
#endif /* !XJUTIL */
  kuten_step = 0;
  return (code);
}

#undef RING

/*
  Local Variables:
  eval: (setq kanji-flag t)
  eval: (setq kanji-fileio-code 0)
  eval: (mode-line-kanji-code-update)
  End:
*/
