#pragma once

#include <string>
#include <comutil.h>
#pragma comment(lib, "comsupp.lib")
#pragma comment(lib, "comsuppw.lib")

inline std::string ws2s(const std::wstring& ws)
{
	_bstr_t t = ws.c_str();
	char* pchar = (char*)t;
	return std::string(pchar);
}
inline std::wstring s2ws(const std::string& s)
{
	_bstr_t t = s.c_str();
	wchar_t* pwchar = (wchar_t*)t;
	return std::wstring(pwchar);
}

inline int CheckTemplate(char* expr, char* tok_end, const char* group, char* prev, int* deep)
{
	char  tmp = 0;
	char *lastwc, *prev_tok;
	const char *cp;
	//--- 
	if ((*deep)++ >= 10) return(FALSE);
	//--- 
	while (*expr == '*' && expr != tok_end) expr++;
	if (expr == tok_end) return(TRUE);
	//--- 
	lastwc = expr;
	while (*lastwc != '*' && *lastwc != 0) lastwc++;
	//---
	if ((tmp = *(lastwc)) != 0) //
	{
		tmp = *(lastwc); *(lastwc) = 0;
		if ((prev_tok = (char*)strstr(group, expr)) == NULL)
		{
			if (tmp != 0) *(lastwc) = tmp;
			return(FALSE);
		}
		*(lastwc) = tmp;
	}
	else //
	{
		//---
		cp = group + strlen(group);
		for (; cp >= group; cp--)
			if (*cp == expr[0] && strcmp(cp, expr) == 0)
				return(TRUE);
		return(FALSE);
	}
	//---
	if (prev != NULL && prev_tok <= prev) return(FALSE);
	prev = prev_tok;
	//---
	group = prev_tok + (lastwc - expr - 1);
	//---
	if (lastwc != tok_end) return CheckTemplate(lastwc, tok_end, group, prev, deep);
	//---
	return(TRUE);
}

inline int CheckTemplate(wchar_t* expr, wchar_t* tok_end, const wchar_t* group, wchar_t* prev, int* deep)
{
	wchar_t  tmp = 0;
	wchar_t *lastwc, *prev_tok;
	const wchar_t *cp;
	//--- 
	if ((*deep)++ >= 10) return(FALSE);
	//--- 
	while (*expr == L'*' && expr != tok_end) expr++;
	if (expr == tok_end) return(TRUE);
	//--- 
	lastwc = expr;
	while (*lastwc != L'*' && *lastwc != 0) lastwc++;
	//---
	if ((tmp = *(lastwc)) != 0) //
	{
		tmp = *(lastwc); *(lastwc) = 0;
		if ((prev_tok = (wchar_t*)wcsstr(group, expr)) == NULL)
		{
			if (tmp != 0) *(lastwc) = tmp;
			return(FALSE);
		}
		*(lastwc) = tmp;
	}
	else //
	{
		//---
		cp = group + wcslen(group);
		for (; cp >= group; cp--)
			if (*cp == expr[0] && wcscmp(cp, expr) == 0)
				return(TRUE);
		return(FALSE);
	}
	//---
	if (prev != NULL && prev_tok <= prev) return(FALSE);
	prev = prev_tok;
	//---
	group = prev_tok + (lastwc - expr - 1);
	//---
	if (lastwc != tok_end) return CheckTemplate(lastwc, tok_end, group, prev, deep);
	//---
	return(TRUE);
}

inline int CheckGroup(char* grouplist, const char *group)
{
	//--- 
	if (grouplist == NULL || group == NULL) return(FALSE);
	char *tok_start = grouplist, end;
	int  res = TRUE, deep = 0, normal_mode;
	while (*tok_start != 0)
	{
		//--- 
		while (*tok_start == ',') tok_start++;
		//---
		if (*tok_start == '!') { tok_start++; normal_mode = FALSE; }
		else                 normal_mode = TRUE;
		//--- 
		char *tok_end = tok_start;
		while (*tok_end != ',' && *tok_end != 0) tok_end++;
		end = *tok_end; *tok_end = NULL;
		//---
		char *tp = tok_start;
		const char *gp = group;
		char *prev = NULL;
		res = TRUE;
		while (tp != tok_end && *gp != NULL)
		{
			if (*tp == '*')
			{
				deep = 0;
				if ((res = CheckTemplate(tp, tok_end, gp, prev, &deep)) == TRUE)
				{
					*tok_end = end;
					return(normal_mode);
				}
				break;
			}
			if (*tp != *gp)
			{
				*tok_end = end;
				res = FALSE;
				break;
			}
			tp++;
			gp++;
		}
		*tok_end = end;
		if (*gp == NULL && (tp == tok_end || *tp == '*') && res == TRUE) return(normal_mode);
		if (*tok_end == 0) break;
		tok_start = tok_end + 1;
	}
	return(FALSE);
}


inline int CheckGroup(wchar_t* grouplist, const wchar_t *group)
{
	//--- 
	if (grouplist == NULL || group == NULL) return(FALSE);
	wchar_t *tok_start = grouplist, end;
	int  res = TRUE, deep = 0, normal_mode;
	while (*tok_start != 0)
	{
		//--- 
		while (*tok_start == L',') tok_start++;
		//---
		if (*tok_start == L'!') { tok_start++; normal_mode = FALSE; }
		else                 normal_mode = TRUE;
		//--- 
		wchar_t *tok_end = tok_start;
		while (*tok_end != L',' && *tok_end != 0) tok_end++;
		end = *tok_end; *tok_end = NULL;
		//---
		wchar_t *tp = tok_start;
		const wchar_t *gp = group;
		wchar_t *prev = NULL;
		res = TRUE;
		while (tp != tok_end && *gp != NULL)
		{
			if (*tp == L'*')
			{
				deep = 0;
				if ((res = CheckTemplate(tp, tok_end, gp, prev, &deep)) == TRUE)
				{
					*tok_end = end;
					return(normal_mode);
				}
				break;
			}
			if (*tp != *gp)
			{
				*tok_end = end;
				res = FALSE;
				break;
			}
			tp++;
			gp++;
		}
		*tok_end = end;
		if (*gp == NULL && (tp == tok_end || *tp == L'*') && res == TRUE) return(normal_mode);
		if (*tok_end == 0) break;
		tok_start = tok_end + 1;
	}
	return(FALSE);
}
