// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
 
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "../../include/javascript/JavaScript.h"
#include "../../include/javascript/IJavaScript.h"
#include "../../include/javascript/JS_Define.h"
#include "../../include/javascript/JS_Object.h"
#include "../../include/javascript/JS_Value.h"
#include "../../include/javascript/util.h"
#include "../../include/javascript/PublicMethods.h"
#include "../../include/javascript/resource.h"
#include "../../include/javascript/JS_Context.h"
#include "../../include/javascript/JS_EventHandler.h"
#include "../../include/javascript/JS_Runtime.h"

#if _FX_OS_  == _FX_ANDROID_
#include <ctype.h>
#endif

static v8::Isolate* GetIsolate(IFXJS_Context* cc)
{
	CJS_Context* pContext = (CJS_Context *)cc;
	ASSERT(pContext != NULL);

	CJS_Runtime* pRuntime = pContext->GetJSRuntime();
	ASSERT(pRuntime != NULL);

	return pRuntime->GetIsolate();
}

BEGIN_JS_STATIC_CONST(CJS_Util)
END_JS_STATIC_CONST()

BEGIN_JS_STATIC_PROP(CJS_Util)
END_JS_STATIC_PROP()

BEGIN_JS_STATIC_METHOD(CJS_Util)
	JS_STATIC_METHOD_ENTRY(printd, 3)
	JS_STATIC_METHOD_ENTRY(printf, 20)
	JS_STATIC_METHOD_ENTRY(printx, 2)
	JS_STATIC_METHOD_ENTRY(scand, 2)
	JS_STATIC_METHOD_ENTRY(byteToChar, 1)
END_JS_STATIC_METHOD()

IMPLEMENT_JS_CLASS(CJS_Util,util)

util::util(CJS_Object *pJSObject) : CJS_EmbedObj(pJSObject)
{
}

util::~util(void)
{
}


struct stru_TbConvert
{
	FX_LPCWSTR lpszJSMark;
	FX_LPCWSTR lpszCppMark;
};

const stru_TbConvert fcTable[] = {
	{ (FX_LPCWSTR)L"mmmm", (FX_LPCWSTR)L"%B" },
	{ (FX_LPCWSTR)L"mmm", (FX_LPCWSTR)L"%b" },
	{ (FX_LPCWSTR)L"mm",  (FX_LPCWSTR)L"%m" },
	//"m"
	{ (FX_LPCWSTR)L"dddd", (FX_LPCWSTR)L"%A" },
	{ (FX_LPCWSTR)L"ddd", (FX_LPCWSTR)L"%a" },
	{ (FX_LPCWSTR)L"dd",  (FX_LPCWSTR)L"%d" },
	//"d",   "%w",
	{ (FX_LPCWSTR)L"yyyy", (FX_LPCWSTR)L"%Y" },
	{ (FX_LPCWSTR)L"yy",  (FX_LPCWSTR)L"%y" },
	{ (FX_LPCWSTR)L"HH",  (FX_LPCWSTR)L"%H" },
	//"H"
	{ (FX_LPCWSTR)L"hh",  (FX_LPCWSTR)L"%I" },
	//"h"
	{ (FX_LPCWSTR)L"MM",  (FX_LPCWSTR)L"%M" },
	//"M"
	{ (FX_LPCWSTR)L"ss",  (FX_LPCWSTR)L"%S" },
	//"s
	{ (FX_LPCWSTR)L"TT",  (FX_LPCWSTR)L"%p" },
	//"t"
#if defined(_WIN32)
	{ (FX_LPCWSTR)L"tt",  (FX_LPCWSTR)L"%p" },
	{ (FX_LPCWSTR)L"h",  (FX_LPCWSTR)L"%#I" },
#else
	{ (FX_LPCWSTR)L"tt",  (FX_LPCWSTR)L"%P" },
	{ (FX_LPCWSTR)L"h",  (FX_LPCWSTR)L"%l" },
#endif
};

#define UTIL_INT			0
#define UTIL_DOUBLE			1
#define UTIL_STRING			2

int util::ParstDataType(std::wstring* sFormat)
{
        size_t i = 0;
	bool bPercent = FALSE;
	for (i=0; i<sFormat->length(); ++i)
	{
		wchar_t c = (*sFormat)[i];
		if (c == L'%')
		{
			bPercent = true;
			continue;
		}

		if (bPercent)
		{
			if (c == L'c' || c == L'C' || c == L'd' || c == L'i' || c == L'o' || c == L'u' || c == L'x' || c == L'X')
			{
				return UTIL_INT;
			}
			else if (c == L'e' || c == L'E' || c == L'f' || c == L'g' || c == L'G')
			{
				return UTIL_DOUBLE;
			}
			else if (c == L's' || c == L'S')
			{
				// Map s to S since we always deal internally
				// with wchar_t strings.
				(*sFormat)[i] = L'S';
				return UTIL_STRING;
			}
			else if (c == L'.' || c == L'+' || c == L'-' || c == L'#' || c == L' ' || CJS_PublicMethods::IsDigit(c))
			{
				continue;
			}
			else break;
		}
	}

	return -1;
}

FX_BOOL util::printf(OBJ_METHOD_PARAMS)
{
	int iSize = params.size();
	if (iSize < 1)
		return FALSE;
	std::wstring  c_ConvChar((const wchar_t*)(FX_LPCWSTR)params[0].operator CFX_WideString());
	std::vector<std::wstring> c_strConvers;
	int iOffset = 0;
	int iOffend = 0;
	c_ConvChar.insert(c_ConvChar.begin(),L'S');
	while(iOffset != -1)
	{
		iOffend = c_ConvChar.find(L"%",iOffset+1);
		std::wstring strSub;
		if (iOffend == -1)
			strSub = c_ConvChar.substr(iOffset);			
		else
			strSub = c_ConvChar.substr(iOffset ,iOffend - iOffset);
		c_strConvers.push_back(strSub);
		iOffset = iOffend ;
	}

	std::wstring c_strResult;

	//for(int iIndex = 1;iIndex < params.size();iIndex++)
	std::wstring c_strFormat;
	for(int iIndex = 0;iIndex < (int)c_strConvers.size();iIndex++)
	{
		c_strFormat = c_strConvers[iIndex];
		if (iIndex == 0)
		{
			c_strResult = c_strFormat;
			continue;
		}


		CFX_WideString strSegment;
		if (iIndex >= iSize) {
			c_strResult += c_strFormat;
			continue;
		}

		switch (ParstDataType(&c_strFormat))
		{
			case UTIL_INT:
				strSegment.Format((FX_LPCWSTR)c_strFormat.c_str(),(int)params[iIndex]);
				break;
			case UTIL_DOUBLE:
				strSegment.Format((FX_LPCWSTR)c_strFormat.c_str(),(double)params[iIndex]);
				break;
			case UTIL_STRING:
				strSegment.Format((FX_LPCWSTR)c_strFormat.c_str(),(FX_LPCWSTR)params[iIndex].operator CFX_WideString());
				break;
			default:
				strSegment.Format((FX_LPCWSTR)L"%S", (FX_LPCWSTR)c_strFormat.c_str());
				break;
		}
		c_strResult += (wchar_t*)strSegment.GetBuffer(strSegment.GetLength()+1);
	}

	c_strResult.erase(c_strResult.begin());
	vRet = (FX_LPCWSTR)c_strResult.c_str();
	return TRUE;
}

FX_BOOL util::printd(OBJ_METHOD_PARAMS)
{
	v8::Isolate* isolate = GetIsolate(cc);

	int iSize = params.size();
	if (iSize < 2)
		return FALSE;

	CJS_Value p1(isolate);
	p1 = params[0];

	CJS_Value p2 = params[1];
	CJS_Date jsDate(isolate);
	if (!p2.ConvertToDate(jsDate))
	{
		sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPRINT1);
		return FALSE;
	}

	if (!jsDate.IsValidDate())
	{
		sError = JSGetStringFromID((CJS_Context*)cc, IDS_STRING_JSPRINT2);
		return FALSE;
	}

	if (p1.GetType() == VT_number)
	{
		int nFormat = p1;

		CFX_WideString swResult;

		switch (nFormat)
		{
		case 0:
			swResult.Format((FX_LPCWSTR)L"D:%04d%02d%02d%02d%02d%02d", 
				jsDate.GetYear(),
				jsDate.GetMonth() + 1,
				jsDate.GetDay(),
				jsDate.GetHours(),
				jsDate.GetMinutes(),
				jsDate.GetSeconds());
			break;
		case 1:
			swResult.Format((FX_LPCWSTR)L"%04d.%02d.%02d %02d:%02d:%02d", 
				jsDate.GetYear(),
				jsDate.GetMonth() + 1,
				jsDate.GetDay(),
				jsDate.GetHours(),
				jsDate.GetMinutes(),
				jsDate.GetSeconds());
			break;
		case 2:
			swResult.Format((FX_LPCWSTR)L"%04d/%02d/%02d %02d:%02d:%02d", 
				jsDate.GetYear(),
				jsDate.GetMonth() + 1,
				jsDate.GetDay(),
				jsDate.GetHours(),
				jsDate.GetMinutes(),
				jsDate.GetSeconds());
			break;
		default:
			return FALSE;
		}

		vRet = swResult;
		return TRUE;
	}
	else if (p1.GetType() == VT_string)
	{
		std::basic_string<wchar_t> cFormat = (wchar_t*)(FX_LPCWSTR)p1.operator CFX_WideString();		

		bool bXFAPicture = false;
		if (iSize > 2)
		{
			//CJS_Value value;
			bXFAPicture = params[2];
		}

		if (bXFAPicture)
		{
			return FALSE; //currently, it doesn't support XFAPicture.
		}

        int iIndex;
		for(iIndex = 0;iIndex<sizeof(fcTable)/sizeof(stru_TbConvert);iIndex++)
		{
			int iStart = 0;
			int iEnd;
			while((iEnd = cFormat.find((CFX_WideString)fcTable[iIndex].lpszJSMark, iStart)) != -1)
			{
				cFormat.replace(iEnd, FXSYS_wcslen(fcTable[iIndex].lpszJSMark), (CFX_WideString)fcTable[iIndex].lpszCppMark);
				iStart = iEnd;
			}
		}

		int iYear,iMonth,iDay,iHour,iMin,iSec;
		iYear = jsDate.GetYear();
		iMonth = jsDate.GetMonth();
		iDay = jsDate.GetDay();
		iHour = jsDate.GetHours();
		iMin = jsDate.GetMinutes();
		iSec = jsDate.GetSeconds();

		struct tm time = {0};
		time.tm_year = iYear-1900;
		time.tm_mon = iMonth;
		time.tm_mday = iDay;
		time.tm_hour = iHour;
		time.tm_min = iMin;
		time.tm_sec = iSec;
		//COleDateTime cppTm(iYear,iMonth+1,iDay,iHour,iMin,iSec);
		//CString strFormat = cppTm.Format(cFormat.c_str());

		struct stru_TbConvertAd
		{
			FX_LPCWSTR lpszJSMark;
			int     iValue;
		};

		stru_TbConvertAd cTableAd[] ={
			(FX_LPCWSTR)L"m", iMonth+1,
				(FX_LPCWSTR)L"d", iDay,
				(FX_LPCWSTR)L"H", iHour,
				(FX_LPCWSTR)L"h", iHour>12?iHour-12:iHour,
				(FX_LPCWSTR)L"M", iMin,
				(FX_LPCWSTR)L"s", iSec
		};

		//cFormat = strFormat.GetBuffer(strFormat.GetLength()+1);
		for(iIndex = 0;iIndex<sizeof(cTableAd)/sizeof(stru_TbConvertAd);iIndex++)
		{
			wchar_t tszValue[10];
			//_itot(cTableAd[iIndex].iValue,tszValue,10);
			CFX_WideString sValue;
			sValue.Format((FX_LPCWSTR)L"%d",cTableAd[iIndex].iValue);
			memcpy(tszValue, (wchar_t *)sValue.GetBuffer(sValue.GetLength()+1),
                               (sValue.GetLength()+1)*sizeof(wchar_t));

			//strFormat.Replace(cTableAd[iIndex].lpszJSMark,"%d");
			//strFormat.Format(strFormat,cTableAd[iIndex].iValue);
			int iStart = 0;
			int iEnd;
			while((iEnd = cFormat.find((CFX_WideString)cTableAd[iIndex].lpszJSMark,iStart)) != -1)
			{
				if (iEnd > 0)
				{
					if (cFormat[iEnd-1] == L'%')
					{
						iStart = iEnd+1;
						continue;
					}
				}
				cFormat.replace(iEnd, FXSYS_wcslen(cTableAd[iIndex].lpszJSMark), tszValue);
				iStart = iEnd;
			}
		}

		CFX_WideString strFormat;
//		strFormat.Format((FX_LPCWSTR)L"%d,%d,%d,%d,%d,%d",iYear, iMonth, iDay, iHour, iMin, iSec);
//		CString strFormat = cppTm.Format(cFormat.c_str());
		wchar_t buf[64] = {0};
		strFormat = wcsftime(buf, 64, cFormat.c_str(), &time);
		cFormat = buf;
		vRet = (FX_LPCWSTR)cFormat.c_str();
		//rtRet = strFormat.GetBuffer(strFormat.GetLength()+1);
		return TRUE;
	}
	return FALSE;
}

void util::printd(const std::wstring &cFormat2, CJS_Date jsDate, bool bXFAPicture, std::wstring &cPurpose)
{
	std::wstring cFormat = cFormat2;
	    
	if (bXFAPicture)
	{
		return ; //currently, it doesn't support XFAPicture.
	}

    int iIndex;
	for(iIndex = 0;iIndex<sizeof(fcTable)/sizeof(stru_TbConvert);iIndex++)
	{
		int iStart = 0;
		int iEnd;
		while((iEnd = cFormat.find((CFX_WideString)fcTable[iIndex].lpszJSMark,iStart)) != -1)
		{
			cFormat.replace(iEnd,FXSYS_wcslen(fcTable[iIndex].lpszJSMark), (CFX_WideString)fcTable[iIndex].lpszCppMark);
			iStart = iEnd;
		}
	}

	int iYear,iMonth,iDay,iHour,iMin,iSec;
	iYear = jsDate.GetYear();
	iMonth = jsDate.GetMonth();
	iDay = jsDate.GetDay();
	iHour = jsDate.GetHours();
	iMin = jsDate.GetMinutes();
	iSec = jsDate.GetSeconds();

	struct tm time = {0};
	time.tm_year = iYear-1900;
	time.tm_mon = iMonth;
	time.tm_mday = iDay;
	time.tm_hour = iHour;
	time.tm_min = iMin;
	time.tm_sec = iSec;
//	COleDateTime cppTm(iYear,iMonth+1,iDay,iHour,iMin,iSec);
	//CString strFormat = cppTm.Format(cFormat.c_str());

	struct stru_TbConvertAd
	{
		FX_LPCWSTR lpszJSMark;
		int     iValue;
	};

	stru_TbConvertAd cTableAd[] ={
		(FX_LPCWSTR)L"m", iMonth+1,
			(FX_LPCWSTR)L"d", iDay,
			(FX_LPCWSTR)L"H", iHour,
			(FX_LPCWSTR)L"h", iHour>12?iHour-12:iHour,
			(FX_LPCWSTR)L"M", iMin,
			(FX_LPCWSTR)L"s", iSec
	};

	//cFormat = strFormat.GetBuffer(strFormat.GetLength()+1);
	for(iIndex = 0;iIndex<sizeof(cTableAd)/sizeof(stru_TbConvertAd);iIndex++)
	{
		wchar_t tszValue[10];
		//_itot(cTableAd[iIndex].iValue,tszValue,10);
		CFX_WideString sValue;
		sValue.Format((FX_LPCWSTR)L"%d",cTableAd[iIndex].iValue);
		memcpy(tszValue, (wchar_t *)sValue.GetBuffer(sValue.GetLength()+1),sValue.GetLength()*sizeof(wchar_t));


		//strFormat.Replace(cTableAd[iIndex].lpszJSMark,"%d");
		//strFormat.Format(strFormat,cTableAd[iIndex].iValue);
		int iStart = 0;
		int iEnd;
		while((iEnd = cFormat.find((CFX_WideString)cTableAd[iIndex].lpszJSMark,iStart)) != -1)
		{
			if (iEnd > 0)
			{
				if (cFormat[iEnd-1] == L'%')
				{
					iStart = iEnd+1;
					continue;
				}
			}
			cFormat.replace(iEnd,FXSYS_wcslen(cTableAd[iIndex].lpszJSMark),tszValue);
			iStart = iEnd;
		}
	}

		CFX_WideString strFormat;
//		strFormat.Format((FX_LPCWSTR)L"%d,%d,%d,%d,%d,%d",iYear, iMonth, iDay, iHour, iMin, iSec);
//		CString strFormat = cppTm.Format(cFormat.c_str());
		wchar_t buf[64] = {0};
		strFormat = wcsftime(buf, 64, cFormat.c_str(), &time);
		cFormat = buf;
		cPurpose = cFormat;
}

FX_BOOL util::printx(OBJ_METHOD_PARAMS)
{
	int iSize = params.size();
	if (iSize<2)
		return FALSE;
	CFX_WideString sFormat = params[0].operator CFX_WideString();
	CFX_WideString sSource = params[1].operator CFX_WideString();
	std::string cFormat = (FX_LPCSTR)CFX_ByteString::FromUnicode(sFormat);
	std::string cSource = (FX_LPCSTR)CFX_ByteString::FromUnicode(sSource);
	std::string cDest;
	printx(cFormat,cSource,cDest);
	vRet = cDest.c_str();
	return TRUE;
}

void util::printx(const std::string &cFormat,const std::string &cSource2,std::string &cPurpose)
{
	std::string cSource(cSource2);
	if (!cPurpose.empty())
		//cPurpose.clear();
		cPurpose.erase();
	int itSource = 0;
	int iSize = cSource.size();
	for(int iIndex = 0; iIndex < (int)cFormat.size() && itSource<iSize; iIndex++)
	{
		char letter = cFormat[iIndex];
		switch(letter)
		{
		case '?':
			//cPurpose.push_back(cSource[itSource]);
			cPurpose += cSource[itSource];
			itSource++;
			break;
		case 'X':
			{
				while(itSource < iSize)
				{
					if ((cSource[itSource]>='0'&&cSource[itSource]<='9') || (cSource[itSource]>='a' && cSource[itSource]<='z') || (cSource[itSource]>='A' && cSource[itSource]<='Z'))
					{
						//cPurpose.push_back(cSource[itSource]);
						cPurpose += cSource[itSource];
						itSource++;
						break;
					}
					itSource++;
				}
				break;
			}
			break;
		case 'A':
			{
				while(itSource < iSize)
				{
					if ((cSource[itSource]>='a' && cSource[itSource]<='z') || (cSource[itSource]>='A' && cSource[itSource]<='Z'))
					{
						//cPurpose.push_back(cSource[itSource]);
						cPurpose += cSource[itSource];
						itSource++;
						break;
					}
					itSource++;
				}
				break;
			}
			break;
		case '9':
			{
				while(itSource < iSize)
				{
					if (cSource[itSource]>='0'&&cSource[itSource]<='9')
					{
						//cPurpose.push_back(cSource[itSource]);
						cPurpose += cSource[itSource];
						itSource++;
						break;
					}
					itSource++;
				}
				break;
			}
		case '*':
			{
				cPurpose.append(cSource,itSource,iSize-itSource);
				itSource = iSize-1;
				break;
			}
		case '\\':
			break;
		case '>':
			{
				for(std::string::iterator it = cSource.begin();it != cSource.end(); it++)
				{
					*it = toupper(*it);
				}
				break;
			}
		case '<':
			{
				for(std::string::iterator it = cSource.begin();it != cSource.end(); it++)
				{
					*it = tolower(*it);
				}
				break;
			}
		case '=':
			break;
		default:
			//cPurpose.push_back(letter);
			cPurpose += letter;
			break;
		}
	}
}

FX_BOOL util::scand(OBJ_METHOD_PARAMS)
{
	v8::Isolate* isolate = GetIsolate(cc);
	int iSize = params.size();
	if (iSize < 2)
		return FALSE;
	CFX_WideString sFormat = params[0].operator CFX_WideString();
	CFX_WideString sDate = params[1].operator CFX_WideString();

	double dDate = JS_GetDateTime();
	if (sDate.GetLength() > 0)
	{
		FX_BOOL bWrongFormat = FALSE;
		dDate = CJS_PublicMethods::MakeRegularDate(sDate,sFormat,bWrongFormat);
	}	
	
	if (!JS_PortIsNan(dDate))
	{
		CJS_Date date(isolate,dDate);
		vRet = date;
	}
	else
	{
		vRet.SetNull();
	}

	return TRUE;
}

FX_INT64 FX_atoi64(const char *nptr)
{
        int c;              /* current char */
        FX_INT64 total;      /* current total */
        int sign;           /* if '-', then negative, otherwise positive */

        /* skip whitespace */
        while ( isspace((int)(unsigned char)*nptr) )
            ++nptr;

        c = (int)(unsigned char)*nptr++;
        sign = c;           /* save sign indication */
        if (c == '-' || c == '+')
            c = (int)(unsigned char)*nptr++;    /* skip sign */

        total = 0;

        while (isdigit(c)) {
            total = 10 * total + (c - '0');     /* accumulate digit */
            c = (int)(unsigned char)*nptr++;    /* get next char */
        }

        if (sign == '-')
            return -total;
        else
            return total;   /* return result, negated if necessary */
}

FX_BOOL util::byteToChar(OBJ_METHOD_PARAMS)
{
	int iSize = params.size();
	if (iSize == 0)
		return FALSE;
	int nByte = (int)params[0];
	unsigned char cByte = (unsigned char)nByte;
	CFX_WideString csValue;
	csValue.Format((FX_LPCWSTR)L"%c", cByte);
	vRet = csValue; 
	return TRUE;
}
