// 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/color.h"
#include "../../include/javascript/JS_EventHandler.h"
#include "../../include/javascript/JS_Context.h"
#include "../../include/javascript/JS_Runtime.h"

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();
}
/* -------------------------- color -------------------------- */

BEGIN_JS_STATIC_CONST(CJS_Color)
END_JS_STATIC_CONST()

BEGIN_JS_STATIC_PROP(CJS_Color)
	JS_STATIC_PROP_ENTRY(black)
	JS_STATIC_PROP_ENTRY(blue)
	JS_STATIC_PROP_ENTRY(cyan)	
	JS_STATIC_PROP_ENTRY(dkGray)
	JS_STATIC_PROP_ENTRY(gray)
	JS_STATIC_PROP_ENTRY(green)
	JS_STATIC_PROP_ENTRY(ltGray)
	JS_STATIC_PROP_ENTRY(magenta)
	JS_STATIC_PROP_ENTRY(red)	
	JS_STATIC_PROP_ENTRY(transparent)
	JS_STATIC_PROP_ENTRY(white)
	JS_STATIC_PROP_ENTRY(yellow)
END_JS_STATIC_PROP()

BEGIN_JS_STATIC_METHOD(CJS_Color)
	JS_STATIC_METHOD_ENTRY(convert, 2)
	JS_STATIC_METHOD_ENTRY(equal, 2)
END_JS_STATIC_METHOD()

IMPLEMENT_JS_CLASS(CJS_Color,color)

color::color(CJS_Object* pJSObject): CJS_EmbedObj(pJSObject)
{
	m_crTransparent = CPWL_Color(COLORTYPE_TRANSPARENT);
	m_crBlack = CPWL_Color(COLORTYPE_GRAY, 0);
	m_crWhite = CPWL_Color(COLORTYPE_GRAY, 1);
	m_crRed = CPWL_Color(COLORTYPE_RGB, 1, 0 ,0);
	m_crGreen = CPWL_Color(COLORTYPE_RGB, 0, 1 ,0);
	m_crBlue = CPWL_Color(COLORTYPE_RGB, 0, 0 ,1);
	m_crCyan = CPWL_Color(COLORTYPE_CMYK, 1, 0 ,0, 0);
	m_crMagenta = CPWL_Color(COLORTYPE_CMYK, 0, 1 ,0, 0);
	m_crYellow = CPWL_Color(COLORTYPE_CMYK, 0, 0 ,1, 0);
	m_crDKGray = CPWL_Color(COLORTYPE_GRAY, 0.25);
	m_crGray = CPWL_Color(COLORTYPE_GRAY, 0.5);
	m_crLTGray = CPWL_Color(COLORTYPE_GRAY, 0.75);
}

color::~color(void)
{
}

void color::ConvertPWLColorToArray(const CPWL_Color& color, CJS_Array& array)
{
	switch (color.nColorType)
	{
	case COLORTYPE_TRANSPARENT:
		array.SetElement(0, CJS_Value(array.GetIsolate(), "T"));
		break;
	case COLORTYPE_GRAY:
		array.SetElement(0, CJS_Value(array.GetIsolate(),"G"));
		array.SetElement(1, CJS_Value(array.GetIsolate(),color.fColor1));
		break;
	case COLORTYPE_RGB:
		array.SetElement(0, CJS_Value(array.GetIsolate(),"RGB"));
		array.SetElement(1, CJS_Value(array.GetIsolate(),color.fColor1));
		array.SetElement(2, CJS_Value(array.GetIsolate(),color.fColor2));
		array.SetElement(3, CJS_Value(array.GetIsolate(),color.fColor3));
		break;
	case COLORTYPE_CMYK:
		array.SetElement(0, CJS_Value(array.GetIsolate(),"CMYK"));
		array.SetElement(1, CJS_Value(array.GetIsolate(),color.fColor1));
		array.SetElement(2, CJS_Value(array.GetIsolate(),color.fColor2));
		array.SetElement(3, CJS_Value(array.GetIsolate(),color.fColor3));
		array.SetElement(4, CJS_Value(array.GetIsolate(),color.fColor4));
		break;
	}
}

void color::ConvertArrayToPWLColor(CJS_Array& array, CPWL_Color& color)
{
	int nArrayLen = array.GetLength();
	if (nArrayLen < 1) return;

	CJS_Value value(array.GetIsolate());
	CFX_ByteString sSpace;
	array.GetElement(0, value);
	sSpace = value;

	double d1 = 0;
	double d2 = 0;
	double d3 = 0;
	double d4 = 0;

	if (nArrayLen > 1)
	{
		array.GetElement(1, value);
		d1 = value;
	}

	if (nArrayLen > 2)
	{
		array.GetElement(2, value);
		d2 = value;
	}

	if (nArrayLen > 3)
	{
		array.GetElement(3, value);
		d3 = value;
	}

	if (nArrayLen > 4)
	{
		array.GetElement(4, value);
		d4 = value;
	}

	if (sSpace == "T")
	{
		color = CPWL_Color(COLORTYPE_TRANSPARENT);
	}
	else if (sSpace == "G")
	{
		color = CPWL_Color(COLORTYPE_GRAY, (FX_FLOAT)d1);
	}
	else if (sSpace == "RGB")
	{
		color = CPWL_Color(COLORTYPE_RGB, (FX_FLOAT)d1, (FX_FLOAT)d2, (FX_FLOAT)d3);
	}
	else if (sSpace == "CMYK")
	{
		color = CPWL_Color(COLORTYPE_CMYK, (FX_FLOAT)d1, (FX_FLOAT)d2, (FX_FLOAT)d3, (FX_FLOAT)d4);
	}
}

#define JS_IMPLEMENT_COLORPROP(prop, var)\
FX_BOOL color::prop(OBJ_PROP_PARAMS)\
{\
	CJS_Context* pContext = (CJS_Context*)cc;\
	v8::Isolate* isolate = pContext->GetJSRuntime()->GetIsolate();\
	if (vp.IsGetting())\
	{\
		CJS_Array array(isolate);\
		ConvertPWLColorToArray(var, array);\
		vp << array;\
	}\
	else\
	{\
		CJS_Array array(isolate);\
		if (!vp.ConvertToArray(array)) return FALSE;\
		ConvertArrayToPWLColor(array, var);\
	}\
	return TRUE;\
}

JS_IMPLEMENT_COLORPROP(transparent, m_crTransparent)
JS_IMPLEMENT_COLORPROP(black, m_crBlack)
JS_IMPLEMENT_COLORPROP(white, m_crWhite)
JS_IMPLEMENT_COLORPROP(red, m_crRed)
JS_IMPLEMENT_COLORPROP(green, m_crGreen)
JS_IMPLEMENT_COLORPROP(blue, m_crBlue)
JS_IMPLEMENT_COLORPROP(cyan, m_crCyan)
JS_IMPLEMENT_COLORPROP(magenta, m_crMagenta)
JS_IMPLEMENT_COLORPROP(yellow, m_crYellow)
JS_IMPLEMENT_COLORPROP(dkGray, m_crDKGray)
JS_IMPLEMENT_COLORPROP(gray, m_crGray)
JS_IMPLEMENT_COLORPROP(ltGray, m_crLTGray)

FX_BOOL color::convert(OBJ_METHOD_PARAMS)
{
	v8::Isolate* isolate = GetIsolate(cc);
	int iSize = params.size();
	if (iSize < 2) return FALSE;
	CJS_Array aSource(isolate);
	if (!params[0].ConvertToArray(aSource)) return FALSE;

	CPWL_Color crSource;
	ConvertArrayToPWLColor(aSource, crSource);

	CFX_ByteString sDestSpace = params[1];

	int nColorType = COLORTYPE_TRANSPARENT;
	
	if (sDestSpace == "T")
	{
		nColorType = COLORTYPE_TRANSPARENT;
	}
	else if (sDestSpace == "G")
	{
		nColorType = COLORTYPE_GRAY;
	}
	else if (sDestSpace == "RGB")
	{
		nColorType = COLORTYPE_RGB;
	}
	else if (sDestSpace == "CMYK")
	{
		nColorType = COLORTYPE_CMYK;
	}

	CJS_Array aDest(isolate);
	CPWL_Color crDest = crSource;
	crDest.ConvertColorType(nColorType);
	ConvertPWLColorToArray(crDest, aDest);
	vRet = aDest;

	return TRUE;
}

FX_BOOL color::equal(OBJ_METHOD_PARAMS)
{
	v8::Isolate* isolate = GetIsolate(cc);
	if (params.size() < 2) return FALSE;

	CJS_Array array1(isolate), array2(isolate);

	if (!params[0].ConvertToArray(array1)) return FALSE;
	if (!params[1].ConvertToArray(array2)) return FALSE;

	CPWL_Color color1;
	CPWL_Color color2;

	ConvertArrayToPWLColor(array1, color1);
	ConvertArrayToPWLColor(array2, color2);

	color1.ConvertColorType(color2.nColorType);

	vRet = color1 == color2;
	return TRUE;
}

