#include "String.h"

//not optimized at all (
STRING String::ReplaceAll(STRING originalString, STRING subStringToReplace, STRING newValue)
{
	STRING entry = StrStr(originalString, subStringToReplace);
	if ( 0 == entry )
		//simply return copy of original
		return StrDup(originalString);
	
	//we have first entry 
	UINT leftSize = (UINT)entry - (UINT)originalString;
	UINT originalLength = StrLen(originalString);
	UINT subLength = StrLen(subStringToReplace);
	UINT newValueSize = StrLen(newValue);
	UINT rightSize = originalLength - leftSize - subLength;
	UINT resultSize = leftSize + rightSize + newValueSize;
	
	STRING result = (STRING) System::SafeAllocMemory(resultSize + 1); //+1 for null character
	System::MemCpy((BYTE*)result,(BYTE*)originalString,leftSize);
	System::MemCpy((BYTE*)(result + leftSize), (BYTE*)newValue, newValueSize);
	System::MemCpy((BYTE*)(result + leftSize + newValueSize),(BYTE*) (entry + subLength), rightSize);
	
	ReplaceAll(result, subStringToReplace, newValue);
	return result;
}

void String::StrCpy(STRING dest, STRING source)
{
#ifdef WINDOWS
	lstrcpyA(dest, source);
#else
	strcpy(dest, source);
#endif
}


UINT String::StrLen(STRING string)
{
#ifdef WINDOWS
	return lstrlenA(string);
#else
	return strlen(string);
#endif
}

void String::StrCat(STRING dest, STRING src)
{
#ifdef WINDOWS
	lstrcatA(dest,src);
#else
	strcat(dest,src);
#endif
}

void String::Sprintf1(STRING buffer, STRING format, int arg1)
{

#ifdef WINDOWS
	wsprintfA(buffer, format, arg1);
#else
	sprintf(buffer,format,arg1);
#endif
}

void String::Sprintf2(STRING buffer, STRING format, int arg1, int arg2)
{
#ifdef WINDOWS
	wsprintfA(buffer, format, arg1, arg2);
#else
	sprintf(buffer,format,arg1,arg2);
#endif
}


void String::StrNCpy(STRING dest, STRING source, UINT count)
{
#ifdef WINDOWS
	lstrcpynA( dest, source, count);
#else
	strncpy(dest, source, count);
#endif
}

STRING String::StrDup(STRING str)
{
	STRING result = (STRING)System::SafeAllocMemory(StrLen(str) + 1);
	StrCpy(result, str);
	return result;
}

STRING String::StrStr(STRING str1, STRING str2)
{
	UINT len1 = StrLen(str1);
	UINT len2 = StrLen(str2);
	if ( len1 < len2 )
		return 0;
	if ( len1 == len2 &&  0 == System::MemCmp((BYTE*)str1,(BYTE*)str2,len1) )
		return str1;
	UINT delta = len1 - len2;
	for ( UINT i = 0; i <= delta; i++)
		if ( 0 == System::MemCmp( (BYTE*)(str1 + i), (BYTE*)str2, len2) )
			return (str1 + i);
	
	return 0;
}

bool String::EndsWith(STRING string, STRING suffix)
{
	if ( 0 == string || 0 == suffix)
		return false;
	UINT stringLen = String::StrLen(string);
	UINT suffixLen = String::StrLen(suffix);
	if ( suffixLen > stringLen)
		return false;
	STRING suffixStart = string + (stringLen - suffixLen);
	return  1 + System::MemCmp((BYTE*)suffixStart, (BYTE*)suffix, suffixLen + 1);
}
UINT String::LastIndexOf(STRING stringToSearch, STRING originalString)
{
	if ( stringToSearch == 0 || originalString == 0)
		return 0;
	UINT originalLength = StrLen(originalString);
	UINT stringLen = StrLen(stringToSearch);
	if ( originalLength < stringLen)
		return - 1;
	UINT startPos = originalLength - stringLen;
	while ( startPos >= 0){
		if ( System::MemCmp((BYTE*)(startPos + originalString), (BYTE*)stringToSearch, stringLen) )
			return startPos;
		startPos--;
	}
	return - 1; //nothing found
}
