#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include <imm.h>

#include "SDL_events.h"
#include "SDL_events_c.h"

/* HK: IME Composition */
static BOOL startIMEComp = FALSE;

static int  IME_PrivateKeyboard(Uint8 state, SDL_keysym *keysym);
static void IME_getResultStr(HWND hWnd, WPARAM wParam, LPARAM lParam);
static void IME_getCompositionStr(HWND hWnd, WPARAM wParam, LPARAM lParam);

void IME_startComposition()
{
	startIMEComp = TRUE;
}

void IME_composition(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
	if (lParam & GCS_RESULTSTR) {
		IME_getResultStr(hWnd, wParam, lParam); 
	} else if (lParam & GCS_COMPSTR) {
		IME_getCompositionStr(hWnd, wParam, lParam);
	}
}

void IME_endComposition()
{
}

static int IME_PrivateKeyboard(Uint8 state, SDL_keysym *keysym)
{
	SDL_Event event;
	int posted, repeatable;

	memset(&event, 0, sizeof(event));

	repeatable = 0;

	/* Post the event, if desired */
	posted = 0;
	if ( SDL_ProcessEvents[event.type] == SDL_ENABLE ) {
		event.type = SDL_KEYDOWN;
		event.key.state = state;
		event.key.keysym = *keysym;

		if ( (SDL_EventOK == NULL) || SDL_EventOK(&event) ) {
			posted = 1;
			SDL_PushEvent(&event);
		}
	}
	return(posted);
}

static void IME_getResultStr(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
	SDL_keysym keysym = { 0, 0, KMOD_IME_COMP | KMOD_IME_COMP_RESULT, 0 };

	HIMC hIMC = NULL;
	LPSTR lpResultStr = NULL;
	DWORD dwBufLen = 0;

	if (!(hIMC = ImmGetContext(hWnd))) 
		return;

	if ((dwBufLen = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0)) > 0)
	{
		lpResultStr = (LPSTR)malloc(dwBufLen + 1);
		lpResultStr[dwBufLen] = '\0';

		ImmGetCompositionString(hIMC, GCS_RESULTSTR, lpResultStr, dwBufLen);
		memcpy(&keysym.unicode, lpResultStr, sizeof(keysym.unicode));
		//printf("result_str : %s, 0x%x\n", lpResultStr, keysym.unicode);

		IME_PrivateKeyboard(SDL_PRESSED, &keysym);

		free(lpResultStr);
	}	

	ImmReleaseContext(hWnd, hIMC);
}

static void IME_getCompositionStr(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
	SDL_keysym keysym = { 0, 0, KMOD_IME_COMP, 0 };

	HIMC hIMC = NULL;
	LPSTR lpResultStr = NULL;
	DWORD dwBufLen;

	if (!(hIMC = ImmGetContext(hWnd))) 
		return;

	if ((dwBufLen = ImmGetCompositionString(hIMC, GCS_COMPSTR, NULL, 0)) > 0)
	{
		lpResultStr = (LPSTR)malloc(dwBufLen + 1);
		lpResultStr[dwBufLen] = '\0';

		ImmGetCompositionString(hIMC, GCS_COMPSTR, lpResultStr, dwBufLen);
		memcpy(&keysym.unicode, lpResultStr, sizeof(keysym.unicode));
		//printf("comp_str : %s, 0x%x\n", lpResultStr, keysym.unicode);

		if (startIMEComp)
		{
			startIMEComp = FALSE;
			keysym.mod |= KMOD_IME_COMP_START;
		}

		IME_PrivateKeyboard(SDL_PRESSED, &keysym);

		free(lpResultStr);
	}	

	ImmReleaseContext(hWnd, hIMC);
}




void Hangul_On(HWND hWnd)
{
	HIMC hIMC;
	DWORD dwConv, dwSent, dwTemp, dwErr;
	HWND hWnd2;

	hWnd2 = ImmGetDefaultIMEWnd(hWnd);

	SendMessage(hWnd2, WM_IME_CONTROL, IMC_OPENSTATUSWINDOW, 0L);



	hIMC = ImmCreateContext();
	ImmAssociateContext(hWnd, hIMC);

	hIMC = ImmGetContext(hWnd);
	dwErr = GetLastError();
	ImmGetConversionStatus(hIMC, &dwConv, &dwSent);

	if ((dwConv & IME_CMODE_NATIVE))
		return;

	dwTemp = dwConv & ~IME_CMODE_LANGUAGE;
	dwTemp |= IME_CMODE_NATIVE;
	dwConv = dwTemp;

	ImmSetConversionStatus(hIMC, dwConv, dwSent);
	ImmReleaseContext(hWnd, hIMC);
}


BOOL IsHangulMode(HWND gHwnd)
{
	HIMC hIME;
	DWORD dwConversion, dwSentence;

	BOOL bResult;

	hIME = ImmGetContext(gHwnd);

	if(hIME) 
	{
		ImmGetConversionStatus(hIME,&dwConversion,&dwSentence);
		switch (dwConversion) 
		{ 
		case IME_CMODE_FULLSHAPE :        //영문전각모드
		case IME_CMODE_ALPHANUMERIC :    //영문입력모드
			bResult = FALSE;
			break;

		case IME_CMODE_HANGUL :        //한글
			bResult = TRUE;
			break;
		}
		ImmReleaseContext(gHwnd,hIME); 
	} 

	return bResult;
}