
// EncodingSupport.X.h for VectorWorks
//
// Copyright © Diehl Graphsoft, Inc. 1999.
// All Rights Reserved.
//
// Cross-Platform Japanese Shift-JIS & other encoding support.
//
// Last SourceSafe check-in:
//		$Revision: 1 $
//		$Date: 6/06/00 6:08p $
//		$Author: Dave $
//
// Started 11/19/99 by Paul C. Pharr


#ifndef _ENCODINGSUPPORT_X_H_
#define _ENCODINGSUPPORT_X_H_ 1

#pragma once

#if _WINDOWS
#include <MBCType.h>
#include <MBString.h>
#endif

enum ECharacterType {
	eSingle,
	eLead,
	eTrail
};


enum EScriptType {
	eUseSystemScript,
	eUseCurrentFontScript
};

inline ECharacterType GetSJISCharacterType(const unsigned char* text, long offset, EScriptType script = eUseSystemScript)
{
	#if _WINDOWS
	
	// this is unused on Windows - will go away in VW12 - PCP
	script;

	// this code looks ugly, but it is doing the very same thing the Mac code below is doing -- namely
	// it starts from the beginning of the string assuming the string does not start with a trailing half
	// of a double byte character. It then traverses the string until it gets to the character in question
	// and at that point it knows what that character is.

	
	int lastType = 0; // set the last type to a single character so we will start traversing correctly	
	int thisType;
	const unsigned char *t = text;


	for (long i = 0; i <= offset; i++, t++) {
#if Chao
		ASSERTPOINTER(kChao, t, 1);	// make this #if Chao if it slows you down. This would have saved me from a 9.0.0 release crash. - JDW
#endif
		thisType = _mbbtype(*t, lastType );
		lastType = thisType;
	}

	switch(thisType) {
		case _MBC_SINGLE:		return eSingle;
		case _MBC_LEAD:			return eLead;
		case _MBC_TRAIL:		return eTrail;
		case _MBC_ILLEGAL: {
			// this happens for all control characters. We treat them as singles
			// DSTOP((kJim, "Illegal character encountered in GetSJISCharacterType! ch: 0x%2x  offset: %d", *text+offset, offset));
			return eSingle;
		}
		default:				return eSingle;
	}
	#else
	
	short scriptToUse = smCurrentScript;
	
	if (script == eUseSystemScript)
		scriptToUse = smSystemScript;
	
	switch(CharacterByteType((Ptr)text, offset, scriptToUse)) {
		case smSingleByte :		return eSingle;
		case smFirstByte:		return eLead;
		case smLastByte:		return eTrail;
		default:				return eSingle;
	}
	#endif
}




inline bool IsSJISLeadCharacter(const unsigned char* text, long offset, EScriptType script = eUseSystemScript)
{
	return (GetSJISCharacterType(text, offset, script) == eLead);
}



///////////////////////////////////////////////////////////////////////////////////////
inline void GetSJISCharacterTypeArray(const char *pStr, ECharacterType *pCharByteType, long strLength, EScriptType script = eUseSystemScript)
//
//	pCharByteType is an array of ECharacterType's that stores the character type
//  of each byte in the string.  
//
//	This function is used where potentially long strings are being handled and
//  we need speed.  This calculates the type of each character with one
//	iteration through the string.  Using the other function will result in something
//	approaching Big O(n^2).
//
///////////////////////////////////////////////////////////////////////////////////////
{
	if (pStr && pCharByteType && strLength > 0) {

		char *pLastNonTrailChar = (char*)pStr;
		long lastNonTrailCharIndex = 0;
		long i = 0;

		for (i = 0; i < strLength; i++) {

			//Get the byte type for this character
			pCharByteType[i] = GetSJISCharacterType((const unsigned char*) pLastNonTrailChar, lastNonTrailCharIndex, script);
			
#if BUG && Robert
			ECharacterType ct = GetSJISCharacterType((const unsigned char*) pStr, i, script);
			ASSERTN(kRobert, ct == pCharByteType[i]);
#endif
			
			if (pCharByteType[i] == eTrail) {
				//For trail characters we just need to increment the last
				//non trail character counter.
				lastNonTrailCharIndex ++;
			} else {
				//For non trail characters we can reset the pLastNonTrailChar pointer so we don't go
				//back over the characters we already processed.
				pLastNonTrailChar = (char*)pStr + i;

				//Be sure to set the index correctly also.
				lastNonTrailCharIndex = 1;
			}
		}

	}
}

#endif
