/*
###
### This file is part of
###
###                        TurboLinux  ZWinPro
###
###                 Copyright (C) 1999-2000 TurboLinux, Inc.
###                        All Rights Reserved
### Distributed under the terms of the GNU General Public License (GPL)
###
###
### Authors:     TurboLinux Chinese Development Team:
###              Justin Yu   <justiny@turbolinux.com.cn>
###              Sean Chen   <seanc@turbolinux.com.cn>
###              Daniel Fang <danf@turbolinux.com.cn>
###
*/

#include "all.h"

// Show current XIM styles
#if 0
static void chinput_print_ximstyle (void)
{
	IC *ic = (IC *)chinput_find_ic (last_icid);

	//print out the input style of this ic
	if (ic->input_style & XIMPreeditNothing) 
		printf("XIMPreeditNothing");
	else if (ic->input_style & XIMPreeditPosition)
		printf("XIMPreeditPosition");
	else if (ic->input_style & XIMPreeditCallbacks)
		printf("XIMPreeditCallbacks");
	else if (ic->input_style & XIMPreeditNone)
		printf("XIMPreeditNone");
	else if (ic->input_style & XIMPreeditArea)
		printf("XIMPreeditArea");
	printf("|");

	if (ic->input_style & XIMStatusNothing)
		printf("XIMStatusNothing");
	else if (ic->input_style & XIMStatusArea)
		printf("XIMStatusArea");
	else if (ic->input_style & XIMStatusCallbacks)
		printf("XIMStatusCallbacks");
	else if (ic->input_style & XIMStatusNone)
		printf("XIMStatusNone");
	printf("\n");
}
#endif

static int chinput_get_dmode (IC *ic)
{
	if (ic->input_style & XIMPreeditCallbacks)
		return HZSERVER_DMODE_ONSPOT;
	else if (ic->input_style & XIMPreeditPosition)
		return HZSERVER_DMODE_OVERSPOT;
	else if (ic->input_style & XIMPreeditArea)
		return HZSERVER_DMODE_OFFSPOT;
	else if (ic->input_style & XIMPreeditNothing)
		return HZSERVER_DMODE_ROOT;
	return -1;
}

// When focus in, set the current ic
// current_focus_ic is used to judge if the request is
// from the current window
Boolean chinput_proc_focus_in (IMChangeFocusStruct *call_data)
{
	IC *ic;

	ic = (IC *) chinput_find_ic (call_data->icid);
	if (!ic)
		return True;

	// If last IC is using offspot, shut it down : )
	if (last_icid)
	{
		IC *tic = (IC *) chinput_find_ic (last_icid);;
		if (tic && tic->input_style & XIMStatusArea)
			chinput_offspot_hide_status_window (tic);
	}

	last_icid = call_data->icid;
	last_connectid = call_data->connect_id;

	prev_dmode = chinput_get_dmode (ic);

	// Record current ic and encoding
	current_focus_ic = ic;
	flag_encoding = ic->encoding;

	// Alert Docking?
#if 0
	chinput_print_ximstyle (ic);
#endif

	if (flag_automode == True)
	{
		// Set input server's display mode
		if ((ic->input_style & XIMPreeditPosition)
				&& ((ic->input_style & XIMStatusNothing)
					|| (ic->input_style & XIMStatusArea)
					|| (ic->input_style & XIMStatusNone)))
		{
//			printf("set to caret mode\n");
//			chinput_set_mode (HZSERVER_DMODE_OVERSPOT);
			dmode = HZSERVER_DMODE_OVERSPOT;
		}
		else if ((ic->input_style & XIMPreeditArea)
				&& ((ic->input_style & XIMStatusArea)
					|| (ic->input_style & XIMStatusNothing)
					|| (ic->input_style & XIMStatusNone)))
		{
			//printf("set to offspot mode\n");
			//chinput_set_mode (HZSERVER_DMODE_OFFSPOT);
			dmode = HZSERVER_DMODE_OFFSPOT;
		}
		else if ((ic->input_style & XIMPreeditNothing)
				&& ((ic->input_style & XIMStatusNothing)
					|| (ic->input_style & XIMStatusNone)))
		{
			//printf("set to root mode\n");
			//chinput_set_mode (HZSERVER_DMODE_ROOT);
			dmode = HZSERVER_DMODE_ROOT;
		}
		else if ((ic->input_style & XIMPreeditCallbacks) &&
				((ic->input_style & XIMStatusArea) ||
				(ic->input_style & XIMStatusCallbacks) ||
				(ic->input_style & XIMStatusNothing) ||
				(ic->input_style & XIMStatusNone)))
		{
			//printf("set to onspot mode\n");
			//chinput_set_mode (HZSERVER_DMODE_ONSPOT);
			dmode = HZSERVER_DMODE_ONSPOT;
		}
	}

	chinput_set_mode (dmode);

	if (dmode == HZSERVER_DMODE_ONSPOT)
	{
		chinput_set_mode (HZSERVER_DMODE_ONSPOT);

		//for onthespot style, the server should
		//clear the previous input buffer before other operation
		chinput_onspot_preedit_clear();
	}
	else if (dmode == HZSERVER_DMODE_OFFSPOT)
	{
		//if the areas are controlled by the client,
		//then reset the background and foreground of drawing gc
		if (flag_client == HZSERVER_AREAMODE_CLIENT)
		{
			if (ic->sts_attr.foreground == ic->sts_attr.background)
			{
				ic->sts_attr.foreground = WhitePixel(display, screen_num);
				ic->sts_attr.background = BlackPixel(display, screen_num);
			}
			XSetForeground(display, offspot_gc, ic->sts_attr.foreground);
			XSetBackground(display, offspot_gc, ic->sts_attr.background);
			XSetForeground(display, offspot_bggc, ic->sts_attr.background);
			XSetBackground(display, offspot_bggc, ic->sts_attr.foreground);
		}
		if (map_mode == 0)
			chinput_offspot_hide_windows ();
	}
	else if (dmode == HZSERVER_DMODE_OVERSPOT)
	{
#if 0
		if (map_mode == 1)
			chinput_overspot_set_location(ic);
		else
			chinput_offspot_hide_status_window (ic);
#endif
		if (map_mode == 0)
			chinput_offspot_hide_status_window (ic);
		chinput_overspot_set_location(ic);
	}

	//flush all
	if (map_mode == 1)
	{
		if(dmode == HZSERVER_DMODE_ROOT)
			chinput_root_flush();
		else if(dmode == HZSERVER_DMODE_OVERSPOT)
			chinput_overspot_flush();
		else if(dmode == HZSERVER_DMODE_ONSPOT)
			chinput_onspot_flush ();
		else if(dmode == HZSERVER_DMODE_OFFSPOT)
			chinput_offspot_flush ();
	}

	return True;
}

Boolean chinput_proc_focus_out (IMChangeFocusStruct *call_data)
{
	//for onthe spot style, clear the preedit area
        IC *ic;

        last_icid = call_data->icid;
        last_connectid = call_data->connect_id;
        ic = (IC *)chinput_find_ic(call_data->icid);

	if((ic->input_style & XIMPreeditCallbacks) &&
	   ((ic->input_style & XIMStatusArea)    ||
	    (ic->input_style & XIMStatusCallbacks)    ||
	    (ic->input_style & XIMStatusNothing) ||
	    (ic->input_style & XIMStatusNone))){
		chinput_onspot_preedit_clear();
	}

	if (ic->input_style & XIMPreeditPosition)
	{
		chinput_hide_window ();
	}

	return True;
}

Boolean chinput_proc_reset_ic (IMResetICStruct *call_data)
{
	//IC *ic;
	//ic = (IC *)chinput_find_ic(call_data->icid);
	return True;
}

//After strings committed , set the current ic,
//this is useful for caret mode
void chinput_proc_set_current_ic (IMForwardEventStruct *call_data)
{
	IC *ic;

	if(flag_automode == False) return;

	ic = (IC *)chinput_find_ic (call_data->icid);
	if(ic != NULL) current_focus_ic = ic;

	//for mozilla, no focus in event, so we have to check
	//input style every time when ic is reset
	dmode = chinput_get_dmode (ic);
	if(dmode != prev_dmode){
		prev_dmode = dmode;
		//switch to dmode
		chinput_set_mode (dmode);
	}
}

void chinput_proc_auto_hide (void)
{
	if(hmode == HZSERVER_HMODE_AUTO)
		hmode = HZSERVER_HMODE_NO;
	else
		hmode = HZSERVER_HMODE_AUTO;
}
