/*
  input-method.c
*/

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

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_MEMORY_H
#include <memory.h>
#endif

#include "iiimcfint.h"

IIIMF_status
iiimcf_unregister_input_method_list(
    int n,
    IIIMCF_input_method_rec **ppi
)
{
    IIIMCF_input_method_rec **pp, *p;
    int i;

    if (!ppi) return IIIMF_STATUS_FAIL;
    for (pp = ppi, i = 0; i < n; i++, pp++) {
	p = *pp;
	if (p) {
	    if (p->imname) free(p->imname);
	    if (p->hrn) free(p->hrn);
	    if (p->domain) free(p->domain);
	    if (p->pplangs) iiimcf_unregister_langs(p->num_langs, p->pplangs);
	    free(p);
	}
    }
    free(ppi);
    return IIIMF_STATUS_SUCCESS;
}

static IIIMF_status
iiimcf_register_input_method_langs(
    IIIMP_language *piml,
    int *pnum,
    IIIMCF_language_rec ***pppl
)
{
    IIIMCF_language_rec **ppl, *pl;
    IIIMP_language *p;
    IIIMP_card16 *pu;
    char *plang_id, *pc;
    int i, j, n;

    for (n = 0, p = piml; p; p = p->next) n++;
    ppl = (IIIMCF_language_rec**) malloc(sizeof(IIIMCF_language_rec*) * n);
    if (!ppl) return IIIMF_STATUS_MALLOC;
    memset(ppl, 0, sizeof(IIIMCF_language_rec*) * n);

    for (i = 0, p = piml; i < n; i++, p = p->next) {
	pl = (IIIMCF_language_rec*) malloc(sizeof(*pl));
	if (!pl) {
	    iiimcf_unregister_langs(n, ppl);
	    return IIIMF_STATUS_MALLOC;
	}
	memset(pl, 0, sizeof(*pl));
	ppl[i] = pl;
	plang_id = (char*) malloc(sizeof(char) * (p->id->len + 1));
	if (!plang_id) {
	    iiimcf_unregister_langs(n, ppl);
	    return IIIMF_STATUS_MALLOC;
	}
	for (j = 0, pu = p->id->ptr, pc = plang_id;j < p->id->len; j++) {
	    *pc++ = (*pu++ & 0x7F);
	}
	*pc = '\0';
	pl->lang_id = plang_id;

	pl->hrn = iiimcf_make_string(p->hrn->ptr, p->hrn->len);
	if (!pl->hrn) {
	    iiimcf_unregister_langs(n, ppl);
	    return IIIMF_STATUS_MALLOC;
	}
    }

    *pnum = n;
    *pppl = ppl;

    return IIIMF_STATUS_SUCCESS;
}

IIIMF_status
iiimcf_register_input_method_list(
    IIIMCF_handle_rec *ph,
    IIIMP_inputmethod_descriptor *piiimp_imlist
)
{
    IIIMF_status st;
    int i, n;
    IIIMP_inputmethod_descriptor *pimd;
    IIIMCF_input_method_rec **ppi, *pi;

    iiimcf_unregister_input_method_list(ph->num_input_methods,
					ph->ppinput_methods);

    ph->ppinput_methods = NULL;
    ph->num_input_methods = 0;

    for (n = 0, pimd = piiimp_imlist; pimd; pimd = pimd->next) n++;

    ppi = (IIIMCF_input_method_rec**) malloc(sizeof(*ppi) * n);
    if (!ppi) return IIIMF_STATUS_MALLOC;
    memset(ppi, 0, sizeof(*ppi) * n);

    for (i = 0, pimd = piiimp_imlist;
	 i < n; i++, pimd = pimd->next) {
	pi = (IIIMCF_input_method_rec*) malloc(sizeof(*pi));
	if (!pi) {
	    iiimcf_unregister_input_method_list(n, ppi);
	    return IIIMF_STATUS_MALLOC;
	}
	memset(pi, 0, sizeof(*pi));
	ppi[i] = pi;
	pi->id = pimd->id;
	pi->imname = iiimcf_make_string(pimd->idname->ptr, pimd->idname->len);
	pi->hrn = iiimcf_make_string(pimd->hrn->ptr, pimd->hrn->len);
	pi->domain = iiimcf_make_string(pimd->rdun->ptr, pimd->rdun->len);
	if ((!pi->imname) || (!pi->hrn)) {
	    iiimcf_unregister_input_method_list(n, ppi);
	    return IIIMF_STATUS_MALLOC;
	}
	st = iiimcf_register_input_method_langs(pimd->language,
						&pi->num_langs,
						&pi->pplangs);
	if (st != IIIMF_STATUS_SUCCESS) {
	    iiimcf_unregister_input_method_list(n, ppi);
	    return st;
	}
    }

    ph->num_input_methods = n;
    ph->ppinput_methods = ppi;

    return IIIMF_STATUS_SUCCESS;
}

/********************************************************************************
			            APIs
********************************************************************************/

IIIMF_status
iiimcf_get_supported_input_methods(
    IIIMCF_handle handle,
    int *pnum_input_methods,
    IIIMCF_input_method **ppinput_methods
)
{

    IIIMCF_handle_rec *ph = (IIIMCF_handle_rec*) handle;

    if (ppinput_methods) *ppinput_methods = ph->ppinput_methods;
    if (pnum_input_methods) *pnum_input_methods = ph->num_input_methods;

    return IIIMF_STATUS_SUCCESS;
}

IIIMF_status
iiimcf_get_input_method_desc(
    IIIMCF_input_method input_method,
    const IIIMP_card16** pinput_method_idname,
    const IIIMP_card16** pinput_method_hrn,
    const IIIMP_card16** pinput_method_domain
)
{
    IIIMCF_input_method_rec *pi = (IIIMCF_input_method_rec*) input_method;

    if (pinput_method_idname) *pinput_method_idname = pi->imname;
    if (pinput_method_hrn) *pinput_method_hrn = pi->hrn;
    if (pinput_method_domain) *pinput_method_domain = pi->domain;

    return IIIMF_STATUS_SUCCESS;
}

IIIMF_status
iiimcf_get_input_method_languages(
    IIIMCF_input_method input_method,
    int *pinput_method_language_size,
    IIIMCF_language **pplanguages
)
{
    IIIMCF_input_method_rec *pi = (IIIMCF_input_method_rec*) input_method;

    if (pinput_method_language_size)
	*pinput_method_language_size = pi->num_langs;
    if (pplanguages)
	*pplanguages = pi->pplangs;

    return IIIMF_STATUS_SUCCESS;
}

/* Local Variables: */
/* c-file-style: "iiim-project" */
/* End: */
