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

#include <z_ctype.hpp>
#include <z_stdlib.hpp>
#include <z_store.hpp>
#include <z_string.hpp>
#include <z_utils.hpp>

ZafIChar *ZafCrNlToCr(ZafIChar *src, ZafIChar *dst)
{
	// Check for a valid source and destination buffer.
	if (!src)
		return (ZAF_NULLP(ZafIChar));
	else if (!dst)
		dst = src;

	// Convert the buffer.
	ZafIChar *tsrc = src;
	ZafIChar *tdst = dst;
	while (*tsrc)
	{
		if (tsrc[0] == '\r' && tsrc[1] == '\n')
		{
			*tdst++ = *tsrc++;
			tsrc++;
		}
		else
			*tdst++ = *tsrc++;
	}
	*tdst = '\0';

	// Return the results.
	return (dst);
}

#if defined(ZAF_UNICODE)
char *ZafCrNlToCr(char *src, char *dst)
{
	// Check for a valid source and destination buffer.
	if (!src)
		return (ZAF_NULLP(char));
	else if (!dst)
		dst = src;

	// Convert the buffer.
	char *tsrc = src;
	char *tdst = dst;
	while (*tsrc)
	{
		if (tsrc[0] == '\r' && tsrc[1] == '\n')
		{
			*tdst++ = *tsrc++;
			tsrc++;
		}
		else
			*tdst++ = *tsrc++;
	}
	*tdst = '\0';

	// Return the results.
	return (dst);
}
#endif

ZafIChar *ZafCrNlToNl(ZafIChar *src, ZafIChar *dst)
{
	// Check for a valid source and destination buffer.
	if (!src)
		return (ZAF_NULLP(ZafIChar));
	else if (!dst)
		dst = src;

	// Convert the buffer.
	ZafIChar *tsrc = src;
	ZafIChar *tdst = dst;
	while (*tsrc)
	{
		if (tsrc[0] == '\r' && tsrc[1] == '\n')
			tsrc++;
		else
			*tdst++ = *tsrc++;
	}
	*tdst = '\0';

	// Return the results.
	return (dst);
}

#if defined(ZAF_UNICODE)
char *ZafCrNlToNl(char *src, char *dst)
{
	// Check for a valid source and destination buffer.
	if (!src)
		return (ZAF_NULLP(char));
	else if (!dst)
		dst = src;

	// Convert the buffer.
	char *tsrc = src;
	char *tdst = dst;
	while (*tsrc)
	{
		if (tsrc[0] == '\r' && tsrc[1] == '\n')
			tsrc++;
		else
			*tdst++ = *tsrc++;
	}
	*tdst = '\0';

	// Return the results.
	return (dst);
}
#endif

ZafIChar *ZafCrToCrNl(ZafIChar *src, ZafIChar *dst)
{
	// Check for a valid source and destination buffer.
	if (!src)
		return (ZAF_NULLP(ZafIChar));
	else if (!dst)
		dst = src;

	// Convert the buffer.
	bool addNl;
	ZafIChar *tsrc = src;
	ZafIChar *tdst = dst;
	while (*tsrc)
	{
		// Check for shifting requirements.
		addNl = false;
		if (tsrc[0] == '\r' && tsrc[1] == '\n')
			*tdst++ = *tsrc++;
		else if (tsrc[0] == '\r')
		{
			if (src == dst)
			{
				// Shift the buffer.
				ZafIChar *tmp = tsrc + 1;
				ZafIChar value1 = '\n';
				while (*tmp)
				{
					ZafIChar value2 = *tmp;
					*tmp++ = value1;
					value1 = value2;
				}
				*tmp++ = value1;
				*tmp = '\0';
				*tdst++ = *tsrc++;
			}
			else
				addNl = true;
		}
		// Assign the buffer value.
		*tdst++ = *tsrc++;
		if (addNl)
			*tdst++ = '\n';
	}
	*tdst = '\0';

	// Return the results.
	return (dst);
}

#if defined(ZAF_UNICODE)
char *ZafCrToCrNl(char *src, char *dst)
{
	// Check for a valid source and destination buffer.
	if (!src)
		return (ZAF_NULLP(char));
	else if (!dst)
		dst = src;

	// Convert the buffer.
	bool addNl;
	char *tsrc = src;
	char *tdst = dst;
	while (*tsrc)
	{
		// Check for shifting requirements.
		addNl = false;
		if (tsrc[0] == '\r' && tsrc[1] == '\n')
			*tdst++ = *tsrc++;
		else if (tsrc[0] == '\r')
		{
			if (src == dst)
			{
				// Shift the buffer.
				char *tmp = tsrc + 1;
				char value1 = '\n';
				while (*tmp)
				{
					char value2 = *tmp;
					*tmp++ = value1;
					value1 = value2;
				}
				*tmp++ = value1;
				*tmp = '\0';
				*tdst++ = *tsrc++;
			}
			else
				addNl = true;
		}
		// Assign the buffer value.
		*tdst++ = *tsrc++;
		if (addNl)
			*tdst++ = '\n';
	}
	*tdst = '\0';

	// Return the results.
	return (dst);
}
#endif

ZafIChar *ZafNlToCrNl(ZafIChar *src, ZafIChar *dst)
{
	// Check for a valid source and destination buffer.
	if (!src)
		return (ZAF_NULLP(ZafIChar));
	else if (!dst)
		dst = src;

	// Convert the buffer.
	ZafIChar *tsrc = src;
	ZafIChar *tdst = dst;
	while (*tsrc)
	{
		// Check for shifting requirements.
		if (tsrc[0] == '\r' && tsrc[1] == '\n')
			*tdst++ = *tsrc++;
		else if (tsrc[0] == '\n')
		{
			if (src == dst)
			{
				// Shift the buffer.
				ZafIChar value1 = '\n';
				ZafIChar *tmp = tsrc;
				*tmp++ = '\r';
				while (*tmp)
				{
					ZafIChar value2 = *tmp;
					*tmp++ = value1;
					value1 = value2;
				}
				*tmp++ = value1;
				*tmp = '\0';
				*tdst++ = *tsrc++;
			}
			else
				*tdst++ = '\r';
		}
		// Assign the buffer value.
		*tdst++ = *tsrc++;
	}
	*tdst = '\0';

	// Return the results.
	return (dst);
}

#if defined(ZAF_UNICODE)
char *ZafNlToCrNl(char *src, char *dst)
{
	// Check for a valid source and destination buffer.
	if (!src)
		return (ZAF_NULLP(char));
	else if (!dst)
		dst = src;

	// Convert the buffer.
	char *tsrc = src;
	char *tdst = dst;
	while (*tsrc)
	{
		// Check for shifting requirements.
		if (tsrc[0] == '\r' && tsrc[1] == '\n')
			*tdst++ = *tsrc++;
		else if (tsrc[0] == '\n')
		{
			if (src == dst)
			{
				// Shift the buffer.
				char value1 = '\n';
				char *tmp = tsrc;
				*tmp++ = '\r';
				while (*tmp)
				{
					char value2 = *tmp;
					*tmp++ = value1;
					value1 = value2;
				}
				*tmp++ = value1;
				*tmp = '\0';
				*tdst++ = *tsrc++;
			}
			else
				*tdst++ = '\r';
		}
		// Assign the buffer value.
		*tdst++ = *tsrc++;
	}
	*tdst = '\0';

	// Return the results.
	return (dst);
}
#endif

/* START BLOCK COMMENT
**	ZafIChar *ZafStrdup(const ZafIChar *srcString)
**	{
**		// Make sure there is a valid string to duplicate.
**		if (!srcString)
**			return (ZAF_NULLP(ZafIChar));
**	
**		// Create the data space and copy the string.
**		ZafIChar *destString = new ZafIChar[strlen(srcString) + 1];
**		strcpy(destString, srcString);
**	
**		// Return the string pointer.
**		return (destString);
**	}
**	
**	int ZafStricmp(const ZafIChar *a, const ZafIChar *b)
**	{
**		ZafIChar la, lb;
**		for (;;)
**		{
**			la = *a; lb = *b;
**			if (isupper(la))
**				la = tolower(la);
**			if (isupper(lb))
**				lb = tolower(lb);
**			if (la != lb || !la)
**				break;
**			a++; b++;
**		}
**		return (la - lb);
**	}
END BLOCK COMMENT */

/* START BLOCK COMMENT
**	ZafIChar *ZafStrlwr(ZafIChar *a)
**	{
**		ZafIChar *b = a;
**		while (*a)
**		{
**			if (IsUpper(*a))
**				*a = ToLower(*a);
**			a++;
**		}
**		return (b);
**	}
END BLOCK COMMENT */

ZafIChar *ZafStrupr(ZafIChar *a)
{
	ZafIChar *b = a;
	while (*a)
	{
		if (IsLower(*a))
			*a = ToUpper(*a);
		a++;
	}
	return (b);
}

void itoa(ZafInt32 value, ZafIChar *string, int radix, int pad)
{
	static ZafIChar ZAF_FARDATA _digits[] =
	{
		'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
		'a', 'b', 'c', 'd', 'e', 'f'
	};

	ZafUInt32 tmpValue;
	if (value < 0 && radix == 10)
	{
		*string++ = '-';
		tmpValue = (ZafUInt32)-value;
	}
	else
		tmpValue = (ZafUInt32)value;
	ZafIChar tmpBuf[64];
	int i = 0;
	while (tmpValue || i == 0)
	{
		ZafUInt16 digit = (ZafUInt16)(tmpValue % radix);
		tmpBuf[i] = _digits[digit];
		i++;
		tmpValue = (ZafUInt32)(tmpValue / radix);
		pad--;
	}
	while (pad > 0)
	{
		tmpBuf[i] = (value < 0 ? _digits[radix] : _digits[0]);
		i++;
		pad--;
	}
	do
	{
		i--;
		*string++ = tmpBuf[i];
	} while (i > 0);
	*string = 0;
}

int streq(const ZafIChar *s1, const ZafIChar *s2)
{
	if (s1 == s2)
		return (0);
	else if (!s1 && s2)
		return -s2[0];
	else if (s1 && !s2)
		return s1[0];
	int i = 0;
	for (; s1[i] && s2[i] && s1[i] == s2[i]; i++)
		;
	return ((int)s1[i] - (int)s2[i]);
}

#if defined(ZAF_UNICODE)
int streq(const ZafIChar *s1, const char *s2)
{
	if (!s1 && s2)
		return -s2[0];
	else if (s1 && !s2)
		return s1[0];
	int i = 0;
	for (; s1[i] && s2[i] && (char)s1[i] == s2[i]; i++)
		;
	return ((int)s1[i] - (int)s2[i]);
}

int streq(const char *s1, const char *s2)
{
	if (s1 == s2)
		return 0;
	else if (!s1 && s2)
		return -s2[0];
	else if (s1 && !s2)
		return s1[0];
	int i = 0;
	for (; s1[i] && s2[i] && s1[i] == s2[i]; i++)
		;
	return ((int)s1[i] - (int)s2[i]);
}
#endif

int strneq(const ZafIChar *s1, const ZafIChar *s2, int n)
{
	int i = 0;
	for (; n && s1[i] && s2[i] && s1[i] == s2[i]; i++, n--)
		;
	return (n ? (int)s1[i] - (int)s2[i] : 0);
}

int strnicmp(const ZafIChar *a, const ZafIChar *b, int n)
{
	ZafIChar la, lb;

	for (;;)
	{
		la = *a; lb = *b;
		if (isupper(la))
			la = tolower(la);
		if (isupper(lb))
			lb = tolower(lb);
		if (la != lb || !la || !n)
			break;
		a++; b++; n--;
	}
	if (n)
		return (la - lb);
	return (0);
}

void strrepc(ZafIChar *string, ZafIChar c, ZafIChar repc)
{
	if (!string)
		return;

	// Replace a character (c) in a string to a new character (repc).
	while (*string)
	{
		if (*string == c)
			*string = repc;
		string++;
	}
}

void strstrip(ZafIChar *string, ZafIChar c)
{
	if (!string)
		return;

	// strip all occurances of c out of string
	ZafIChar *src = string;
	ZafIChar *dest = string;
	do
	{
		while (*src == c)
			src++;
	} while ((*dest++ = *src++) != 0);
}

int WildStrcmp(const ZafIChar *str, const ZafIChar *pattern)
{
	for ( ;  *str && (*str == *pattern || *pattern == '?' || *pattern == '*');
		str++, pattern++)
		if (*pattern == '*')
		{
			// Compress multiple astrisks, eg: "**".
			while (*++pattern == '*')
				;	// Update pattern count.
			if (!*pattern)
				return (0);		// pattern ended in *.
			const ZafIChar *nextTest = str;
			do
			{
				nextTest = strchr(nextTest, *pattern);
				if (!nextTest)
				{
					pattern--;
					break;
				}
				if (!WildStrcmp(nextTest, pattern))
				{
					str = nextTest;
					break;
				}
				nextTest++;
			} while (nextTest);
		}
	while (*pattern == '*')
		pattern++;
	return (*str - *pattern);
}


