/*	TransChar.cpp
 *
 *		Translate characters from one OS to another. This only affects
 *	high 8 bit characters
 */

/**********************************************************************

  YAAF is Copyright 1997-1999 by William Woody.

  Redistribution and use in source and binary forms, with or without 
  modification, are permitted provided that the following conditions 
  are met:

  Redistributions of source code must retain the above copyright notice, 
  this list of conditions and the following disclaimer.

  Neither the name of the copyright holder or other contributors may
  be used to promote products derived from this software without
  specific written prior permission.

  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 
  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 
  ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 
  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
  SOFTWARE.
  
  Contact:   woody@alumni.caltech.edu
  Web page:  http://www.pandawave.com/yaaf/

**********************************************************************/

#include <XConfig.h>
#include <string.h>
#include <XMisc.h>

/************************************************************************/
/*																		*/
/*	Tables																*/
/*																		*/
/************************************************************************/

/*	GTransTable
 *
 *		Macintosh to Windows character translation table
 */

static unsigned char GTransTable[128] = {
	0xC4, 0xC5, 0xC7, 0xC9, 0xD1, 0xD6, 0xDC, 0xE1,	// 0x80
	0xE0, 0xE2, 0xE4, 0xE3, 0xE5, 0xE7, 0xE9, 0xE8, // 0x88
	0xEA, 0xEB, 0xED, 0xEC, 0xEE, 0xEF, 0xF1, 0xF3, // 0x90
	0xF2, 0xF4, 0xF6, 0xF5, 0xFA, 0xF9, 0xFB, 0xFC, // 0x98
	0x86, 0xB0, 0xA2, 0xA3, 0xA7, 0x95, 0xB6, 0xDF, // 0xA0
	0xAE, 0xA9, 0x99, 0xB4, 0xA8, 0x00, 0xC6, 0xD8, // 0xA8
	0x00, 0xB1, 0x00, 0x00, 0xA5, 0xB5, 0x00, 0x00, // 0xB0
	0x00, 0x00, 0x00, 0xAA, 0xBA, 0x00, 0xE6, 0xF8, // 0xB8
	0xBF, 0xA1, 0xAC, 0x00, 0x83, 0x00, 0x00, 0xAB, // 0xC0
	0xBB, 0x85, 0x00, 0xC0, 0xC3, 0xD5, 0x8C, 0x9C, // 0xC8
	0x96, 0x97, 0x93, 0x94, 0x92, 0x91, 0xF7, 0x00, // 0xD0
	0xFF, 0x9F, 0x2F, 0xA4, 0x8B, 0x9B, 0x00, 0x00, // 0xD8
	0x87, 0xB7, 0x82, 0x84, 0x89, 0xC2, 0xCA, 0xC1, // 0xE0
	0xCB, 0xC8, 0xCD, 0xCE, 0xCF, 0xCC, 0xD3, 0xD4, // 0xE8
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF0
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // 0xF8
};

/*	GTransInvert
 *
 *		Invert translation table. This is built dynamically if it's
 *	not currently initialized
 */

static bool GTransInit;
static unsigned char GTransInvert[128];

/************************************************************************/
/*																		*/
/*	Timer Routines														*/
/*																		*/
/************************************************************************/

/*	BuildInvertTable
 *
 *		Build the inversion table on the fly. This is used internally
 *	by XGTransChar
 */

static void BuildInvertTable(void)
{
	int i,j;
	
	if (GTransInit) return;
	
	for (i = 0; i < 128; i++) {
		j = GTransTable[i];
		if (j >= 0x80) {
			GTransInvert[j - 0x80] = i + 0x80;
		}
	}
}


/*$	XGTransChar
 *
 *		Character translation service for high 8 bit characters. This
 *	is useful when sending text with the high 8 bit characters set
 *	for international characters. This is a kludge, by the way, and
 *	richly deserves to be rewritten.
 */

char *XGTransChar(XGOSType src, XGOSType dest, char *ptr, long len)
{
	long off;
	unsigned char c;
	
	/*
	 *	Translate 'native' symbol
	 */
	
	if (src == KXGNative) {
#if OPT_MACOS
		src = KXGMacintosh;
#endif

#if OPT_WINOS
		src = KXGWindows;
#endif

#if OPT_XWIN
		src = KXGUnix;
#endif
	}
	if (dest == KXGNative) {
#if OPT_MACOS
		dest = KXGMacintosh;
#endif

#if OPT_WINOS
		dest = KXGWindows;
#endif

#if OPT_XWIN
		dest = KXGUnix;
#endif
	}
	
	/*
	 *	### Kludge alert!
	 */
	
	if (src == KXGUnix) src = KXGWindows;
	if (dest == KXGUnix) dest = KXGWindows;
	
	/*
	 *	Source and destination same
	 */
	 
	if (src == dest) return ptr;
	
	/*
	 *	Mac -> Windows
	 */
	
	if (len == -1) len = strlen(ptr);
	if ((src == KXGMacintosh) && (dest == KXGWindows)) {
		for (off = 0; off < len; off++) {
			c = (unsigned char)(ptr[off]);
			
			if (c & 0x80) {
				c = GTransTable[c & 0x7F];
				if (c) ptr[off] = (char)c;
			}
		}
	} else if ((src == KXGWindows) && (dest == KXGMacintosh)) {
		BuildInvertTable();
		for (off = 0; off < len; off++) {
			c = (unsigned char)(ptr[off]);
			
			if (c & 0x80) {
				c = GTransInvert[c & 0x7F];
				if (c) ptr[off] = (char)c;
			}
		}
	}
	
	/*
	 *	Done.
	 */
	
	return ptr;
}
