/** 
 ** Parser UTIL Stable by sa1me AKA Eriurias
 ** http://www.amx-x.ru
 ** 
 ** Bug fixed (thanks for 'Ronna Riva')
 ** Added support for parse regular files (without sections)
 */

#if defined __UTIL_ParserIncluded
	#endinput
#endif

#define __UTIL_ParserIncluded

enum
{
	PARSER_ERROR = -3,
	PARSER_NOT_EXIST,
	PARSER_SUCCESS
};

const PARSER_BREAK = PLUGIN_HANDLED;
const PARSER_CONTINUE = PLUGIN_CONTINUE;

const _MAX_BUFFER_STRSIZE = 192;
const _MAX_SECTION_STRSIZE = 32;

stock any: UTIL_ParserLoadFile(const dir[])
{
	new Trie: tParserContent = TrieCreate();
		
	if (!file_exists(dir))
		return PARSER_NOT_EXIST;
	
	new iFile = fopen(dir, "rt");
	
	if (!iFile)
		return PARSER_ERROR;
	
	new bool: bFileSection = UTIL_FindSquareBrackets(dir), Array: aContent;
	new szBuffer[_MAX_BUFFER_STRSIZE], szSection[_MAX_SECTION_STRSIZE];
	
	if (!bFileSection)
		aContent = ArrayCreate(_MAX_BUFFER_STRSIZE, 1);
	
	while (!feof(iFile))
	{
		fgets(iFile, szBuffer, charsmax(szBuffer));
		
		trim(szBuffer);
		
		if (szBuffer[0] == ';' || szBuffer[0] == '#' || szBuffer[0] == EOS)
			continue;
			
		if (bFileSection && szBuffer[0] == '[' && szBuffer[1] != EOS)
		{
			aContent = ArrayCreate(_MAX_BUFFER_STRSIZE, 1);
			copy(szSection, charsmax(szSection), szBuffer);
			TrieSetCell(tParserContent, szSection, aContent);
			continue;
		}
		
		ArrayPushString(aContent, szBuffer);
	}
	
	if (!bFileSection && feof(iFile))
		TrieSetCell(tParserContent, "default", aContent);
	
	fclose(iFile);
	
	return tParserContent;
}

stock UTIL_ParserGetLines(const handle, const section[] = "default")
{
	if (!TrieKeyExists(Trie: handle, section))
		return PARSER_NOT_EXIST;
	
	new Array: aContent;
	TrieGetCell(Trie: handle, section, aContent);
	
	return ArraySize(aContent);
}

stock UTIL_ParserGetContent(const handle, const line, output[], const size, const section[] = "default")
{
	if (!TrieKeyExists(Trie: handle, section))
		return PARSER_NOT_EXIST;
	
	new Array: aContent;
	TrieGetCell(Trie: handle, section, aContent);
	
	if (ArrayGetString(aContent, line, output, size))
		return PARSER_SUCCESS;
	
	return PARSER_ERROR;
}

stock UTIL_ParserGetContentOnHandle(const handle, const function[], const section[] = "default")
{
	if (!TrieKeyExists(Trie: handle, section))
		return PARSER_NOT_EXIST;
	
	new szBuffer[_MAX_BUFFER_STRSIZE], Array: aContent;
	TrieGetCell(Trie: handle, section, aContent);
	
	for (new i; i < ArraySize(aContent); i++)
	{
		ArrayGetString(aContent, i, szBuffer, charsmax(szBuffer));
		
		if (callfunc_begin(function) == PARSER_NOT_EXIST)
		{
			callfunc_end();
			break;
		}
		
		callfunc_push_str(szBuffer);
		
		if (callfunc_end() == PARSER_BREAK)
			break;
	}
	
	return PARSER_SUCCESS;
}

static stock bool: UTIL_FindSquareBrackets(const dir[])
{
	new iFile = fopen(dir, "rt");
	
	if (!iFile)
		return false;
	
	new szBuffer[_MAX_BUFFER_STRSIZE];
	
	while (!feof(iFile))
	{
		fgets(iFile, szBuffer, charsmax(szBuffer));
		trim(szBuffer);
		
		if (szBuffer[0] == '[')
			return true;
	}
	
	return false;
}