/*
 * Copyright 2003 Sun Microsystems Inc.
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 * Authors: Karl Park <karl.park@sun.com>
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <assert.h>

#include "le_proc.h"
#include "koinput.h"
#include "le.h"
#include "iml.h"
#include "encode.h"
#include "method.h"
#include "logf.h"

/* UTF-8 string of [ ÇÑ±¹¾î ] */
/*
unsigned char English_Status_UTF[] = {
	0x5b, 0x20, 0xe8, 0x8b, 0xb1, 0xe6, 0x96, 0x87, 0x20, 0x5d, 0x0
};
*/

extern unsigned char English_Status_UTF[];
extern int        	g_number_of_engines;
extern IMEEngineRec 	*g_engines[MAX_ENGINE_NUM];

static int get_keyboard_string(keyboard_layout id, char **keyboard_str_return);
static int get_hex_string(iml_session_t *s, char **hex_string_return);
static int get_symbol_string(char **symbol_string_return);
static int get_hanja_string(char **hanja_string_return);

/* output input method buffer to system */
void
le_output_ime_buffer (iml_session_t *s, IMEBuffer ime_buffer,
		      IMEKeyEventStruct  *ime_keyevent)
{
  MyDataPerSession *session_data = (MyDataPerSession *) s->specific_data;
  MyDataPerDesktop *desktop_data = (MyDataPerDesktop *)(s->desktop->specific_data);
  IMEBufferMethods mthds = session_data->session_core.ime_methods_table;
  IMEBufferWhatToDo *task_list = NULL;

  int current_engine_id = 0;
  IMEEngine p_current_engine;
  Bool result_is_okay = True;
  Bool method_return;
                                                                               
  UTFCHAR *status_string = NULL;
  UTFCHAR *preedit_string = NULL;
  UTFCHAR **lookup_string_list = NULL;
  UTFCHAR *commit_string = NULL;
  int n_candidates;
  int i_current_candidate;
  
  p_current_engine = g_engines[current_engine_id];

  method_return = (*mthds->ime_buffer_get_what_to_do) (ime_buffer,&task_list);
  assert (method_return == True);
  if (method_return != True){
    fprintf (stderr, "le_output_ime_buffer erroro: cannot get todo list\n");
    return;
  }

  if (task_list->do_status) {
    result_is_okay = 
      (*mthds->ime_buffer_get_status) (ime_buffer, &status_string);
    assert (result_is_okay == True);
    
    if (result_is_okay = True) {
      iml_status_draw (s);
      free (status_string);
    }
  }

  if (task_list->do_commit) {
    result_is_okay = 
      (*mthds->ime_buffer_get_commit_string) (ime_buffer, &commit_string);
    if (result_is_okay = True) {
      iml_preedit_enddraw (s);
      iml_commit (s, commit_string);
      task_list->do_commit = False;

      /*
	s->If->m->iml_make_preedit_erase_inst (s);
      */
      free (commit_string);
      }
  }

  if (task_list->do_preedit) {
    result_is_okay = 
      (*mthds->ime_buffer_get_preedit) (ime_buffer, &preedit_string);
    assert (result_is_okay == True);
    
    if (result_is_okay = True) {
      iml_preedit_draw (s, preedit_string, -1);
      free (preedit_string);
    } else {
      iml_inst *lp;
      lp = (iml_inst *)s->If->m->iml_make_lookup_done_inst (s);
      s->If->m->iml_execute (s, &lp);
    }
  }

  if (task_list->do_lookup) {
    result_is_okay = 
      (*mthds->ime_buffer_get_candidates) (ime_buffer,
					   &n_candidates,
					   &i_current_candidate,
					   &lookup_string_list);

    if (result_is_okay = True)
      iml_lookup_draw (s,
		       lookup_string_list,
		       n_candidates, i_current_candidate, NUMERIC_LABEL);
      
  } else {
    iml_inst *lp;
    iml_inst *rrv = NULL;
    lp = s->If->m->iml_make_lookup_done_inst(s);
    s->If->m->iml_link_inst_tail (&rrv, lp);
    s->If->m->iml_execute (s, &rrv);
  }

    

  if (task_list->do_sendback && ime_keyevent)
    {
      iml_sendback_key(s, ime_keyevent);
      task_list->do_sendback = False;
    }
  (*mthds->ime_buffer_set_what_to_do) (ime_buffer, task_list);
  free (task_list);
}
	
   


/* return:
	0 - success
	-1 - error(memory allocation)
   in: keyboard_layout_id
   out: keyboard_str_return encoded in utf-8
*/

static int get_keyboard_string(keyboard_layout id, char **keyboard_str_return)
{
	int ret;
	size_t ilen, olen;
	char inbuffer[256], outbuffer[256];
	char *tbuf;
	char *key_str;

	switch(id){
	case KEYBOARD_LAYOUT_2BEOLSIK:
		key_str= (char *)strdup(KEYBOARD_2BEOLSIK);
		break;
	case KEYBOARD_LAYOUT_3BEOLSIK_390:
		key_str = (char *)strdup(KEYBOARD_3BEOLSIK_390);
		break;
	case KEYBOARD_LAYOUT_3BEOLSIK_FINAL:
		key_str = (char *)strdup(KEYBOARD_3BEOLSIK_FINAL);
		break;
	default:
		key_str = (char *)strdup(KEYBOARD_2BEOLSIK);
		break;
	}
	if(NULL == key_str){ /* memory allocation error */
		return -1;
	}
	
	bzero(inbuffer, 256); bzero(outbuffer, 256);
	strcpy(inbuffer, key_str);
	ilen = strlen(inbuffer), olen = 256;
	tbuf = outbuffer;

	ret = Convert_Native_To_UTF8(ENCODE_EUC_KO,inbuffer, ilen, &tbuf, &olen);

	assert(ret != -1);
	*keyboard_str_return = (char *)strdup(outbuffer);
	if(NULL == *keyboard_str_return)
		return -1;
	return 0;

}
#if 0

static int get_hex_string(iml_session_t *s, char **hex_string_return)
{
	int ret;
	size_t ilen, olen;
	char inbuffer[256], outbuffer[256];
	char *tbuf;
	MyDataPerSession *session_data = (MyDataPerSession *) s->specific_data;

	bzero(inbuffer, 256); bzero(outbuffer, 256);
	if(session_data->ime_buffer->triggered_conversion_key == ctrl_x){
		strcpy(inbuffer, INPUT_MODE_HEX_IN_EUC_STR);
	}
	else if(session_data->ime_buffer->triggered_conversion_key == ctrl_shift_x){
		strcpy(inbuffer, INPUT_MODE_HEX_IN_UTF8_STR);
	}

	ilen = strlen(inbuffer), olen = 256;
	tbuf = outbuffer;

	ret = Convert_Native_To_UTF8(ENCODE_EUC_KO,inbuffer, ilen, &tbuf, &olen);

	assert(ret != -1);
	*hex_string_return = (char *)strdup(outbuffer);
}
#endif

static int get_symbol_string(char **symbol_string_return)
{
	int ret;
	size_t ilen, olen;
	char inbuffer[256], outbuffer[256];
	char *tbuf;

	bzero(inbuffer, 256); bzero(outbuffer, 256);
	strcpy(inbuffer, INPUT_MODE_SYMBOL_STR);
	ilen = strlen(inbuffer), olen = 256;
	tbuf = outbuffer;

	ret = Convert_Native_To_UTF8(ENCODE_EUC_KO,inbuffer, ilen, &tbuf, &olen);

	assert(ret != -1);

	*symbol_string_return = (char *)strdup((const char *) &outbuffer[0]);

	return 0;
}

static int get_hanja_string(char **hanja_string_return)
{
	int ret;
	size_t ilen, olen;
	char inbuffer[256], outbuffer[256];
	char *tbuf;

	bzero(inbuffer, 256); bzero(outbuffer, 256);
	strcpy(inbuffer, INPUT_MODE_HANJA_STR);
	ilen = strlen(inbuffer), olen = 256;
	tbuf = outbuffer;

	ret = Convert_Native_To_UTF8(ENCODE_EUC_KO,inbuffer, ilen, &tbuf, &olen);

	assert(ret != -1);
	*hanja_string_return = (char *)strdup(outbuffer);
	return 0;
	
}

void
le_switch_engine(iml_session_t *s, int engine_id)
{
#if 0
  int engine_id, i;
  char locale_id, system_locale_id;
  IMEBufferMethods ime_methods;

  Bool result_is_good;
  MyDataPerSession *session_data = (MyDataPerSession *) s->specific_data;

  if (engine_id >= g_number_of_engines)  
    engine_id = 0xff;

  if (engine_id != 0xff && 
      g_engines[engine_id]->core.baseinfo.status == ENGINE_NOT_INSTALLED)
    engine_id = 0xff;

  if (engine_id != 0xff) {
    result_is_good =
      g_engines[engine_id]->so_methods->ime_buffer_initialize(
							      &g_engines[engine_id]->core,
							      session_data->ime_buffer);
		
    logf ("start aux window and IME_SessionInit return :%d\n", ret);
    if (result_is_good == False)
      engine_id = 0xff;
  }

  session_data->paletteaux_status.engine_id = engine_id;
  le_status_draw(s);
  le_update_keymapinfo_notify(s, engine_id);
#endif
}

void le_update_ime_buffer(iml_session_t *s, UserPreference *pref)
{
#if 0
	MyDataPerSession *sd = (MyDataPerSession *) s->specific_data;
	MyDataPerDesktop *dd = (MyDataPerDesktop *)(s->desktop->specific_data);
	IMEBuffer ime_buffer = sd->ime_buffer;

	ime_buffer->ime_user_id = pref->ime_user_id;

	if(pref->ime_user_home){
		if(ime_buffer->ime_user_home)
			free(ime_buffer->ime_user_home);
		ime_buffer->ime_user_home = strdup(pref->ime_user_home);
	}
	ime_buffer->keyboard_layout = pref->keyboard_layout;
	ime_buffer->conversion_format = pref->conversion_format;
	/* ime_buffer->delete_by_jaso = pref->delete_by_jaso; */
	ime_buffer->auto_commit_on_char_basis = pref->auto_commit_on_char_basis;
	ime_buffer->auto_commit_on_single_candidate_conversion = pref->auto_commit_on_single_candidate_conversion;
#endif
}

