/*
 * $Id: init.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 OMRON Corporation. 1987, 1988, 1989, 1990, 1991, 1992, 1999
 * 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:
 *
 */

#include "sdefine.h"
#include "xim.h"
#include "sheader.h"
#include "ext.h"

static void
default_flag_set ()
{
  cursor_colum = 0;
  cursor_reverse = 0;
  cursor_underline = 0;
  cursor_invisible = 1;
  cursor_bold = 0;
  quote_flag = 0;
  send_ascii_char = 0;
  send_ascii_stack = 0;
  send_ascii_char_quote = 0;
  c_c->command_func_stack[0] = NULL;
  c_c->func_stack_count = -1;
  c_c->buffer_ignored = 0;
}

static int
copy_env (wc)
     register WnnClientRec *wc;
{
  WnnEnv *p;

  for (p = wc->normal_env; p; p = p->next)
    {
      if (get_new_env (c_c, NULL, 0) < 0 || (p->host_name && !(servername = alloc_and_copy (p->host_name))))
        goto ERROR_RET;
      envrcname = p->envrc_name;
      strcpy (env_name, p->env_name_str);
    }
  for (p = wc->reverse_env; p; p = p->next)
    {
      if (get_new_env (c_c, NULL, 1) < 0 || (p->host_name && !(reverse_servername = alloc_and_copy (p->host_name))))
        goto ERROR_RET;
      reverse_envrcname = p->envrc_name;
      strcpy (reverse_env_name, p->env_name_str);
    }

  send_ascii_char = send_ascii_char_def;

  c_c->m_table = wc->m_table;
  c_c->m_table->re_count++;
  return (0);
ERROR_RET:
  free_env (c_c->normal_env);
  free_env (c_c->reverse_env);
  return (-1);
}

static void
add_wnnclientlist (cl)
     register WnnClientRec *cl;
{
  cl->next = wnnclient_list;
  wnnclient_list = cl;
}

static void
remove_wnnclientlist (cl)
     register WnnClientRec *cl;
{
  register WnnClientList p, *prev;
  for (prev = &wnnclient_list; p = *prev; prev = &p->next)
    {
      if (p == cl)
        {
          *prev = p->next;
          break;
        }
    }
}

void
add_ximclientlist (cl)
     register XIMClientRec *cl;
{
  cl->next = ximclient_list;
  ximclient_list = cl;
}

void
remove_ximclientlist (cl)
     register XIMClientRec *cl;
{
  register XIMClientList p, *prev;
  for (prev = &ximclient_list; p = *prev; prev = &p->next)
    {
      if (p == cl)
        {
          *prev = p->next;
          break;
        }
    }
}

void
add_inputlist (xi)
     register XIMInputRec *xi;
{
  xi->next = input_list;
  input_list = xi;
}

void
remove_inputlist (xi)
     register XIMInputRec *xi;
{
  register XIMInputList p, *prev;
  for (prev = &input_list; p = *prev; prev = &p->next)
    {
      if (p == xi)
        {
          *prev = p->next;
          break;
        }
    }
}

static WnnClientRec *
find_same_lang (lang)
     char *lang;
{
  register XIMClientRec *p;
  register XIMLangRec *xl;
  register int i;
  for (p = ximclient_list; p != NULL; p = p->next)
    {
      for (i = 0; i < p->lang_num; i++)
        {
          xl = p->xl[i];
          if (xl->w_c && xl->w_c->m_table)
            {
              if (!strcmp (xl->lang_db->lang, lang) && xl->w_c != NULL)
                {
                  return ((WnnClientRec *) xl->w_c);
                }
            }
        }
    }
  return ((WnnClientRec *) NULL);
}

int
allocate_wnn (uname)
     char *uname;
{
  int len = 0;
  register char *p;
  extern void bzero ();

  if (uname && *uname)
    len = strlen (uname) + 1;
  if (!(p = Malloc (sizeof (WnnClientRec) + sizeof (ClientBuf) + len)))
    {
      malloc_error ("allocation of data for wnn");
      return (-1);
    }
  c_c = (WnnClientList) p;
  bzero ((char *) c_c, sizeof (WnnClientRec));
  p += sizeof (WnnClientRec);
  c_b = (ClientBuf *) p;
  bzero ((char *) c_b, sizeof (ClientBuf));
  if (uname && *uname)
    {
      p += sizeof (ClientBuf);
      c_c->user_name = (char *) p;
      strcpy (c_c->user_name, uname);
    }
  add_wnnclientlist (c_c);
  default_flag_set ();
  return (0);
}

void
free_wnn ()
{
  remove_wnnclientlist (c_c);
  Free ((char *) c_c);
}

int
initialize_wnn (xl, root)
     XIMLangRec *xl;
     int root;
{
  WnnClientRec *p;

  if ((p = find_same_lang (xl->lang_db->lang)) != NULL)
    {
      if (copy_env (p) < 0)
        return (-1);
    }
  else
    {
      if (uumrc_get_entries (xl->lang_db, 0, root) == -1)
        {
          return (-1);
        }
      if (init_key_table (xl->lang_db->lang) == -1)
        {
          del_client (c_c, 4);
          return (-1);
        }
    }
  henkan_off_flag = henkan_off_def;
  maxlength = maxchg * 2;
  if (allocate_areas () == -1)
    {
      del_client (c_c, 3);
      return (-1);
    }
  if (init_history () == -1)
    {
      del_client (c_c, 2);
      return (-1);
    }
  if (open_romkan (xl->lang_db) == -1)
    {
      del_client (c_c, 1);
      return (-1);
    }
  return (0);
}
