namespace IGCS
{
	ScanPattern::ScanPattern(std::string bytePatternAsString, int occurrence) : 
		_bytePatternAsString{ bytePatternAsString }, _occurrence{ occurrence }, _bytePattern{ nullptr }, _patternMask{ nullptr }, _patternSize{-1}, 
		_customOffset{ 0 }
	{
		createAOBPatternFromStringPattern();
	}


	ScanPattern::~ScanPattern()
	{
	}


	// Updates this pattern with the data used with an aob scan. This pattern contains a string in the form of "aa bb ??" where '??' is a byte
	// which has to be skipped in the comparison, and 'aa' and 'bb' are hexadecimal bytes which have to have that value at that position.
	// If a '|' is specified in the pattern, the position of the byte following it is the start offset returned by the aob scanner, instead of
	// the position of the first byte of the pattern. 
	void ScanPattern::createAOBPatternFromStringPattern()
	{
		if (_bytePattern != nullptr)
		{
			// already initialized
			return;
		}
		int index = 0;
		char* pChar = (char*)_bytePatternAsString.c_str();
		_patternSize = static_cast<int>(_bytePatternAsString.size());
		_bytePattern = (LPBYTE)calloc(_patternSize, sizeof(BYTE));
		_patternMask = (char*)calloc((__int64)_patternSize + 2, sizeof(char));
		_customOffset = 0;

		while (*pChar)
		{
			if (*pChar == ' ')
			{
				pChar++;
				continue;
			}

			if (*pChar == '|')
			{
				pChar++;
				_customOffset = index;
				continue;
			}

			if (*pChar == '?')
			{
				_patternMask[index++] += '?';
				pChar += 2;
				continue;
			}

			_patternMask[index] = 'x';
			_bytePattern[index++] = (CharToByte(pChar[0]) << 4) + CharToByte(pChar[1]);
			pChar += 2;
		}
	}
	

	BYTE ScanPattern::CharToByte(char c)
	{
		BYTE b;
		sscanf_s(&c, "%hhx", &b);
		return b;
	}
}