/*
 * $Id: jikouho.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
 */
#include <stdio.h>
#include "commonhd.h"
#include "sdefine.h"
#include "xim.h"
#include "sheader.h"
#include "ext.h"


/* add by KUWA */
int
dai_top (buf, bnst)
     struct wnn_buf *buf;
     int bnst;
{
  if (bnst >= jl_bun_suu (buf))
    return (jl_bun_suu (buf));
  for (; bnst >= 0 && !jl_dai_top (buf, bnst); bnst--);
  return (bnst);
}

int
dai_end (buf, bnst)
     struct wnn_buf *buf;
     int bnst;
{
  for (bnst++; bnst < jl_bun_suu (buf) && !jl_dai_top (buf, bnst); bnst++);
  return (bnst);
}

void
set_escape_code (x)
     char *x;
{
  int m;
  char buf[512];
  char *tmp;

  for (m = 0, tmp = x; *tmp; tmp++)
    {
      if (ESCAPE_CHAR ((*tmp & 0xff)))
        {
          buf[m++] = '^';
          if (*tmp == 0x7f)
            buf[m++] = '?';
          else
            buf[m++] = (*tmp + 'A' - 1);
        }
      else
        {
          buf[m++] = *tmp;
        }
    }
  buf[m] = '\0';
  strcpy (x, buf);
}

/* 次候補を一つずつ表示する関数
num = 1 のとき次候補を、num = -1 のとき前候補を表示する */
static int
jikouho (num)
     int num;
{
  int tmp;
  int mae_p;
  /* 注目している文節の次候補がまだ用意されていない時は
     まずそれを用意する。 */
  jl_env_set (bun_data_, bunsetsu_env[cur_bnst_]);
  if (bunsetsu_env[cur_bnst_] == bunsetsu_env[cur_bnst_ + 1])
    mae_p = WNN_USE_ZENGO;
  else
    mae_p = WNN_USE_MAE;
  if (jl_zenkouho_bun (bun_data_) != cur_bnst_ || jl_zenkouho_daip (bun_data_))
    {
      if (jl_zenkouho (bun_data_, cur_bnst_, mae_p, WNN_UNIQ) < 0)
        {
          errorkeyin ();
          return (-1);
        }
    }

  if (num == 1)
    jl_next (bun_data_);
  else if (num == -1)
    jl_previous (bun_data_);
  else
    return (-1);
  make_kanji_buffer (cur_bnst_);

  tmp = c_b->t_b_st;
  c_b->t_m_start = bunsetsuend[cur_bnst_];
  c_b->t_b_st = bunsetsu[dai_top (bun_data_, cur_bnst_)];
  c_b->t_b_end = bunsetsuend[dai_end (bun_data_, cur_bnst_) - 1];
  t_redraw_move (bunsetsu[cur_bnst_], MIN_VAL (tmp, c_b->t_b_st), c_b->maxlen, 1);
  check_scroll ();
  return (0);
}

/* 次候補を一つずつ表示する関数
num = 1 のとき次候補を、num = -1 のとき前候補を表示する */
static int
jikouho_dai (num)
     int num;
{
  int tmp;
  int mae_p;
  /* 注目している文節の次候補がまだ用意されていない時は
     まずそれを用意する。 */
  jl_env_set (bun_data_, bunsetsu_env[cur_bnst_]);
  if (bunsetsu_env[cur_bnst_] == bunsetsu_env[dai_end (bun_data_, cur_bnst_)])
    mae_p = WNN_USE_ZENGO;
  else
    mae_p = WNN_USE_MAE;
  if (jl_zenkouho_bun (bun_data_) != cur_bnst_ || !jl_zenkouho_daip (bun_data_))
    {
      if (jl_zenkouho_dai (bun_data_, cur_bnst_, dai_end (bun_data_, cur_bnst_), mae_p, WNN_UNIQ) < 0)
        {
          errorkeyin ();
          return (-1);
        }
    }

  if (num == 1)
    jl_next_dai (bun_data_);
  else if (num == -1)
    jl_previous_dai (bun_data_);
  else
    return (-1);
  make_kanji_buffer (cur_bnst_);
  for (tmp = cur_bnst_ + 1; tmp < jl_bun_suu (bun_data_); tmp++)
    bunsetsu_env[tmp] = jl_env_get (bun_data_);
  tmp = c_b->t_b_st;
  c_b->t_m_start = bunsetsuend[cur_bnst_];
  c_b->t_b_st = bunsetsu[dai_top (bun_data_, cur_bnst_)];
  c_b->t_b_end = bunsetsuend[dai_end (bun_data_, cur_bnst_) - 1];
  t_redraw_move (bunsetsu[cur_bnst_], MIN_VAL (tmp, c_b->t_b_st), c_b->maxlen, 1);
  check_scroll ();
  return (0);
}



int
jikouho_c ()
{
  jikouho (1);
  return (0);
}

int
zenkouho_c ()
{
  jikouho (-1);
  return (0);
}

int
jikouho_dai_c ()
{
  jikouho_dai (1);
  return (0);
}

int
zenkouho_dai_c ()
{
  jikouho_dai (-1);
  return (0);
}

static int
make_jikouho_retu (h, h_m, r, r_m)
     char *h;
     int h_m;
     int r_m;
     char *r[];
{
  int k;
  char *c = h;
  w_char tmp[512];
  char tmp1[512];

  if (r_m <= jl_zenkouho_suu (bun_data_))
    return (-1);

  for (k = 0; k < jl_zenkouho_suu (bun_data_); k++)
    {
      r[k] = c;
      tmp[0] = 0;
      jl_get_zenkouho_kanji (bun_data_, k, tmp);
      if (print_out_func)
        (*print_out_func) (tmp, tmp, Strlen (tmp));
      delete_w_ss2 (tmp, Strlen (tmp));
      sStrcpy (tmp1, tmp);
      if (c + strlen (tmp1) + 1 >= h_m + h)
        {
          return (-1);
        }
      set_escape_code (tmp1);   /* add by KUWA */
      strcpy (c, tmp1);
      c += strlen (tmp1) + 1;
    }
  return (0);
}

static int
select_jikouho1 (daip, in)
     int daip;
     int in;
{
  static char *j_retu[MAXJIKOUHO];
  static char jikouho_heap[MAXJIKOUHO * 10];
  int c;
  int tmp;
  static int jikouho_step = 0;
  static WnnClientRec *c_c_sv = 0;
  static char *lang;

  if (c_c_sv != 0 && c_c != c_c_sv)
    {
      ring_bell ();
      return (-1);
    }
  if (jikouho_step == 0)
    {
      jl_env_set (bun_data_, bunsetsu_env[cur_bnst_]);
      if (jl_zenkouho_bun (bun_data_) != cur_bnst_ || jl_zenkouho_daip (bun_data_) != daip)
        {
          if (daip)
            {
              if (jl_zenkouho_dai (bun_data_, cur_bnst_, dai_end (bun_data_, cur_bnst_), WNN_USE_ZENGO, WNN_UNIQ) == -1)
                {
                  errorkeyin ();
                  return (-1);
                }
            }
          else
            {
              if (jl_zenkouho (bun_data_, cur_bnst_, WNN_USE_ZENGO, WNN_UNIQ) == -1)
                {
                  errorkeyin ();
                  return (-1);
                }
            }
        }
      lang = cur_lang->lang;
      if (make_jikouho_retu (jikouho_heap, MAXJIKOUHO * 10, j_retu, MAXJIKOUHO) == -1)
        {
          print_msg_getc ("%s", msg_get (cd, 3, default_message[3], lang), NULL, NULL);
          return (-1);
        }
      c_c_sv = c_c;
      jikouho_step++;
    }

  if ((c = xw_select_one_element (j_retu, jl_zenkouho_suu (bun_data_),
                                  jl_c_zenkouho (bun_data_), (daip ? msg_get (cd, 2, default_message[2], lang) : msg_get (cd, 1, default_message[1], lang)), JIKOUHO, main_table[4], in)) == -1)
    {
      jikouho_step = 0;
      c_c_sv = 0;
      return (-1);
    }
  else if (c == BUFFER_IN_CONT)
    {
      return (BUFFER_IN_CONT);
    }
  if (daip == WNN_SHO)
    {
      jl_set_jikouho (bun_data_, c);
    }
  else
    {
      jl_set_jikouho_dai (bun_data_, c);
    }
  make_kanji_buffer (cur_bnst_);
  for (tmp = cur_bnst_ + 1; tmp < jl_bun_suu (bun_data_); tmp++)
    bunsetsu_env[tmp] = jl_env_get (bun_data_);
  c_b->t_m_start = bunsetsuend[cur_bnst_];
  c_b->t_c_p = bunsetsu[cur_bnst_];
  c_b->t_b_st = bunsetsu[dai_top (bun_data_, cur_bnst_)];
  c_b->t_b_end = bunsetsuend[dai_end (bun_data_, cur_bnst_) - 1];
  jikouho_step = 0;
  c_c_sv = 0;
  return (0);
}

int
select_jikouho (in)
     int in;
{
  int ret;
  static WnnClientRec *c_c_sv = 0;

#ifdef  CALLBACKS
  if (IsPreeditCallbacks (cur_x) && cur_x->cb_redraw_needed)
    {
      redraw_line ();
      c_c_sv = 0;
      pop_func (c_c);
      cur_x->cb_redraw_needed = 0;
      return (0);
    }
#endif /* CALLBACKS */
  if (c_c_sv != 0 && c_c != c_c_sv)
    {
      ring_bell ();
      return (0);
    }
  if (c_c_sv == 0)
    {
      c_c_sv = c_c;
      push_func (c_c, select_jikouho);
    }
  if ((ret = select_jikouho1 (WNN_SHO, in)) == BUFFER_IN_CONT)
    {
      return (BUFFER_IN_CONT);
    }
  else if (ret == -1)
    {
      if (cur_p->cur_xl->visible == 3)
        {
          t_print_l ();
        }
    }
  else
    {
#ifdef  CALLBACKS
      if (IsPreeditCallbacks (cur_x))
        {
          cur_x->cb_redraw_needed = 1;
          SendCBRedraw ();
          return (BUFFER_IN_CONT);
        }
      else
        {
#endif /* CALLBACKS */
          kk_cursor_invisible ();
          redraw_line ();
          kk_cursor_normal ();
#ifdef  CALLBACKS
        }
#endif /* CALLBACKS */
    }
  c_c_sv = 0;
  pop_func (c_c);
  check_scroll ();
  return (0);
}

int
select_jikouho_dai (in)
     int in;
{
  int ret;
  static WnnClientRec *c_c_sv = 0;

#ifdef  CALLBACKS
  if (IsPreeditCallbacks (cur_x) && cur_x->cb_redraw_needed)
    {
      redraw_line ();
      c_c_sv = 0;
      pop_func (c_c);
      cur_x->cb_redraw_needed = 0;
      return (0);
    }
#endif /* CALLBACKS */
  if (c_c_sv != 0 && c_c != c_c_sv)
    {
      ring_bell ();
      return (0);
    }
  if (c_c_sv == 0)
    {
      c_c_sv = c_c;
      push_func (c_c, select_jikouho_dai);
    }
  if ((ret = select_jikouho1 (WNN_DAI, in)) == BUFFER_IN_CONT)
    {
      return (BUFFER_IN_CONT);
    }
  else if (ret == -1)
    {
      if (cur_p->cur_xl->visible == 3)
        {
          t_print_l ();
        }
    }
  else
    {
#ifdef  CALLBACKS
      if (IsPreeditCallbacks (cur_x))
        {
          cur_x->cb_redraw_needed = 1;
          SendCBRedraw ();
          return (BUFFER_IN_CONT);
        }
      else
        {
#endif /* CALLBACKS */
          kk_cursor_invisible ();
          redraw_line ();
          kk_cursor_normal ();
#ifdef  CALLBACKS
        }
#endif /* CALLBACKS */
    }
  c_c_sv = 0;
  pop_func (c_c);
  check_scroll ();
  return (0);
}

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