//	Zinc Application Framework - Z_CSET.HPP
//	COPYRIGHT (C) 1990-1999.  All Rights Reserved.
//	Zinc Software Incorporated.  Pleasant Grove, Utah  USA

#if !defined(Z_CSET_HPP)
#define Z_CSET_HPP
#include <z_idata.hpp>

// --------------------------------------------------------------------------
// ----- ZafCodeSetData -----------------------------------------------------
// --------------------------------------------------------------------------

#if defined(mblen) && defined(ZAF_UNICODE)
#	undef mblen
#endif

class ZAF_EXPORT ZafCodeSetDataStub : public ZafI18nData
{
public:
	// --- General members ---
	ZafIChar dirSepStr[2];

	ZafCodeSetDataStub(void);
	ZafCodeSetDataStub(const ZafCodeSetDataStub &copy);
#if defined(USE_ZAF_PERSISTENCE)
	ZafCodeSetDataStub(const ZafIChar *name, ZafDataPersistence &persist);
#endif

	virtual ~ZafCodeSetDataStub(void);
	virtual int ConvertToOSChar(ZafIChar zafChar, char *osChar) = 0;
	virtual char *ConvertToOSString(const ZafIChar *zafString,
		char *osString = ZAF_NULLP(char), bool allocate = true) = 0;
	virtual int ConvertToZafChar(const char *osChar, ZafIChar &zafChar) = 0;
	virtual ZafIChar *ConvertToZafString(const char *osString,
		ZafIChar *zafString = ZAF_NULLP(ZafIChar), bool allocate = true) = 0;

	// --- Special UNICODE functions ---
#if defined(ZAF_UNICODE)
	virtual int ConvertToOSWChar(ZafIChar zafChar, wchar_t *osChar) = 0;
	virtual wchar_t *ConvertToOSWString(const ZafIChar *zafString,
		wchar_t *osString = ZAF_NULLP(wchar_t), bool allocate = true) = 0;
	virtual int ConvertToZafChar(const wchar_t *osChar, ZafIChar &zafChar) = 0;
	virtual ZafIChar *ConvertToZafString(const wchar_t *osString,
		ZafIChar *zafString = ZAF_NULLP(ZafIChar), bool allocate = true) = 0;
	virtual ZafIChar *IsoToUnicode(const char *isoText,
		ZafIChar *unicodeText = ZAF_NULLP(ZafIChar)) = 0;
	virtual char *UnicodeToIso(const ZafIChar *unicodeText,
		char *isoText = ZAF_NULLP(char)) = 0;

	virtual int mblen(const char *hardware) = 0;
	virtual int wcstombs(char *s, const ZafIChar *pwcs, int n = -1) = 0;
	virtual int mbstowcs(ZafIChar *pwcs, const char *s, int n = -1) = 0;
#endif

	// --- Attributes & data access ---
	// get
	static const ZafIChar *CodeSetName(void);

	virtual ZafUInt8 DefaultLeadByte(void) const = 0;
	// set
	virtual void Clear(void) = 0;
	virtual ZafUInt8 SetDefaultLeadByte(ZafUInt8 defaultLeadByte) = 0;
	static ZafError SetCodeSetName(const ZafIChar *codeSetName);

	// --- Default charmap ---
	static void CodeSetAllocate(const ZafIChar *name = ZAF_NULLP(ZafIChar));
	static void CodeSetFree(bool globalRequest = false);

	// --- Class identification ---
//???	static ZafClassID classID;
//???	static ZafClassNameChar ZAF_FARDATA className[];
//	virtual ZafClassID ClassID(void) const { return (classID); }
//	virtual ZafClassName ClassName(void) const { return (className); }
//	virtual bool IsA(ZafClassID compareID) const;
//	virtual bool IsA(ZafClassName compareName) const;

#if defined(ZAF_UNICODE)
	virtual bool SetNativeMapping(bool mapping) = 0;
	virtual bool NativeMapping(void) const = 0;
	static bool OSNativeMapping(void);
#endif
	virtual void InitializeDirSepStr(void) = 0;
};

extern ZAF_EXPORT ZafCodeSetDataStub *zafCodeSet;

inline const ZafIChar *ZafCodeSetDataStub::CodeSetName(void) { return (zafCodeSet ? zafCodeSet->StringID() : ZAF_NULLP(ZafIChar)); }

char *ZafConvertToOSString(const ZafIChar *zafString,
	char *osString = ZAF_NULLP(char), bool allocate = true);
ZafIChar *ZafConvertToZafString(const char *osString,
	ZafIChar *zafString = ZAF_NULLP(ZafIChar), bool allocate = true);
ZafIChar *ZafOSDirSepStr(void);
#if defined(ZAF_UNICODE)
wchar_t *ZafConvertToOSWString(const ZafIChar *zafString,
	wchar_t *osString = ZAF_NULLP(wchar_t), bool allocate = true);
ZafIChar *ZafConvertToZafString(const wchar_t *osString,
	ZafIChar *zafString = ZAF_NULLP(ZafIChar), bool allocate = true);

#endif

class ZAF_EXPORT ZafCharLookup;
class ZAF_EXPORT ZafWcharLookup;
class ZAF_EXPORT ZafCodeSetData : public ZafCodeSetDataStub
{
public:
	// --- General members ---
//	ZafIChar dirSepStr[2];

	ZafCodeSetData(ZafIChar *isoToLocal, ZafIChar *localToIso);
	ZafCodeSetData(const ZafCodeSetData &copy);
	virtual ~ZafCodeSetData(void);
	int ConvertToOSChar(ZafIChar zafChar, char *osChar);
	char *ConvertToOSString(const ZafIChar *zafString, char *osString = ZAF_NULLP(char), bool allocate = true);
	int ConvertToZafChar(const char *osChar, ZafIChar &zafChar);
	ZafIChar *ConvertToZafString(const char *osString, ZafIChar *zafString = ZAF_NULLP(ZafIChar), bool allocate = true);

	// --- Special UNICODE functions ---
#if defined(ZAF_UNICODE)
	int ConvertToOSWChar(ZafIChar zafChar, wchar_t *osChar);
	wchar_t *ConvertToOSWString(const ZafIChar *zafString, wchar_t *osString = ZAF_NULLP(wchar_t), bool allocate = true);
	int ConvertToZafChar(const wchar_t *osChar, ZafIChar &zafChar);
	ZafIChar *ConvertToZafString(const wchar_t *osString, ZafIChar *zafString = ZAF_NULLP(ZafIChar), bool allocate = true);
	ZafIChar *IsoToUnicode(const char *isoText, ZafIChar *unicodeText = ZAF_NULLP(ZafIChar));
	char *UnicodeToIso(const ZafIChar *unicodeText, char *isoText = ZAF_NULLP(char));

	int mblen(const char *hardware);
	int wcstombs(char *s, const ZafIChar *pwcs, int n = -1);
	int mbstowcs(ZafIChar *pwcs, const char *s, int n = -1);
#endif

#if defined(USE_ZAF_PERSISTENCE)
	// --- Persistent members ---
	ZafCodeSetData(const ZafIChar *name, ZafDataPersistence &persist);
	static ZafElement *Read(const ZafIChar *name, ZafDataPersistence &persist);
	virtual void Write(ZafDataPersistence &persist);
#endif

	virtual ZafData *Duplicate(void);

	// --- Attributes & data access ---
	// get
	static const ZafIChar *CodeSetName(void);
	ZafUInt8 DefaultLeadByte(void) const;
	// set
	virtual void Clear(void);
	ZafUInt8 SetDefaultLeadByte(ZafUInt8 defaultLeadByte);
	static ZafError SetCodeSetName(const ZafIChar *codeSetName);

	// --- Default charmap ---
	static void CodeSetAllocate(const ZafIChar *name = ZAF_NULLP(ZafIChar));
	static void CodeSetFree(bool globalRequest = false);

	// --- Class identification ---
	static ZafClassID classID;
	static ZafClassNameChar ZAF_FARDATA className[];
	virtual ZafClassID ClassID(void) const;// { return (classID); }
	virtual ZafClassName ClassName(void) const;// { return (className); }
	virtual bool IsA(ZafClassID compareID) const;
	virtual bool IsA(ZafClassName compareName) const;

#if defined(ZAF_UNICODE)
	bool SetNativeMapping(bool mapping) { nativeMapping = mapping; return (nativeMapping); }
	bool NativeMapping(void) const { return (nativeMapping); }
#endif

protected:
	// --- Persistence ---
#if defined(USE_ZAF_PERSISTENCE)
	virtual ZafDataConstructor ReadFunction(void) { return (ZafCodeSetData::Read); }
#endif
	void InitializeDirSepStr(void);

#if defined(ZAF_UNICODE)
	bool nativeMapping;
#endif

private:
	ZafUInt8 defaultLeadByte;
	ZafCharLookup *isoToLocal;
	ZafCharLookup *localToIso;
#	if defined(ZAF_UNICODE)
	ZafWcharLookup *unicodeToLocal;
	ZafWcharLookup *localToUnicode;

	static int OSConvertToOSChar(ZafIChar zafChar, char *osChar);
	static char *OSConvertToOSString(const ZafIChar *zafString, char *osString, int maxLength);
	static int OSConvertToZafChar(const char *osChar, ZafIChar &zafChar);
	static ZafIChar *OSConvertToZafString(const char *osString, ZafIChar *zafString, int maxLength);
#	endif

};

// --- inline functions ---
//inline const ZafIChar *ZafCodeSetData::CodeSetName(void) { return (zafCodeSet ? zafCodeSet->StringID() : ZAF_NULLP(ZafIChar)); }
//inline ZafUInt8 ZafCodeSetData::DefaultLeadByte(void) const { return (defaultLeadByte); }

#endif // Z_CSET_HPP

