/* 
 * Copyright 1998 by Sun Microsystems, Inc., 901 San Antonio Road,
 * Palo Alto, California, 94303, U.S.A. All rights reserved.
 *
 * This software is the confidential and proprietary information of Sun
 * Microsystems, Inc. ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered
 * into with Sun.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <dlfcn.h>

#include "unit_input.h"
#include "phonetic_im.h"
#include "phonetic_table.h"
#include "phonetic_filter.h"
#include "logf.h"

int  phonetic_SetOptions(IMECore, char *);
int  phonetic_SetValues(IMECore, IMEArgList, int);
int  phonetic_Init(IMECore);
int  phonetic_Open(IMECore, IMEBuffer, void *);
int  phonetic_Filter(IMECore, IMEKey, IMEArgList, IMEBuffer);
void phonetic_Close(IMECore);

#ifdef	WIN32
#define EXPORT extern __declspec(dllexport)
EXPORT
#endif

/* IF Method */
IMEMethodsRec ime_methods = {
	phonetic_SetOptions,
	phonetic_SetValues,
	phonetic_Init,
	phonetic_Open,
	phonetic_Filter,
	phonetic_Close
};

/* Set options for codetable input method. */
int phonetic_SetOptions(IMECore core, char *options)
{
	char 	data_path[256];
  int i;

  /* Change path : /usr/lib/im/locale/in_IN/<locale_name>/phonetic.cfg */
	sprintf(data_path, "%s/%s/%s/%s", DEFAULT_ENGINE_PATH, core->envinfo.lang_name, options, PHONETIC_CONFIG_NAME);

	core->envinfo.data_path = (char *)strdup(data_path);
	log_f("phonetic_im: data_path :%s\n", core->envinfo.data_path);

  fNum = 0;
  table_Num = 0;
  for (i=0; i<MAX_ENGINE_NUM; i++)
    phtable_Info[i] = NULL;

	return (0);
}

int phonetic_SetValues(IMECore core, IMEArgList arglist, int option_value)
{
	log_f("phonetic_im: phonetic_SetValues === \n");

	if (arglist == NULL) return(-1);

  arglist->args_num = 0;
	return(0);
}

/* return the name and encode status and status of codetable IME */

int phonetic_Init(IMECore core)
{
	int  		ret;
	char		*file_name;
	TableStruct tHeader;

	log_f("phonetic_im: phonetic_Init ====\n");

	/* read table from file to memory buffer  */
	file_name = core->envinfo.data_path;
	log_f("phonetic_im: file name :%s\n",file_name);

	ret = LoadTableHeader(file_name, &tHeader); 
	if (ret == -1) 
		return (-1);

	/* Return Information that needed by Input Method Manager */
	/* Such as Encode, Cname, Status */

	core->baseinfo.status = ENGINE_NOT_INITIATED;
  log_f("Lname:%s\n",tHeader.Lname);
  core->baseinfo.lname = (char *)strdup(tHeader.Lname);
  log_f("Cname:%s\n",tHeader.Cname);
	core->baseinfo.cname = (char *)strdup(tHeader.Cname);
  log_f("encode_id:%d\n",tHeader.Encode);
	core->baseinfo.encode_id = tHeader.Encode;
  log_f("Engine_id:%d\n",core->baseinfo.engine_id);

  log_f("UsedCodes:%s\n",tHeader.UsedCodes);

	return(0);
}

int phonetic_Open(IMECore core, IMEBuffer ime_buffer, void *handler)
{
	char		*file_name;
	int		i, ret;

	log_f("phonetic_im: phonetic_Open ==== \n");

	ime_buffer->encode = 0;
	ime_buffer->return_status = 0;
	ime_buffer->preedit_len = 0;
	ime_buffer->commit_len  = 0;
	ime_buffer->lookup_num  = 0;
	ime_buffer->cur_lookup_pos = 0;


	if (core->baseinfo.status == ENGINE_NOT_INSTALLED){
    log_f("phonetic_Open: ENGINE_NOT_INSTALLED \n");
   	return(-1);
  }

	if (core->baseinfo.status == ENGINE_INITIATED) {
    if(table_Num > 0){
      log_f("table_Num:%d\n", table_Num);
      for (i=0; i<table_Num; i++){
        log_f("phtable_Info[%d].EngineId:%d, phtable_Info[%d]->ptr:%x\n",i,phtable_Info[i]->EngineId, i, phtable_Info[i]->ptr);
        log_f("core->baseinfo.engine_id:%d\n",core->baseinfo.engine_id);
        if(phtable_Info[i]->EngineId == core->baseinfo.engine_id){
          core->envinfo.data_ptr = phtable_Info[i]->ptr; 
          fNum = i;
          log_f("fNum:%d\n",fNum);
        }
      }
    }
    log_f("phonetic_Open: ENGINE_INITIATED \n");
		return 0;
  }

	/* if IME engine is not initiated, would malloc dictionary buffer */

	core->baseinfo.status = ENGINE_NOT_INSTALLED;

	/* read table from file to memory buffer  */
	file_name = core->envinfo.data_path;
	log_f("phonetic_Open: file name :%s\n",file_name);

	phtable_Info[table_Num] = (TableStruct *)calloc(1, sizeof(TableStruct));
	if (phtable_Info[table_Num] == NULL) {
		fprintf(stderr, "Error in Calloc: %s\n",core->baseinfo.ename);
		return(-1);
	}

  ret = LoadTableHeader(file_name, phtable_Info[table_Num]);
  if(ret == -1){
    free((char *)phtable_Info[table_Num]);
    return(-1);
  }
  phtable_Info[table_Num]->EngineId = core->baseinfo.engine_id;
  phtable_Info[table_Num]->ptr = (char *)phtable_Info[table_Num];

  log_f("phonetic_Open: Calling dlsym for Fname:%s\n",phtable_Info[table_Num]->Fname);
  log_f("phonetic_Open: Calling dlsym handler:%x\n",handler);
  fArray[table_Num] = (int(*)(char *, unsigned char **, int *, int, int)) dlsym(handler, phtable_Info[table_Num]->Fname);
  if(!fArray[table_Num]){
    log_f("dlsym error\n");
    return(-1);
  }

	core->baseinfo.status = ENGINE_INITIATED;
	core->envinfo.data_ptr = (char *)phtable_Info[table_Num];

  fNum = table_Num;

  table_Num ++; 

  word_start_flag = 1;
  word_separator_flag = 0;
  word_end_flag = 0;

	return(0);
}

/* close IME, and free codetable pointers */
void phonetic_Close(IMECore core)
{
	int		i;

	log_f("phonetic_im: phonetic_Close ==== \n");

  for (i=0; i<table_Num; i++){
    if(phtable_Info[i])
      free(phtable_Info[i]);
  }

  if (core->baseinfo.lname)
    free((char *)core->baseinfo.lname);
	if (core->baseinfo.cname)
		free((char *)core->baseinfo.cname);
	if (core->envinfo.data_path)
		free((char *)core->envinfo.data_path);
}

/* process key input event                                             */
/* return value:  IME_NOT_USED_KEY:  if IME not use this key, return   */
/*                                   this key to systerm directly      */
/*                IME_USED_KEY:      if IME has used this key          */

int  phonetic_Filter(core, key_event, ime_args, ime_buffer)
IMECore core;
IMEKey  key_event;
IMEArgList ime_args;
IMEBuffer ime_buffer;
{
	int 		ret;
	TableStruct *tHeader;

	log_f("phonetic_im: phonetic_Filter ==== \n");

	if (core->baseinfo.status != ENGINE_INITIATED)
		return(IME_NOT_USED_KEY);
		
	/* set tHeader's argument setting */
	
	/* tHeader's argument setting are always coveried by user defined data */
	tHeader = (TableStruct *)(core->envinfo.data_ptr);
	tHeader->Output_Encode = core->envinfo.output_encode_id;

	ret = phonetic_filter(tHeader, key_event, ime_buffer);
	log_f("phonetic_im: phonetic_filter : return: %d\n", ret);
	return(ret);
}

