#ifndef _KOINPUT_H_
#define _KOINPUT_H_

#include <X11/Xmd.h>
#include <IMProtocolStruct.h>
#include "aux-message.h"
#include "le-options.h"

/***************************************************************************/
/*                          Int'l readiness                                */
/***************************************************************************/

#define _(String) (String)
#define N_(String) String
#define textdomain(Domain)
#define bindtextdomain(Package, Directory)


#define MAX_SESSION 		1024
/***************************************************************************/
/*                          Key  Definition                                */
/***************************************************************************/

/* Key Used by Input Method Manager */

#define IMM_NOT_USED_KEY			0
#define IMM_USED_KEY				1
#define FULL_HALF_WIDTH_SWITCH_KEY		2
#define HEX_INPUT_IN_EUC_MODE_KEY		3 
#define HEX_INPUT_IN_UTF8_MODE_KEY		4
#define ENGLISH_KOREAN_SWITCH_KEY		5
#define SYMBOL_INPUT_MODE_KEY			6
#define HANJA_CONVERSION_DEFAULT_KEY		20
#define HANJA_CONVERSION_HANJA_KEY		21
#define HANJA_CONVERSION_HANGUL_HANJA_KEY	22
#define HANJA_CONVERSION_HANJA_HANGUL_KEY	23

#define KEYBOARD_LAYOUT_TOGGLE_KEY		30
/*
  #define KEYBOARD_LAYOUT_2BEOLSIK_KEY		30
  #define	KEYBOARD_LAYOUT_3BEOLSIK_390_KEY	31
  #define KEYBOARD_LAYOUT_3BEOLSIK_FINAL_KEY	32
*/
/* Key Used by Input Method Entry */
#define IME_NOT_USED_KEY		0
#define IME_USED_KEY			1
#define ESC_KEY               		2
#define BACKSPACE_KEY        		3
#define RETURN_KEY            		4
#define INSERT_KEY			5
#define DELETE_KEY			6
#define HOME_KEY			7
#define END_KEY				8
#define PAGEUP_KEY             		9
#define PAGEDOWN_KEY           		10
#define SPACE_KEY           		0x20

/***************************************************************************/
/*                    Input Method Engine  Definition                      */
/***************************************************************************/
#define	MAX_CANDIDATES_NUM		16
#define MAX_INPUT_KEY_NUM		256
#define MAX_PREEDIT_CHAR_NUM		256
#define MAX_CANDIDATE_CHAR_NUM 		256
#define MAX_STATUS_CHAR_NUM    		256
#define MAX_COMMIT_CHAR_NUM    		512

#define MAX_KEYMAP_KEY_NUM		95

#define IME_PREEDIT_AREA 		1
#define IME_LOOKUP_AREA  		2
#define IME_STATUS_AREA  		4
#define IME_COMMIT       		8

#define ENGINE_NOT_INSTALLED 		1
#define ENGINE_NOT_INITIATED 		2
#define ENGINE_INITIATED     		3

#define DEFAULT_ENGINE_PATH		"/usr/lib/im/locale"
#define DEFAULT_DICT_PATH		"data"
#define COMMON_ENGINE_PATH		"common"
#define LANGNAME                        "ko_KR"
#define DEFAULT_DICT_NAME               "hhdict"

#define CODETABLE_ENGINE_NAME    	"ctim"
#define USER_PROFILE_PATH      		".Xlocale"
#define USER_PROFILE_NAME      		"ime.cfg"
#define SYSTEM_PROFILE_NAME      	"sysime.cfg"
#define USER_OPTION_FILE_NAME      	"options.cfg"

#define NUMERIC_LABEL			0
#define LOWER_LABEL			1
#define UPPER_LABEL			2

#define MAX_ENGINE_NUM			127
#define MAX_NAME_LEN			16

#define MAX_OPTION_NUM			6
#define MAX_ARGS_NUM			10

/***************************************************************************/
/*         Protocol used by Auxiliary window and Language Engine           */
/***************************************************************************/
/* Conversion Status */
typedef enum {
  CONVERSION_OFF = 0,
  CONVERSION_ON = 1
} CONVERSION_STATUS_T;


/* Types of Input Method Switching */
#define IME_ROUND_SWITCH  		0
#define IME_SELECT_SWITCH		1


/***************************************************************************/
/*                 Keyboard Layout Support				   */
/***************************************************************************/

typedef enum _KEYBOARD_T {
  KEYBOARD_LAYOUT_2BEOLSIK =  0,
  KEYBOARD_LAYOUT_3BEOLSIK_390 = 1,
  KEYBOARD_LAYOUT_3BEOLSIK_FINAL = 2
} KEYBOARD_T;

#define KEYBOARD_2BEOLSIK			"2벌식"
#define KEYBOARD_3BEOLSIK_390			"3벌식 390"
#define KEYBOARD_3BEOLSIK_FINAL			"3벌식 최종"
/***************************************************************************/
/*                 User Preference Information				    /
		   /***************************************************************************/

#define IDX_IME_USER_ID						0
#define IDX_IME_USER_HOME					1
#define IDX_KEYBOARD_LAYOUT					2
#define IDX_CONVERSION_FORMAT					3
#define IDX_AUTO_COMMIT_ON_CHAR_BASIS				4
#define IDX_AUTO_COMMIT_ON_SINGLE_CANDIDATE_CONVERSION		5

#define STR_IME_USER_ID			"ime_user_id"
#define STR_IME_USER_HOME		"ime_user_home"
#define STR_KEYBOARD_LAYOUT		"keyboard_layout"
#define STR_CONVERSION_FORMAT		"conversion_format"
#define STR_AUTO_COMMIT_ON_CHAR_BASIS	"auto_commit_on_char_basis"
#define STR_AUTO_COMMIT_ON_SINGLE_CANDIDATE_CONVERSION "auto_commit_on_single_candidate_conversion"

#define OPTION_PAIR_NUM		6

typedef enum _option_type {
  type_pchar, type_int
}option_type;

typedef struct _Option_Pair{
  option_type type;
  char *option_name;
  union {
    char *string_value;
    int integer_value;
  }value;
}Option_Pair;


enum conversion_key_sequence {
  ctrl_q = 0,
  ctrl_h,
  ctrl_e,
  ctrl_r,
  /*
    ctrl_w,
  */
  ctrl_x,
  ctrl_shift_x
};
enum conversion_format {
  hanja_only = 0,
  hangul_hanja,
  hanja_hangul
};

typedef enum _keyboard_layout {
  KBD_LAYOUT_2BEOLSIK = 0,
  KBD_LAYOUT_3BEOLSIK_390,
  KBD_LAYOUT_3BEOLSIK_FINAL,
} keyboard_layout;

typedef struct _UserPreference{
  int	ime_user_id;
  char	*ime_user_home;
  int     keyboard_layout;
  int     conversion_format;
  int     auto_commit_on_char_basis;
  int     auto_commit_on_single_candidate_conversion;
}UserPreference;


/***************************************************************************/
/*                 IME structure used by Language Engine                   */
/***************************************************************************/

#define INPUT_MODE_HANGUL_STR                   "한글"
#define INPUT_MODE_HEX_IN_EUC_STR               "코드(KS X 1001)"
#define INPUT_MODE_HEX_IN_UTF8_STR              "코드(UTF-8)"
#define INPUT_MODE_SYMBOL_STR                   "특수 기호"
#define INPUT_MODE_HANJA_STR  	               "한자"

typedef struct _IMEKeyEventStruct IMEKeyEventStruct, *IMEKeyEvent;

struct _IMEKeyEventStruct {
  int key_code;
  int key_char;
  int key_modifier;
};

typedef enum _INPUT_MODE_T {
  INPUT_MODE_NONE = -1,
  INPUT_MODE_ENGLISH,
  INPUT_MODE_HANGUL,
  INPUT_MODE_HANJA,
  INPUT_MODE_HEX_EUC,
  INPUT_MODE_HEX_UTF8,
  INPUT_MODE_SYMBOL_MENU,
  INPUT_MODE_SYMBOL
} INPUT_MODE_T;

/* IMEBaseRec that shared between Language Engine and Auxiliary Window. */
typedef struct {
  CARD8 		engine_id;		/* engine identity */
  CARD8 		locale_id;		/* supported locale idendity */
  CARD8 		encode_id;		/* encode that dictionary used */
  CARD8 		status;			/* engine status: initialized or installed */
  char		*ename; 		/* English name of this engine */
  char 		*kname;			/* Korean Name of this engine */
} IMEBaseRec, *IMEBase;

/* Arguments:
   system arguments ---> IMECoreRec
   user defined arguments   ---> Desktop_data
*/
typedef struct {
  char		*name;
  CARD8		type;
  CARD8 		value;
} IMEArgRec, *IMEArg;
	
typedef struct { 
  int 		args_num;
  IMEArgRec	args[MAX_ARGS_NUM];
} IMEArgListRec, *IMEArgList;

/* Runtime Environment */
typedef struct { 
  CARD8	output_encode_id;	/* encode that IME need output */
  char 	*lang_name;		/* language name such as zh_CN/zh_TW... */
  char 	*locale_name;		/* locale name defined in config file */
  char 	*data_path;		/* directory for dictionary */
  char 	*data_ptr;		/* memory pointer for dictionary data */
} IMEEnvListRec, *IMEEnvList;

/* Keymap Information */
typedef struct {
  char 		bSet;			/* whether be set by IM engine */
  char 		*keymap[MAX_KEYMAP_KEY_NUM];
} IMEKeyMapRec, *IMEKeyMap;

typedef struct {
  int n_count;
  IMEKeyEventStruct **keylist;
} IMEHotKeyRec, *IMEHotKey;

/* IME Core Information */
typedef struct {
  IMEBaseRec	baseinfo;		/* Input Method Entry information */
  IMEEnvListRec	envinfo;		/* runtime environment of IME engine */
  IMEArgListRec	argsinfo;		/* system arguments setting */
  IMEKeyMapRec	keymapinfo;		/* key mapping for the IM */
  IMEHotKeyRec  hotkeys;
} IMECoreRec, *IMECore;

typedef struct _IMEBufferRec IMEBufferRec, *IMEBuffer;
typedef struct _IMEBufferMethodsRec IMEBufferMethodsRec, *IMEBufferMethods;
typedef struct _IMEBufferWhatToDo IMEBufferWhatToDo;
struct _IMEBufferWhatToDo {
  Bool do_preedit;
  Bool do_status;
  Bool do_lookup;
  Bool do_commit;
  Bool do_sendback;
};


struct _IMEBufferMethodsRec {
  Bool (*ime_engine_start)(int, KOLE_config **);
  /*
    Bool ( *ime_buffer_set_user_options) (UserPreference *);
  */
  Bool (*ime_engine_get_hotkeys)(int *, IMEKeyEventStruct ***);
  Bool (*ime_buffer_new) (IMEBuffer *, int session_id, int engine_id);
  Bool (*ime_buffer_initialize) (IMEBuffer);
  Bool (*ime_buffer_conversion_start) (IMEBuffer);
  Bool (*ime_buffer_conversion_end) (IMEBuffer);

  Bool (*ime_buffer_get_session_id) (IMEBuffer, int *);
  Bool (*ime_buffer_get_engine_id) (IMEBuffer, int *);
  Bool (*ime_buffer_get_input_mode) (IMEBuffer , INPUT_MODE_T *);
  Bool (*ime_buffer_get_keyboard_layout)(IMEBuffer, KEYBOARD_LAYOUT_T *);
  Bool (*ime_buffer_get_active_repertoire)(IMEBuffer, OPTION_CHARSET *);
  Bool (*ime_buffer_set_active_repertoire)(IMEBuffer, OPTION_CHARSET *);
  Bool (*ime_buffer_get_deletion_option) (IMEBuffer, OPTION_DELETION *);
  Bool (*ime_buffer_get_commitmode_option) (IMEBuffer, OPTION_DELETION *);
  Bool (*ime_buffer_get_preedit) (IMEBuffer , UTFCHAR **);
  Bool (*ime_buffer_get_status) (IMEBuffer, UTFCHAR **);
  Bool (*ime_buffer_get_commit_string) (IMEBuffer ,UTFCHAR **);

  Bool (*ime_buffer_get_candidates) (IMEBuffer, int *, int *, UTFCHAR ***);
  Bool (*ime_buffer_lookup_do_next_page) (IMEBuffer a_buffer, int *new_page_num_return);
  Bool (*ime_buffer_lookup_do_previous_page) (IMEBuffer a_buffer, int *new_page_num_return);
  Bool (*ime_buffer_lookup_do_scroll) (IMEBuffer a_buffer);
  Bool (*ime_buffer_lookup_do_select_candidate) (IMEBuffer a_buffer, IMEKeyEventStruct *);
	
  Bool (*ime_buffer_get_current_lookup_pos) (IMEBuffer, int *);
  Bool (*ime_buffer_process_key_input) (IMEBuffer, IMEKeyEventStruct *);
  Bool (*ime_buffer_free) (IMEBuffer );
  Bool (*ime_buffer_get_what_to_do) (IMEBuffer ,IMEBufferWhatToDo **);
  Bool (*ime_buffer_set_what_to_do) (IMEBuffer ,IMEBufferWhatToDo *);
  Bool (*ime_buffer_get_configuration)(IMEBuffer, int *, KOLE_config ***);
  Bool (*ime_engine_finish) ();
};


typedef struct {
  IMECoreRec	core;
  IMEBufferMethods	so_methods;
  void		*so_handler;
} IMEEngineRec, *IMEEngine;

typedef struct {
  int 		nIME_Num;
  IMEBaseRec	*arrIME_Base[MAX_ENGINE_NUM];
} IMEListRec;


typedef struct _SessionProperty SessionProperty;
struct _SessionProperty {
  int count;
  KOLE_config *pconfig;
};

#endif   /* _KOINPUT_H_  */

