#include "Core/Asura.h"
#include "Misc/Tools_StringUtil.h"

#include "Core/Asura_String.h"

#include <stdlib.h>


bool Tools_StringUtil::WildcardMatch(const char* pszTestString,const char* pszSearchString)
{
	const char* pcTestPos = pszTestString;
	const char* pcSearchPos = pszSearchString;
	bool bWildcard = false;

	while(*pcSearchPos)
	{
		while(*pcSearchPos == '*')
		{
			bWildcard = true;
			pcSearchPos++;
		}
		
		if(!*pcSearchPos) break;

		if(bWildcard)
		{
			bool bMatch;
			do
			{
				bMatch = true;

				//search forward until test string matches current character in search string
				while(*pcTestPos && tolower(*pcTestPos) != tolower(*pcSearchPos)) pcTestPos++;
				if(!*pcTestPos) return false;

				const char* pcTestPosBackup = pcTestPos;
				const char* pcSearchPosBackup = pcSearchPos;

				//see if characters match until * or end of search string is found
				while(*pcSearchPos && *pcSearchPos != '*')
				{
					if(tolower(*pcTestPos) != tolower(*pcSearchPos))
					{
						//doesn't match
						bMatch = false;
						break;
					}
					pcTestPos++;
					pcSearchPos++;
				}

				if(!bMatch)
				{
					//didn't match starting from that point
					//return to the backup , but advance the test string one character so we
					//don't find it again.
					pcTestPos = pcTestPosBackup+1;
					pcSearchPos = pcSearchPosBackup;
				}

			}while(!bMatch);

		}
		else
		{
			//no wildcard yet ,so just attempt to match letters one at a time
			while(*pcSearchPos && *pcSearchPos != '*')
			{
				if(tolower(*pcTestPos) != tolower(*pcSearchPos))
				{
					//doesn't match
					return false;
				}
				pcTestPos++;
				pcSearchPos++;
			}
		}
		bWildcard = false;

	}

	//reached end of search string . so we have a match if we are also at the end of the test
	//string , or if we have a wildcard leftover to mop up the remaining letters.

	return bWildcard || (*pcTestPos == 0);

}

void Tools_StringUtil::GenerateUniqueName(const char* szOriginalName, Asura_String& xOutput, bool(*IsNameOkay)(const char* szName))
{
	Asura_Assert(szOriginalName, "");
	Asura_Assert(IsNameOkay, "");

	//Is the original name okay?
	if(IsNameOkay(szOriginalName))
	{
		xOutput = szOriginalName;
		return;	
	}
	
	//If there is a numerical postfix on the name , cut it off , so it can be incremented when making the new name
	char acPrefix[200];
	Asura_PrintfToBfr(acPrefix,"%s",sizeof(acPrefix),true,szOriginalName);

	char* pcEnd = &acPrefix[strlen(acPrefix)-1];

	while(pcEnd>&acPrefix[0])
	{
		if((*pcEnd >= '0' && *pcEnd <= '9'))
		{
			pcEnd--;
		}
		else
		{
			break;
		}
	}
	pcEnd++;

	//Get the number (if any) from the end
	int iPostfixNumber = 0;

	bool bFoundPostfix = (sscanf(pcEnd,"%d",&iPostfixNumber) == 1);
	*pcEnd = 0;

	//search for an acceptable name
	char acNewName[300];
	do
	{
		if(bFoundPostfix)
		{
			Asura_PrintfToBfr(acNewName,"%s%d",sizeof(acNewName),true,acPrefix,++iPostfixNumber);
		}
		else
		{
			Asura_PrintfToBfr(acNewName,"%s %d",sizeof(acNewName),true,acPrefix,++iPostfixNumber);
		}
	}
	while(!IsNameOkay(acNewName));

	xOutput = acNewName;
}