/******************************************************************************
 *    SetParamString.cpp
 *
 *    This file is part of Object Script Library
 *    Copyright (C) 2005-2009 Tom N Harris <telliamed@whoopdedo.org>
 *
 *    Permission is hereby granted, free of charge, to any person obtaining
 *    a copy of this software and associated documentation files (the 
 *    "Software"), to deal in the Software without restriction, including 
 *    without limitation the rights to use, copy, modify, merge, publish, 
 *    distribute, sublicense, and/or sell copies of the Software, and to 
 *    permit persons to whom the Software is furnished to do so.
 *    
 *    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 
 *    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 
 *    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-
 *    INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 
 *    BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 
 *    AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 
 *    IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
 *    THE SOFTWARE.
 *
 *****************************************************************************/

#include "ScriptLib.h"

#include <string.h>
#include <ctype.h>
#include <stdio.h>

extern const char* g_pszParamDelim;
extern const char* g_pszQuotes;

char* SetParamString(char* pszString, const char* pszParam, const char* pszVal)
{
	if (!pszParam || !pszVal)
		return NULL;
	int iLen = pszString ? strlen(pszString) : 0;
	iLen += strlen(pszParam) + 2;
	char quote = 0;
	const char* pszChar = pszVal;
	while (*pszChar)
	{
		switch (*pszChar++)
		{
		case '"':
			if (!quote) quote = '\'';
			iLen += 2;
			break;
		case '\'':
			quote = '"';
			iLen += 2;
			break;
		case '\\':
			++iLen;
		case ';': case '=': case '!': case ' ':
			if (!quote) quote = '"';
		default:
			++iLen;
			break;
		}
	}
	if (quote)
		iLen += 2;
	char* pszNew = reinterpret_cast<char*>(g_pMalloc->Alloc(iLen + 1));
	if (!pszNew)
		return NULL;
	char* pszRet;
	if (quote)
	{
		pszRet = pszNew + sprintf(pszNew, "%s=", pszParam);
		pszChar = pszVal;
		*pszRet++ = quote;
		while (*pszChar)
		{
			if (*pszChar == quote || *pszChar == '\\')
				*pszRet++ = '\\';
			*pszRet++ = *pszChar++;
		}
		*pszRet++ = quote;
	}
	else
		pszRet = pszNew + sprintf(pszNew, "%s=%s", pszParam, pszVal);
	if (pszString)
	{
		*pszRet++ = *g_pszParamDelim;
		char* pszSep, *pszToken;
		for (pszSep = pszString, pszToken = strqsep(&pszSep, g_pszParamDelim, g_pszQuotes); 
		     pszToken; pszToken = strqsep(&pszSep, g_pszParamDelim, g_pszQuotes))
		{
			while (isspace(*pszToken)) ++pszToken;
			if (!*pszToken)
				continue;
			char* pszStart = strchr(pszToken, '=');
			if (pszStart)
				*pszStart++ = '\0';
			if (stricmp(pszToken, pszParam))
			{
				strcpy(pszRet, pszToken);
				pszRet += strlen(pszToken);
				if (pszStart)
				{
					*pszRet++ = '=';
					strcpy(pszRet, pszStart);
					pszRet += strlen(pszStart);
				}
				*pszRet++ = *g_pszParamDelim;
			}
		}
	}
	*pszRet = '\0';
	return pszNew;
}
