// 
// This file is part of miniChinput-0.0.4.
//
// miniChinput and this file, are released under GPL
//
// Author : Jacky Lau <zenithlau@sniic.com>
//

// This files mainly contains functions for encoding manipulations.

#include "enc.h"

#define		CHINPUT_ENC_LOCALE_MAX_LEN		32

// Encoding value is defined in header. Invalid in_locale will return -1
int
chinput_enc_get_encoding (const char* in_locale)
{
	// If locale is in the form xx_xx.xx
	//   return encoding depends on the tailing .xx
	// otherwise
	//   return encoding depends on xx_xx with a one to one mapping

	char	enc_str[CHINPUT_ENC_LOCALE_MAX_LEN + 1] = {'\0'};
	char	*c_ptr = enc_str;

	if (in_locale == NULL || strlen (in_locale) == 0)
		return -1;

	strncpy (enc_str, in_locale, CHINPUT_ENC_LOCALE_MAX_LEN + 1);
	enc_str [CHINPUT_ENC_LOCALE_MAX_LEN] = '\0';

	if (strchr (c_ptr, '.'))
	{
		c_ptr ++;

		if (strcasecmp (c_ptr, "big5") == 0)
			return HZSERVER_ENCODING_BIG5;

		else if (strcasecmp (c_ptr, "big5hkscs") == 0)
			return HZSERVER_ENCODING_BIG5HKSCS;

		else if (strcasecmp (c_ptr, "gb2312") == 0)
			return HZSERVER_ENCODING_GB2312;

		else if (strcasecmp (c_ptr, "gb18030") == 0)
			return HZSERVER_ENCODING_GB18030;

		else
			return HZSERVER_ENCODING_BIG5;
	}
	else
	{
		if (strcasecmp (c_ptr, "zh_tw") == 0)
			return HZSERVER_ENCODING_BIG5;

		else if (strcasecmp (c_ptr, "zh_hk") == 0)
			return HZSERVER_ENCODING_BIG5HKSCS;

		else if (strcasecmp (c_ptr, "zh_cn") == 0)
			return HZSERVER_ENCODING_GB2312;

		else if (strcasecmp (c_ptr, "zh") == 0)
			return HZSERVER_ENCODING_BIG5;

		else
			return -1;
	}
}

// Return a locale string as "out_locale" depends on "enc".
// Return -1 if "enc" is invalid
int
chinput_enc_get_locale (char *out_locale, int enc)
{
	switch (enc)
	{
		case HZSERVER_ENCODING_BIG5:
			strcpy (out_locale, HZSERVER_BIG5_LOCALE);
			return 0;
		case HZSERVER_ENCODING_BIG5HKSCS:
			strcpy (out_locale, HZSERVER_BIG5HKSCS_LOCALE);
			return 0;
		case HZSERVER_ENCODING_GB2312:
			strcpy (out_locale, HZSERVER_GB2312_LOCALE);
			return 0;
		case HZSERVER_ENCODING_GB18030:
			strcpy (out_locale, HZSERVER_GB18030_LOCALE);
			return 0;
		default:
			return -1;
	}
}

// Set locale, which is depends on enc. Return original locale as "orig_locale"
// Return -1 if "enc" is invalid, -2 if "setlocale ()" error, or 0 if success 
int
chinput_enc_set_locale (char *orig_locale, int enc)
{
	// Set locale by enc, using one-to-one mapping
	// If enc is invalid, return -1
	// If setlocale () error, return -2
	// If success, orig_locale will be the original locale. return 0

	char new_locale [CHINPUT_ENC_LOCALE_MAX_LEN];

	if (chinput_enc_get_locale (new_locale, enc) == -1)
		return -1;

	strncpy (orig_locale, setlocale (LC_CTYPE, NULL),
			CHINPUT_ENC_LOCALE_MAX_LEN + 1);

	return (setlocale (LC_CTYPE, new_locale)) ? 0 : -2;
}

// Set "out_imname" as system default IM name depends on given "enc"
// Return -1 if invalid "enc"
int
chinput_enc_get_def_im (char *out_imname, int enc)
{
	switch (enc)
	{
		case HZSERVER_ENCODING_BIG5:
			strcpy (out_imname, HZSERVER_DEFAULT_BIG5_IME);
			return 0;
		case HZSERVER_ENCODING_BIG5HKSCS:
			strcpy (out_imname, HZSERVER_DEFAULT_BIG5HKSCS_IME);
			return 0;
		case HZSERVER_ENCODING_GB2312:
			strcpy (out_imname, HZSERVER_DEFAULT_GB2312_IME);
			return 0;
		case HZSERVER_ENCODING_GB18030:
			strcpy (out_imname, HZSERVER_DEFAULT_GB18030_IME);
			return 0;
		default:
			return -1;
	}
}

// Set approporiate IM Server Status String to 'out_status', depends on 
// 'flag_2byte, 'flag_punct', and 'enc'
// Return '-1' if invalid 'enc'
int
chinput_enc_get_status_str (char *out_status, int flag_2byte,
		int flag_punct, int enc)
{
	if (enc == HZSERVER_ENCODING_BIG5
			|| enc == HZSERVER_ENCODING_BIG5HKSCS)
	{
		if (flag_2byte)
			strcat (out_status, "¡i¥þ");
		else
			strcat (out_status, "¡i¥b");

		if (flag_punct)
			strcat (out_status, "¢÷¡j");
		else
			strcat (out_status, "¡O¡j");
	}
	else if (enc == HZSERVER_ENCODING_GB2312
			|| enc == HZSERVER_ENCODING_GB18030)
	{
		if (flag_2byte)
			strcat (out_status, "¡¾È«");
		else
			strcat (out_status, "¡¾°ë");

		if (flag_punct)
			strcat (out_status, "£ï¡¿");
		else
			strcat (out_status, " .¡¿");
	}
	else
		return -1;

	return 0;
}
