/*
 * $Id: jutil.c,v 1.7.2.1 1999/02/08 04:58:41 yamasita 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
 *
 * 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
 */
/* jisho utility routine for otasuke (user interface) process */
/*	活辞書とはカレントユーザ辞書のことだよ	*/

#include <stdio.h>
#include "commonhd.h"
#include "jslib.h"
#include "jllib.h"
#include "sdefine.h"
#include "sheader.h"
#include "wnn_os.h"

#define MESSAGE_REC 3
#define MESSAGE_NUM 5


#ifdef	nodef
char *sh_fname();
#endif

static void ret() ; /* remove sonota() , nullfun() */
 void touroku();
 void kensaku();
 void jishoadd() , dicsv(),fuzoku_set();
 void  paramchg() , dicinfoout(), select_one_dict8();

/*
static struct msg_fun {
  char *msg;
  void (*fun)();
};

static struct msg_fun message1[] = { 
  {"辞書追加", jishoadd},
  {"辞書一覧",select_one_dict8},
  {"登録", touroku},
  {"検索", kensaku},  
  {"パラメータ変更",paramchg},
  {"頻度セーブ",dicsv},
  {"辞書情報",dicinfoout},
  {"付属語変更", fuzoku_set},
  {"終了",ret}
};
*/

struct msg_fun {
  void (*fun)();
};

static struct msg_fun message1[] = { 
  {jishoadd},
  {select_one_dict8},
  {touroku},
  {kensaku},  
  {paramchg},
  {dicsv},
  {dicinfoout},
  {fuzoku_set},
  {ret}
};

int
jutil()
{
  static int last = 3;
  int not_redrawtmp = not_redraw;
  int c;
  int k;
  char *buf[sizeof(message1) / sizeof(struct msg_fun)];

  not_redraw = 1;
  for(k = 0 ; k <( sizeof(message1) / sizeof(struct msg_fun));k++){
    /*
    buf[k]=message1[k].msg;
    */
    buf[k]=MSG_GET(61+k);
  }

  c = select_one_element(buf,sizeof(message1)/sizeof(struct msg_fun),last,"",0,1,main_table[4]);
  if(c == -1) {
	not_redraw = not_redrawtmp;
	return(0);
  }
  last = c;
  (*message1[c].fun)();
  not_redraw = not_redrawtmp;
  return(0);
}

static void ret()
{
}


void
paramchg()
{
    int c,k;
    int newval;
    char *ch;
    char st[80];
    char message[80];
    w_char kana_buf[1024];

#ifdef	nodef
    static char *ccc[] = {"解析文節数" , "小文節の最大数",
"頻度重み" , "小文節長重み" , "自立語長重み" , "最近使用状況重み" , "辞書優先度重み", "小文節の評価値重み", "大文節長重み", "小文節数重み", /* "幹語長重み", */
"数字の頻度", "カナの頻度", "英数の頻度", "記号の頻度", "閉括弧の頻度", "付属語の頻度", "開括弧の頻度"};
#endif
    struct wnn_param para;
    int *paraary;
    /*
    char *cccmsg[(sizeof(ccc) / sizeof(char *))];
    */
    char *cccmsg[86-70+1];
    char buf[1024];
    
    paraary = (int *)&para;
    if(jl_param_get(bun_data_, &para) < 0) {
    	errorkeyin();
    }
    /*
    for(k = 0,ch = buf ; k < (sizeof(ccc) / sizeof(char *)) ; k++){
    */
    for(k = 0,ch = buf ; k < (86-70+1) ; k++){
      cccmsg[k] = ch;
      /*
      sprintf(ch,"%s[%d]",ccc[k],paraary[k]);
      */
      sprintf(ch,"%s[%d]",MSG_GET(70+k),paraary[k]);
      ch += strlen(ch) + 1;
    }
  repeat:
    /*
    if((c = select_one_element(cccmsg,(sizeof(ccc) / sizeof(char *)),
    */
    if((c = select_one_element(cccmsg,(86-70+1),
			       0,"",0,1,main_table[4])) == -1){
      return;
    }
    
    throw_c(0);
    clr_line();

    if(c == 0){
      /*
      sprintf(message , "現在 %d文節解析法を用いています。何文節解析法を用いますか ?" , paraary[0]);
      */
      sprintf(message, MSG_GET(45), paraary[0]);
    }else{
      /*
      sprintf(message , "現在の%sは %dです、幾つにしますか  ? ", ccc[c] , paraary[c] );
      */
      sprintf(message, MSG_GET(46), MSG_GET(70+c), paraary[c]);
    }
    kana_buf[0] = 0;
    if(kana_in(message , UNDER_LINE_MODE ,kana_buf , 1024) == -1)return;
    if(wchartochar(kana_buf , st) ||
       sscanf(st , "%d" , &newval) <= 0 ){
      /*
      print_msg_getc("数字を入力してください。(如何?)");
      */
      print_msg_getc(MSG_GET(47));
      goto repeat;
    }
    if(c == 0 && newval <= 0){
      /*
      print_msg_getc("正の数字を入力してください。(如何?)");
      */
      print_msg_getc(MSG_GET(48));
      goto repeat;
    }
    paraary[c] = newval;
    if(jl_param_set(bun_data_, &para) < 0) {
      errorkeyin();
    }
}


void
dicsv()
{
    /*
    print_msg("只今、辞書の頻度とユーザ辞書をセーブしています。");
    */
    print_msg(MSG_GET(49));
    flush();
    if(jl_dic_save_all(bun_data_) == -1){
    	errorkeyin();
    }
}

int
update_dic_list(buf)
struct wnn_buf *buf;
{
    if((dic_list_size = jl_dic_list(bun_data_, &dicinfo)) == -1){
	errorkeyin();
	return(-1);
    }
    return(0);
}

int
dic_nickname(dic_no, buf)
int dic_no;
char *buf;
{
    int j;

    if((j = find_dic_by_no(dic_no)) == -1)return(-1);
    if(*dicinfo[j].comment) sStrcpy(buf, dicinfo[j].comment);
    else strcpy(buf, dicinfo[j].fname);
    return(0);
}

int
find_dic_by_no(dic_no)
int dic_no;
{
    int j;

    for(j = 0 ; j < dic_list_size; j++){
	if(dicinfo[j].dic_no == dic_no)
	    return(j);
    }
    return(-1);
}



void
dicinfoout()
{
    int k;
    int cnt;
    char buf[4096];
    char *info[JISHOKOSUU];
    int size;

    if(update_dic_list(bun_data_) == -1){
	errorkeyin();
	return;
    }
    cnt = dic_list_size;

    cnt += 1; /* for the comment line */
    size = 4096 / cnt;
    if(make_info_out(buf, size, dicinfo, cnt) == -1){
	/*
	print_msg("残念、辞書が多すぎます。");
	*/
	print_msg(MSG_GET(50));
	return;
      }
    for(k = 0 ; k < cnt ; k++){
      info[k] = buf + k * size;
    }
    set_lc_offset(1);
    select_line_element(info,cnt,0,"",0,0,main_table[8]); 
    set_lc_offset(0);
}


void
select_one_dict8()
{
    set_lc_offset(0);
    select_one_dict1(8);
}

int
select_one_dict1(tbl)
int tbl;
{
    int l;
    char *c;
    char buf[4096];
    char *buf_ptr[JISHOKOSUU];
    char baka[1024];

    if(update_dic_list(bun_data_) == -1){
	errorkeyin();
	return(0);
    }
    if(dic_list_size == 0){
	/*
	print_msg_getc("辞書が一つも有りません。");
	*/
	print_msg_getc(MSG_GET(51));
	return(0);
    }

    for(c = buf,l = 0 ; l < dic_list_size ; l++){
	buf_ptr[l] = c;
	dic_nickname(dicinfo[l].dic_no, baka);
	sprintf(c,"%s(%s) %s %d/%d",baka, dicinfo[l].hfname,
		/*
		dicinfo[l].enablef?  "使用中":"中断中",
		*/
		dicinfo[l].enablef?  MSG_GET(52):MSG_GET(53),
		l + 1,dic_list_size);
	c += strlen(c) + 1;
    }
    return(select_line_element(buf_ptr, dic_list_size, 0, "", 0, 0, main_table[tbl]));
}

void
print_msg1(X)
char *X;
{
    push_cursor();throw_c(0); clr_line();printf(X);flush();pop_cursor();
}

void
fuzoku_set()
{
    /*
    char *message = "付属語ファイル名 >";
    */
    char fname[128];
    w_char kana_buf[1024];

    Strcpy(kana_buf , fuzokugopath);
    if(kana_in(MSG_GET(54), UNDER_LINE_MODE , kana_buf , 1024) == -1) return;
    wchartochar(kana_buf , fname);
    if(strlen(fname) == 0)return;
    Strcpy(fuzokugopath , kana_buf);
    if(jl_fuzokugo_set(bun_data_,fname) == -1){
	errorkeyin();  
    }
}

void
jishoadd()
{
    /*
    char *message = "新しい辞書は > ";
    char *hmessage = "頻度ファイル名 > ";
    char *priomessage = "辞書の優先度の数字を指定して下さい。 > ";
    */
    char fname[128];
    char tmp[128];
    char hfname[128];
    int prio;
    int rdonly;
    int hrdonly;
    int id, l;
    w_char kana_buf[1024];

    Strcpy(kana_buf , jishopath);
    if(kana_in(MSG_GET(55) , UNDER_LINE_MODE , kana_buf , 1024) == -1) return;
    wchartochar(kana_buf , fname);
    if(strlen(fname) == 0)return;
    Strcpy(jishopath , kana_buf);

    Strcpy(kana_buf,hindopath);
    getfname(hfname,fname);
    if(strcmp(hfname + strlen(hfname) - 4, ".usr") == 0 ||
       strcmp(hfname + strlen(hfname) - 4, ".sys") == 0 ||
       strcmp(hfname + strlen(hfname) - 4, ".dic") == 0 ||
       strcmp(hfname + strlen(hfname) - 4, ".rev") == 0) {
	hfname[strlen(hfname) - 4] = 0;
	strcat(hfname , ".h");
    } else if(strcmp(hfname + strlen(hfname) - 5, ".usrR") == 0 ||
       strcmp(hfname + strlen(hfname) - 5, ".sysR") == 0) {
	hfname[strlen(hfname) - 5] = 0;
	strcat(hfname , ".hR");
    } else {
	strcat(hfname , ".h");
    }
    Sstrcpy(kana_buf + Strlen(kana_buf), hfname);
    if(kana_in(MSG_GET(56) , UNDER_LINE_MODE , kana_buf , 1024) == -1){
	return;
    }
    wchartochar(kana_buf , hfname);
    sprintf(tmp,"%d",JISHO_PRIO_DEFAULT);
    Sstrcpy(kana_buf, tmp);
    if(kana_in(MSG_GET(57) , UNDER_LINE_MODE , kana_buf , 1024) == -1) return;
    wchartochar(kana_buf , tmp);
    prio = atoi(tmp);
    /*
    if(yes_or_no_or_newline("辞書を更新するモードで使いますか?(Y or Newline / N)") == 1){
    */
    if(yes_or_no_or_newline(MSG_GET(58)) == 1){
	rdonly = 0;
    }else{
	rdonly = 1;
    }
    /*
    if(yes_or_no_or_newline("頻度を更新するモードで使いますか?(Y or Newline / N)") == 1){
    */
    if(yes_or_no_or_newline(MSG_GET(59)) == 1){
	hrdonly = 0;
    }else{
	hrdonly = 1;
    }

    throw_c(0);
    clr_line();
    /*
    printf("只今、辞書を読み込んでいます。");
    */
    printf(MSG_GET(60));
    flush();

    if((id = jl_dic_add(bun_data_,fname,hfname,0,prio,rdonly, hrdonly, NULL, NULL, yes_or_no_or_newline, print_msg1)) == -1 && wnn_errorno != -1){
	errorkeyin();  
    }
    update_dic_list(bun_data_);
    for(l = 0 ; l < dic_list_size ; l++){
	if(dicinfo[l].dic_no == id){
	    break;
	}
    }
    if(l != dic_list_size && env_reverse &&
       (dicinfo[l].type == WNN_REV_DICT
	|| dicinfo[l].type == BWNN_REV_DICT
	|| dicinfo[l].type == CWNN_REV_DICT
       )){
	if(jl_dic_add_e(env_reverse, fname,hfname, 1,prio,rdonly, hrdonly, NULL, NULL, yes_or_no_or_newline, print_msg1) == -1 && wnn_errorno != -1){
	    errorkeyin();  
	}
    }
}

#ifdef	nodef
char *
sh_fname(s , n , d)  /* file名 sが長い時に、その最後の方を取って n文字にまとめて dに入れる   */ 
char *s , *d;
int n;
{
  int k;
  char *c , *c1;

  k = strlen(s);
  if(k < n){
    strcpy(d , s);
    return(d);
  }else{
    c = s + k - n + 2;
    c1 = d;
    *c1++ = '-';
    *c1++ = '-';
    for(;*c && *c != '/';c++){
      *c1++ = '-';
    }
    strcpy(c1 , c);
    return(d);
  }
}
#endif

int
yes_or_no(string)
char *string;
{
  int x;
    throw_c(0);
    clr_line();
    printf(string);
    flush();
  for(;;){
    x=keyin();
    if(x=='n' || x=='N') return(0);
    if(x == 'y' || x == 'Y')return(1);
  }
}


int
yes_or_no_or_newline(string)
char *string;
{
  int x;
    throw_c(0);
    clr_line();
    printf(string);
    flush();
  for(;;){
    x=keyin();
    if(x=='n' || x=='N') return(0);
    if(x == 'y' || x == 'Y' || x == '\n' || x == CR)return(1);
  }
}




/*
static char *info_out_data[] ={
  "No.", 
  "Type",
  "こめんと",
  "ファイル名",
  "頻度ファイル名",
  "語彙数",
  "優先度",
  "登録可能",
  "頻度更新可能",
  "使用中か",
  "登録パスワード",
  "頻度更新パスワード",
  ""
};
*/

int
make_info_out(buf,size,infobuf,cnt)
char buf[];
WNN_DIC_INFO infobuf[];
int cnt;
int size;
{
  int max1 = 0;
  int max0 = 0;
  int i,k,j;
  
  for(k = 0 ; k < cnt ; k++){
    for(j = 0 ; j < size ; j++){
      buf[k * size + j] = 0;
    }
  }

  for(i = 0 ; i < 13;i++){
    if(i == 12){
      sprintf(buf + max0,"%3d/%-3d",0,cnt - 1);
    }else{
      /*
      sprintf(buf + max0,"%s",info_out_data[i]);
      */
      sprintf(buf + max0,"%s",MSG_GET(87+i));
    }
    max1 = max(max1, strlen(buf));
    if(max1 >= size)return(-1);
    for(k = 1 ; k < cnt;k++){
      switch(i){
      case 0:
	sprintf(buf + size * k + max0,"%3d ",infobuf[k - 1].dic_no);
	break;
      case 1:
	{
	char *tmp;
	if((0xff00&infobuf[k - 1].type) == (BWNN_REV_DICT & 0xff00))
	    tmp = bwnn_dic_types[0xff&infobuf[k - 1].type];
	else
	if((0xff00&infobuf[k - 1].type) == (CWNN_REV_DICT & 0xff00))
	    tmp = cwnn_dic_types[0xff&infobuf[k - 1].type];
	else
	    tmp = wnn_dic_types[infobuf[k - 1].type];
	sprintf(buf + size * k + max0,"%8s", tmp);
	break;
	}
      case 2:
	sStrcpy(buf + size * k + max0,infobuf[k - 1].comment);
	break;
      case 3:
	strcpy(buf + size * k + max0,infobuf[k - 1].fname);
	break;
      case 4:
	strcpy(buf + size * k + max0,infobuf[k - 1].hfname);
	break;
      case 5:
	sprintf(buf + size * k + max0,"%6d",infobuf[k - 1].gosuu);
	break;
      case 6:
	sprintf(buf + size * k + max0,"%4d",infobuf[k - 1].nice);
	break;
      case 7:
	strcpy(buf + size * k + max0,(!infobuf[k - 1].rw)? "Yes":"No");
	break;
      case 8:
	strcpy(buf + size * k + max0,(!infobuf[k - 1].hindo_rw)? "Yes":"No");
	break;
      case 9:
	/*
	strcpy(buf + size * k + max0,(infobuf[k - 1].enablef)? "使用中":"中断中");
	*/
	strcpy(buf + size * k + max0,(infobuf[k - 1].enablef)? MSG_GET(52):MSG_GET(53));
	break;
      case 10:
	strcpy(buf + size * k + max0,infobuf[k - 1].passwd);
	break;
      case 11:
	strcpy(buf + size * k + max0,infobuf[k - 1].hpasswd);
	break;
      case 12:
	sprintf(buf + size * k + max0,"%3d/%-3d",k,cnt - 1);
	break;
      }
      max1 = max(max1, strlen(buf + size * k));
      if(max1 >= size)return(-1);
    }
    max0 = max1 + 1;
    for(k = 0 ; k < cnt;k++){
	fill(buf + size * k,max0);
    }
  }
  return(1);
}


void
fill(c,x)
char *c;
int x;
{
  for(;*c;c++,x--);
  for(;x;x--,c++){
    *c = ' ';
  }
}

