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

#if !defined(Z_STR_HPP)
#define Z_STR_HPP
#include <z_fdata.hpp>
#include <z_stdarg.hpp>
#include <z_string.hpp>

// --------------------------------------------------------------------------
// ----- ZafStringData ------------------------------------------------------
// --------------------------------------------------------------------------

#define ZAF_STRING_DATA_LENGTH		255

class ZAF_EXPORT ZafStringData : public ZafFormatData
{
public:
	// -- General members ---
	ZafStringData(bool staticData = false);
	ZafStringData(const ZafIChar *value, int maxLength = -1, bool staticData = false);
	ZafStringData(const ZafStringData &copy);
	virtual ~ZafStringData(void);

	// --- Persistence ---
	virtual ZafData *Duplicate(void);
#if defined(USE_ZAF_PERSISTENCE)
	ZafStringData(const ZafIChar *name, ZafDataPersistence &persist);
	static ZafElement *Read(const ZafIChar *name, ZafDataPersistence &persist);
	virtual void Write(ZafDataPersistence &persist);
#endif

	// --- Attributes & data access ---
	// get
	virtual int FormattedText(ZafIChar *buffer, int bufferSize, const ZafIChar *format = 0) const;
	ZafIChar Char(int offset) const;
	int Length(void) const;
	int MaxLength(void) const;
	bool StaticData(void) const;
	char *DynamicOSText(void) const;
	ZafIChar *DynamicText(void) const;
	const ZafIChar *Text(void) const;
	// set
	virtual ZafStringData &Append(const ZafIChar *text);
	virtual void Clear(void);
	virtual int Compare(const ZafIChar *text, bool caselessCompare = false) const;
	virtual ZafStringData &Insert(int offset, const ZafIChar *text, int length = -1);
	virtual ZafStringData &Remove(int offset, int size);
	virtual ZafStringData &Remove(const ZafIChar *text);
	virtual ZafStringData &Replace(int offset, int size, const ZafIChar *text, int length = -1);
	virtual bool SetStaticData(bool staticData);
	virtual ZafError SetChar(int offset, ZafIChar value, bool ignoreNotification = true);
	virtual int SetMaxLength(int maxLength);
	virtual ZafError SetOSText(const char *text);
	virtual ZafError SetText(const ZafIChar *text);
	virtual ZafError SetText(const ZafIChar *text, int maxLength);
	virtual ZafError SetText(const ZafStringData &string);
	virtual ZafError SetText(const ZafIChar *buffer, const ZafIChar *format);

	// --- Operators ---
	operator const ZafIChar *() const { return value; }

	ZafStringData &operator=(const ZafStringData &value);
	ZafStringData &operator=(const ZafIChar *value);
	ZafStringData &operator=(const ZafIChar value);
	ZafStringData &operator+=(const ZafIChar value);
	ZafStringData &operator+=(const ZafIChar *value);
	ZafStringData &operator+=(const ZafStringData &data);
	ZafStringData &operator-=(const ZafIChar *value);
	ZafStringData &operator-=(const ZafStringData &data);

	ZafIChar &operator[](int offset);
	ZafIChar operator[](int offset) const;

	// --- 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;

	// --- Unicode support ---
#	if defined(ZAF_UNICODE)
	ZafStringData(const char *value, int maxLength = -1, bool staticData = false);
	wchar_t *DynamicOSWText(void) const;
	ZafError SetOSWText(const wchar_t *text);
#	endif

protected:
#if defined(USE_ZAF_PERSISTENCE)
	// --- Persistence ---
	void ReadData(ZafDataPersistence &persist);
	virtual ZafDataConstructor ReadFunction(void) { return (ZafStringData::Read); }
	void WriteData(ZafDataPersistence &persist);
#endif

private:
	friend class ZAF_EXPORT ZafStandardArg;

	bool staticData;
	int bufferSize;
	int maxLength;
	ZafIChar *value;

	// printf support
	static void Bind(void);
	static void Format(va_list *argList, ZafIChar **ptrBuffer, ZafIChar fmtch, int flags, int width, int prec);
	static int Parse(va_list *argList, ZafIChar **ptrBuffer, ZafIChar fmtch, int flags, int width, const ZafIChar **fmt);
};

// --- inline functions ---
inline int ZafStringData::MaxLength(void) const { return maxLength; }
inline ZafIChar ZafStringData::Char(int offset) const { return (value[offset]); }
inline const ZafIChar *ZafStringData::Text(void) const { return value; }
inline bool ZafStringData::StaticData(void) const { return (staticData); }
inline ZafIChar &ZafStringData::operator[](int offset) { return (value[offset]); }
inline ZafIChar ZafStringData::operator[](int offset) const { return (value[offset]); }
inline ZafStringData &ZafStringData::operator+=(const ZafIChar *text) { Append(text); return (*this); }
inline ZafStringData &ZafStringData::operator+=(const ZafStringData &data) { Append(data.value); return (*this); }
inline ZafStringData &ZafStringData::operator-=(const ZafIChar *text) { Remove(text); return (*this); }
inline ZafStringData &ZafStringData::operator-=(const ZafStringData &data) { Remove(data.value); return (*this); }

// --- ZafStringData operators ---
ZAF_EXPORT ZafStringData operator+(const ZafStringData &string1, const ZafStringData &string2);
ZAF_EXPORT ZafStringData operator+(const ZafStringData &string, const ZafIChar *value);
ZAF_EXPORT ZafStringData operator+(const ZafIChar *value, const ZafStringData &string);
ZAF_EXPORT ZafStringData operator+(const ZafStringData &string, const ZafIChar value);
ZAF_EXPORT ZafStringData operator+(const ZafIChar value, const ZafStringData &string);

ZAF_EXPORT ZafStringData operator-(const ZafStringData &string1, const ZafStringData &string2);
ZAF_EXPORT ZafStringData operator-(const ZafStringData &string, const ZafIChar *value);
ZAF_EXPORT ZafStringData operator-(const ZafIChar *value, const ZafStringData &string);

inline bool operator==(const ZafStringData &string1, const ZafStringData &string2) { return (string1.Compare(string2) ? false : true); }
inline bool operator==(const ZafStringData &string, const ZafIChar *value) { return (string.Compare(value) ? false : true); }
inline bool operator==(const ZafIChar *value, const ZafStringData &string) { return (string.Compare(value) ? false : true); }

inline bool operator!=(const ZafStringData &string1, const ZafStringData &string2) { return (string1.Compare(string2) ? true : false); }
inline bool operator!=(const ZafStringData &string, const ZafIChar *value) { return (string.Compare(value) ? true : false); }
inline bool operator!=(const ZafIChar *value, const ZafStringData &string) { return (string.Compare(value) ? true : false); }

inline bool operator>(const ZafStringData &string1, const ZafStringData &string2) { return ((string1.Compare(string2) > 0) ? true : false); }
inline bool operator>(const ZafStringData &string, const ZafIChar *value) { return ((string.Compare(value) > 0) ? true : false); }
inline bool operator>(const ZafIChar *value, const ZafStringData &string) { return ((string.Compare(value) < 0) ? true : false); }

inline bool operator>=(const ZafStringData &string1, const ZafStringData &string2) { return ((string1.Compare(string2) >= 0) ? true : false); }
inline bool operator>=(const ZafStringData &string, const ZafIChar *value) { return ((string.Compare(value) >= 0) ? true : false); }
inline bool operator>=(const ZafIChar *value, const ZafStringData &string) { return ((string.Compare(value) <= 0) ? true : false); }

inline bool operator<(const ZafStringData &string1, const ZafStringData &string2) { return ((string1.Compare(string2) < 0) ? true : false); }
inline bool operator<(const ZafStringData &string, const ZafIChar *value) { return ((string.Compare(value) < 0) ? true : false); }
inline bool operator<(const ZafIChar *value, const ZafStringData &string) { return ((string.Compare(value) > 0) ? true : false); }

inline bool operator<=(const ZafStringData &string1, const ZafStringData &string2) { return ((string1.Compare(string2) <= 0) ? true : false); }
inline bool operator<=(const ZafStringData &string, const ZafIChar *value) { return ((string.Compare(value) <= 0) ? true : false); }
inline bool operator<=(const ZafIChar *value, const ZafStringData &string) { return ((string.Compare(value) >= 0) ? true : false); }

#endif // Z_STR_HPP
