#include <stdio.h>

#include "le_info.h"
#include "le_session.h"
#include "le_desktop.h"
#include "wtt_isc.h"
#include "encode.h"

LeDesktopContextRec *le_session_get_desktop_context(iml_session_t * s);
LeSessionContextRec *le_session_get_session_context(iml_session_t * s);

LeResult le_session_set_focus_out(iml_session_t * s);
LeResult le_session_set_focus_in(iml_session_t * s);

extern LeInfoRec *le_info;

/*****************************************
      LeSessionContextRec
*****************************************/
LeSessionContextRec *le_session_context_new()
{
    LeSessionContextRec *le_session_context = NULL;

    le_session_context =
	(LeSessionContextRec *) calloc(1, sizeof(LeSessionContextRec));
    if (le_session_context == NULL)
	return (NULL);

    le_session_context->current_conversion_status = CONVERSION_OFF;
    le_session_context->current_input_mode_id = WTT_ISC0;
    le_session_context->current_keyboard_id = 0;

    return (le_session_context);
}

LeResult le_session_context_destroy(LeSessionContextRec *
				    le_session_context)
{
    if (le_session_context == NULL)
	return (LE_FAIL);

    free((char *) le_session_context);

    return (LE_OK);
}

LeResult le_session_context_print(LeSessionContextRec * le_session_context)
{
    if (le_session_context == NULL)
	return (LE_FAIL);

    return (LE_OK);
}

/*****************************************
      LE Session for iml_session_t
*****************************************/
LeSessionContextRec *le_session_create(iml_session_t * s)
{
    LeDesktopContextRec *le_desktop_context = NULL;
    LeSessionContextRec *le_session_context = NULL;
    int default_input_mode_id;
    int default_keyboard_id;
    int default_conversion_status;

    le_session_context = (LeSessionContextRec *) le_session_context_new();
    if (le_session_context == NULL)
	return (NULL);

    le_desktop_context =
	(LeDesktopContextRec *) le_session_get_desktop_context(s);
    default_input_mode_id =
	le_desktop_context_get_default_input_mode_id(le_desktop_context);
    default_keyboard_id =
	le_desktop_context_get_default_keyboard_id(le_desktop_context);
    default_conversion_status =
	le_desktop_context_get_default_conversion_status
	(le_desktop_context);

    le_session_context->current_input_mode_id = default_input_mode_id;
    le_session_context->current_keyboard_id = default_keyboard_id;
    le_session_context->current_conversion_status =
	default_conversion_status;

    le_session_context->s = s;

    s->specific_data = (void *) le_session_context;

    return (le_session_context);
}

LeResult le_session_destroy(iml_session_t * s)
{
    DEBUG_printf("le_session_destroy: s: 0x%x\n", s);

    LeSessionContextRec *le_session_context =
	le_session_get_session_context(s);

    if (le_session_context != NULL) {
	le_session_context_destroy(le_session_context);
    }

    return (LE_OK);
}

LeResult le_session_set_focus_out(iml_session_t * s)
{
}

LeResult le_session_set_focus_in(iml_session_t * s)
{
    LeSessionContextRec *le_session_context = NULL;
    ConversionStatus conversion_status;

    le_session_context = le_session_get_session_context(s);
    if (le_session_context == NULL)
	return (LE_FAIL);

    conversion_status = le_session_context->current_conversion_status;
    DEBUG_printf("le_session_set_focus_in: %d\n", conversion_status);
    if (conversion_status == CONVERSION_OFF) {
	le_status_draw(s, CONVERSION_OFF);
    } else {
	le_status_draw(s, CONVERSION_ON);
    }

    return (LE_OK);
}

IMText *le_session_reset(iml_session_t * s)
{
    return ((IMText *) NULL);
}

/*****************************************
      LE Session Functions for iml_session_t
*****************************************/
LeDesktopContextRec *le_session_get_desktop_context(iml_session_t * s)
{
    return ((LeDesktopContextRec *) s->desktop->specific_data);
}

LeSessionContextRec *le_session_get_session_context(iml_session_t * s)
{
    return (LeSessionContextRec *) s->specific_data;
}

ConversionStatus le_session_get_conversion_status(iml_session_t * s)
{
    LeSessionContextRec *le_session_context = NULL;

    le_session_context = le_session_get_session_context(s);
    if (le_session_context == NULL)
	return (CONVERSION_OFF);

    return (le_session_context->current_conversion_status);
}

LeResult le_session_set_conversion_status(iml_session_t * s,
					  ConversionStatus
					  conversion_status)
{
    LeSessionContextRec *le_session_context = NULL;

    le_session_context = le_session_get_session_context(s);
    if (le_session_context == NULL)
	return (LE_FAIL);

    if (conversion_status == CONVERSION_OFF) {
	le_status_draw(s, CONVERSION_OFF);
	le_iml_conversion_off(s);
    } else {
	le_iml_conversion_on(s);
	le_status_draw(s, CONVERSION_ON);
    }

    le_session_context->current_conversion_status = conversion_status;

    return (LE_OK);
}

LeResult le_session_toggle_conversion_status(iml_session_t * s)
{
    LeSessionContextRec *le_session_context = NULL;
    ConversionStatus conversion_status;
    LeResult le_result;

    le_session_context = le_session_get_session_context(s);
    if (le_session_context == NULL)
	return (LE_FAIL);

    conversion_status = le_session_context->current_conversion_status;
    DEBUG_printf("le_session_toggle_conversion_status: %d\n",
		 ~conversion_status);
    if (conversion_status == CONVERSION_OFF) {
	le_result = le_session_set_conversion_status(s, CONVERSION_ON);
    } else {
	le_result = le_session_set_conversion_status(s, CONVERSION_OFF);
    }

    return (le_result);
}

LeResult le_session_set_as_desktop_current_session(iml_session_t * s)
{
    LeDesktopContextRec *le_desktop_context = NULL;

    le_desktop_context =
	(LeDesktopContextRec *) le_session_get_desktop_context(s);
    le_desktop_context_set_current_session(le_desktop_context, s);

    return (LE_OK);
}

int le_session_get_isc_mode(iml_session_t * s)
{
    LeDesktopContextRec *le_desktop_context =
	(LeDesktopContextRec *) le_session_get_desktop_context(s);
    LeSessionContextRec *le_session_context =
	le_session_get_session_context(s);
    int current_input_mode_id;

    current_input_mode_id = le_session_context->current_input_mode_id;

    if (current_input_mode_id < 0
	|| current_input_mode_id >= WTT_ISC_MODES_NUM)
	current_input_mode_id = le_desktop_context->default_input_mode_id;

    return (current_input_mode_id);
}

int le_session_save_isc_mode(iml_session_t * s, int current_input_mode_id)
{
    LeSessionContextRec *le_session_context =
	le_session_get_session_context(s);

    if (current_input_mode_id < 0
	|| current_input_mode_id >= WTT_ISC_MODES_NUM)
	current_input_mode_id = WTT_ISC0;

    le_session_context->current_input_mode_id = current_input_mode_id;
}

int le_session_get_keyboard_mode(iml_session_t * s)
{
    LeDesktopContextRec *le_desktop_context =
	(LeDesktopContextRec *) le_session_get_desktop_context(s);
    LeSessionContextRec *le_session_context =
	le_session_get_session_context(s);
    int current_keyboard_id;

    current_keyboard_id = le_session_context->current_keyboard_id;

    if (current_keyboard_id < 0
	|| current_keyboard_id >= le_info->keymap_list->nNum_Keymaps)
	current_keyboard_id = le_desktop_context->default_keyboard_id;

    return (current_keyboard_id);
}

int le_session_save_keyboard_mode(iml_session_t * s,
				  int current_keyboard_id)
{
    LeDesktopContextRec *le_desktop_context =
	(LeDesktopContextRec *) le_session_get_desktop_context(s);
    LeSessionContextRec *le_session_context =
	le_session_get_session_context(s);

    if (current_keyboard_id < 0
	|| current_keyboard_id >= le_info->keymap_list->nNum_Keymaps)
	current_keyboard_id = le_desktop_context->default_keyboard_id;

    le_session_context->current_keyboard_id = current_keyboard_id;
}

int le_session_get_previous_char(iml_session_t * s)
{
    LeSessionContextRec *le_session_context =
	le_session_get_session_context(s);
    return (le_session_context->char_previous);
}

int le_session_save_previous_char(iml_session_t * s, char ch)
{
    LeSessionContextRec *le_session_context =
	le_session_get_session_context(s);
    le_session_context->char_previous = ch;
}
