#include <config.h>
#include <stdio.h>
#include "IMInputContext.hh"
#include "IMConnection.hh"
#include "IMSvr.hh"
#include "LEMgr.hh"
#include "IMLog.hh"

//
// LEContext management.
//

LEMgr*
IMInputContext::get_lemgr()
{
    return get_imconnection()->get_imsvr()->get_lemgr();
}

LEContext*
IMInputContext::create_lecontext()
{
    LEContext* plec;

    plec = get_lemgr()->choose_LE(this);
    if (plec) leclist.push_back(plec);

    return plec;
}

LEContext*
IMInputContext::get_current_lecontext()
{
    if (pcur_lec) return pcur_lec;
    pcur_lec = create_lecontext();

    if (!pcur_lec) {
	LOG_ERROR("Failed to create LE context.");
    }
    //TODO attr = pcur_lec->get_icattribute();
    return pcur_lec;
}

bool
IMInputContext::switch_lecontext(
    const ICAttribute &x_attr
)
{
    // TODO  spcicial client HTT_XBE requires this feature...
    return false;
}

//
// service for LEContext.
//

void
IMInputContext::get_lecontext_args(
    vector<IMArg> &args
)
{
    IMArg a;

    IMSetArg(a, SC_CLIENT_LOCALE,
	     attr.get_inputlanguage().get_charstr());
    args.push_back(a);
    IMSetArg(a, SC_CLIENT_INPUT_METHOD_NAME,
	     attr.get_inputmethod().get_charstr());
    args.push_back(a);
    IMSetArg(a, SC_CLIENT_CHARACTER_SUBSETS,
	     attr.get_character_subsets().get_c_csidices());
    args.push_back(a);

    return;
}

/*******************************************************************************
                        ICHandler realization
*******************************************************************************/

bool
IMInputContext::send_event(
    IMLExec* pimlex,
    IMInputEvent* pimevent
)
{
#if 0 // AUX forwarding... TODO!!!!
    if (fev->type == IM_EventAux) {
	IMAuxEvent *aux_event = (IMAuxEvent*)fev;
	ImlSession *temp_session;

	for (int i = 1; i <= session_list.getSize(); i++) {
	    temp_session = (ImlSession *)&(session_list.getItem(i));
	    int len = temp_session->mAuxName.length();
	    if (len > 0 && strstr(aux_event->aux->aux_name,
				  (const char*)temp_session->mAuxName)) {
		sc = temp_session->sc;
		break;
	    }
	}
#if 0
	// not found, save current aux name for later comparison.
	if (active_session->mAuxName.length() == 0) {
	    char *p = 0;
	    char *aux_name = strdup(aux_event->aux->aux_name);
	    if (p = rindex (aux_name, '.'))
		*p = 0;
	    active_session->mAuxName = CompoundString(aux_name);
	    free (aux_name);
	}
#endif
    }
#endif
    LEContext *plec = get_current_lecontext();

    if (!plec) return false;

    return plec->send_event(pimlex, pimevent);
}

bool
IMInputContext::send_event_getvalues(
    IMLExec* pimlex,
    IMInputEvent* pimevent
)
{
    LEContext *plec = get_current_lecontext();

    if (!plec) return false;

    return plec->send_event_getvalues(pimlex, pimevent);
}

bool
IMInputContext::send_event_getvalues_finished(
    IMLExec* pimlex
)
{
    LEContext *plec = get_current_lecontext();

    if (!plec) return false;

    return plec->send_event_getvalues_finished(pimlex);
}

const ICAttribute&
IMInputContext::get_icattr()
{
    return attr;
}

bool
IMInputContext::set_icattr(
    ICAttribute &x_attr
)
{
    attr = x_attr;
    // TODO...
    pcur_lec = create_lecontext();

    return true;
}

bool
IMInputContext::toggle_conversion(
    IMLExec *pimlex,
    bool flag
)
{
    LEContext *plec = get_current_lecontext();

    if (!plec) return false;

    return plec->toggle_conversion(pimlex, flag);
}

bool
IMInputContext::invoke_desktop_listener(
    IMLExec *pimlex,
    int listener_id,
    int file_size,
    void *object
)
{
    LEContext *plec = get_current_lecontext();
    iml_desktop_t *desktop = plec->get_iml_desktop();
    iml_listener_t *l;

    if (!plec) return false;

    l = desktop->lookupListenerFromDesktop(plec->get_iml_session(), listener_id);
    l->listener(listener_id, file_size, object, l->private_data);
   
    return true;
}

bool
IMInputContext::reset(
    IMLExec *pimlex
)
{
    LEContext *plec = get_current_lecontext();

    if (!plec) return false;

    return plec->reset(pimlex);
}

bool
IMInputContext::destroy(
    IMLExec *pimlex
)
{
    LEContextList::iterator i;
    for (i = leclist.begin(); i != leclist.end(); i++) {
	(*i)->destroy(pimlex);
    }
    delete this;
    return true;
}

void
IMInputContext::destroy()
{
    destroy_all(leclist);
    delete this;
}

bool
IMInputContext::toggle_focus(
    IMLExec *pimlex,
    bool flag
)
{
    LEContext *plec = get_current_lecontext();

    if (!plec) return false;

    return plec->toggle_focus(pimlex, flag);
}

/*******************************************************************************
                       Constructor/Destructor
*******************************************************************************/

IMInputContext::IMInputContext(
    IMConnection *x_pimc,
    const ICAttribute &x_attr
)
{
    pimc = x_pimc;
    attr = x_attr;
    pcur_lec = NULL;
}

IMInputContext::~IMInputContext()
{
    pimc->remove_inputcontext(this);
}

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