
/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SkAnimatorScript2.h"
#include "SkAnimateBase.h"
#include "SkAnimateMaker.h"
#include "SkDisplayTypes.h"
#include "SkExtras.h"
#include "SkMemberInfo.h"
#include "SkOpArray.h"
#include "SkParse.h"
#include "SkScript2.h"
#include "SkScriptCallBack.h"

static const SkDisplayEnumMap gEnumMaps[] = {
	{ SkType_AddMode, "indirect|immediate" },
	{ SkType_Align, "left|center|right" },
	{ SkType_ApplyMode, "immediate|once" },
	{ SkType_ApplyTransition, "reverse" },
	{ SkType_BitmapEncoding, "jpeg|png" },
	{ SkType_BitmapFormat, "none|A1|A8|Index8|RGB16|RGB32" },
	{ SkType_Boolean, "false|true" },
	{ SkType_Cap, "butt|round|square" },
	{ SkType_EventCode, "none|up|down|left|right|back|end|OK|send|leftSoftKey|rightSoftKey|key0|key1|key2|key3|key4|key5|key6|key7|key8|key9|star|hash" },
	{ SkType_EventKind, "none|keyChar|keyPress|mouseDown|mouseDrag|mouseMove|mouseUp|onEnd|onLoad|user" },
	{ SkType_EventMode, "deferred|immediate" },
	{ SkType_FillType, "winding|evenOdd" },
	{ SkType_FilterType, "none|bilinear" },
	{ SkType_FromPathMode, "normal|angle|position" },
	{ SkType_Join, "miter|round|blunt" },
	{ SkType_MaskFilterBlurStyle, "normal|solid|outer|inner" },
	{ SkType_PathDirection, "cw|ccw" },
	{ SkType_Style, "fill|stroke|strokeAndFill" },
	{ SkType_TextBoxAlign, "start|center|end" },
	{ SkType_TextBoxMode, "oneLine|lineBreak" },
	{ SkType_TileMode, "clamp|repeat|mirror" },
	{ SkType_Xfermode, "clear|src|dst|srcOver|dstOver|srcIn|dstIn|srcOut|dstOut|"
		"srcATop|dstATop|xor|darken|lighten" },
};

static int gEnumMapCount = SK_ARRAY_COUNT(gEnumMaps);


class SkAnimatorScript_Box : public SkScriptCallBackConvert {
public:
	SkAnimatorScript_Box() {}

	~SkAnimatorScript_Box() {
		for (SkDisplayable** dispPtr = fTrackDisplayable.begin(); dispPtr < fTrackDisplayable.end(); dispPtr++)
			delete *dispPtr;
	}

	virtual bool convert(SkOperand2::OpType type, SkOperand2* operand) {
		SkDisplayable* displayable;
		switch (type) {
			case SkOperand2::kArray: {
				SkDisplayArray* boxedValue = new SkDisplayArray(*operand->fArray);
				displayable = boxedValue;
				} break;
			case SkOperand2::kS32: {
				SkDisplayInt* boxedValue = new SkDisplayInt;
				displayable = boxedValue;
				boxedValue->value = operand->fS32;
				} break;
			case SkOperand2::kScalar: {
				SkDisplayFloat* boxedValue = new SkDisplayFloat;
				displayable = boxedValue;
				boxedValue->value = operand->fScalar;
				} break;
			case SkOperand2::kString: {
				SkDisplayString* boxedValue = new SkDisplayString(*operand->fString);
				displayable = boxedValue;
				} break;
			case SkOperand2::kObject: 
				return true;
			default:
				SkASSERT(0);
				return false;
		}
		track(displayable);
		operand->fObject = (void*) displayable;
		return true;
	}

	virtual SkOperand2::OpType getReturnType(int index) { 
		return SkOperand2::kObject; 
	}

	virtual Type getType() const { 
		return kBox; 
	}

	void track(SkDisplayable* displayable) { 
		SkASSERT(fTrackDisplayable.find(displayable) < 0);  
		*fTrackDisplayable.append() = displayable; 
	}

	SkTDDisplayableArray fTrackDisplayable;
};


class SkAnimatorScript_Enum : public SkScriptCallBackProperty {
public:
	SkAnimatorScript_Enum(const char* tokens) : fTokens(tokens) {}

	virtual bool getConstValue(const char* name, int len, SkOperand2* value) { 
		return SkAnimatorScript2::MapEnums(fTokens, name, len, &value->fS32);
	}

private:
	const char* fTokens;
};

	// !!! if type is string, call invoke
	// if any other type, return original value
		// distinction is undone: could do this by returning index == 0 only if param is string
		// still, caller of getParamTypes will attempt to convert param to string (I guess)
class SkAnimatorScript_Eval : public SkScriptCallBackFunction {
public:
	SkAnimatorScript_Eval(SkAnimatorScript2* engine) : fEngine(engine) {}

	virtual bool getIndex(const char* name, int len, size_t* result) {
		if (SK_LITERAL_STR_EQUAL("eval", name, len) != 0)
			return false;
		*result = 0;
		return true;
	}
	
	virtual void getParamTypes(SkIntArray(SkOperand2::OpType)* types) {
		types->setCount(1);
		SkOperand2::OpType* type = types->begin();
		type[0] = SkOperand2::kString;
	}

	virtual bool invoke(size_t index, SkOpArray* params, SkOperand2* answer) {
		SkAnimatorScript2 engine(fEngine->getMaker(), fEngine->getWorking(), 
			SkAnimatorScript2::ToDisplayType(fEngine->getReturnType()));
		SkOperand2* op = params->begin();
		const char* script = op->fString->c_str();
		SkScriptValue2 value;
		return engine.evaluateScript(&script, &value);
		SkASSERT(value.fType == fEngine->getReturnType());
		*answer = value.fOperand;
		// !!! incomplete ?
		return true;
	}

private:
	SkAnimatorScript2* fEngine;
};

class SkAnimatorScript_ID : public SkScriptCallBackProperty {
public:
	SkAnimatorScript_ID(SkAnimatorScript2* engine) : fEngine(engine) {}

	virtual bool getIndex(const char* token, int len, size_t* result) {  
		SkDisplayable* displayable;
		bool success = fEngine->getMaker().find(token, len, &displayable);
		if (success == false) {
			*result = 0;
		} else {
			*result = (size_t) displayable;
			SkDisplayable* working = fEngine->getWorking();
			if (displayable->canContainDependents() && working && working->isAnimate()) {
				SkAnimateBase* animator = (SkAnimateBase*) working;
				if (animator->isDynamic()) {
					SkDisplayDepend* depend = (SkDisplayDepend* ) displayable;
					depend->addDependent(working);
				}
			}
		}
		return true; 
	}

	virtual bool getResult(size_t ref, SkOperand2* answer) {
		answer->fObject = (void*) ref;
		return true;
	}

	virtual SkOperand2::OpType getReturnType(size_t index) {
		return index == 0 ? SkOperand2::kString : SkOperand2::kObject;
	}

private:
	SkAnimatorScript2* fEngine;
};


class SkAnimatorScript_Member : public SkScriptCallBackMember {
public:

	SkAnimatorScript_Member(SkAnimatorScript2* engine) : fEngine(engine) {}

	bool getMemberReference(const char* member, size_t len, void* object, SkScriptValue2* ref) {
		SkDisplayable* displayable = (SkDisplayable*) object;
		SkString name(member, len);
		SkDisplayable* named = displayable->contains(name);
		if (named) {
			ref->fType = SkOperand2::kObject;
			ref->fOperand.fObject = named;
			return true;
		}
		const SkMemberInfo* info = displayable->getMember(name.c_str());
		if (info == NULL)
			return false;	// !!! add additional error info?
		ref->fType = SkAnimatorScript2::ToOpType(info->getType());
		ref->fOperand.fObject = (void*) info;
		return true;
	}

	bool invoke(size_t ref, void* object, SkOperand2* value) {
		const SkMemberInfo* info = (const SkMemberInfo* ) ref;
		SkDisplayable* displayable = (SkDisplayable*) object;
		if (info->fType == SkType_MemberProperty) {
			if (displayable->getProperty2(info->propertyIndex(), value) == false) {
				return false;
			}
		}
		return fEngine->evalMemberCommon(info, displayable, value);
	}

	SkAnimatorScript2* fEngine;
};


class SkAnimatorScript_MemberFunction : public SkScriptCallBackMemberFunction {
public:
	SkAnimatorScript_MemberFunction(SkAnimatorScript2* engine) : fEngine(engine) {}

	bool getMemberReference(const char* member, size_t len, void* object, SkScriptValue2* ref) {
		SkDisplayable* displayable = (SkDisplayable*) object;
		SkString name(member, len);
		const SkMemberInfo* info = displayable->getMember(name.c_str());
		if (info == NULL || info->fType != SkType_MemberFunction)
			return false;	// !!! add additional error info?
		ref->fType = SkAnimatorScript2::ToOpType(info->getType());
		ref->fOperand.fObject = (void*) info;
		return true;
	}

	virtual void getParamTypes(SkIntArray(SkOperand2::OpType)* types) {
		types->setCount(3);
		SkOperand2::OpType* type = types->begin();
		type[0] = type[1] = type[2] = SkOperand2::kS32;
	}

	bool invoke(size_t ref, void* object, SkOpArray* params, SkOperand2* value)
	{
		const SkMemberInfo* info = (const SkMemberInfo* ) ref;
		SkDisplayable* displayable = (SkDisplayable*) object;
		displayable->executeFunction2(displayable, info->functionIndex(), params, info->getType(), 
			value);
		return fEngine->evalMemberCommon(info, displayable, value);
	}

	SkAnimatorScript2* fEngine;
};


class SkAnimatorScript_NamedColor : public SkScriptCallBackProperty {
public:
	virtual bool getConstValue(const char* name, int len, SkOperand2* value) {
		return SkParse::FindNamedColor(name, len, (SkColor*) &value->fS32) != NULL;
	}
};


class SkAnimatorScript_RGB : public SkScriptCallBackFunction {
public:
	virtual bool getIndex(const char* name, int len, size_t* result) {
		if (SK_LITERAL_STR_EQUAL("rgb", name, len) != 0)
			return false;
		*result = 0;
		return true;
	}

	virtual void getParamTypes(SkIntArray(SkOperand2::OpType)* types) {
		types->setCount(3);
		SkOperand2::OpType* type = types->begin();
		type[0] = type[1] = type[2] = SkOperand2::kS32;
	}

	virtual bool invoke(size_t index, SkOpArray* params, SkOperand2* answer) {
		SkASSERT(index == 0);
		unsigned result = 0xFF000000;
		int shift = 16;
		for (int index = 0; index < 3; index++) {
			result |= SkClampMax(params->begin()[index].fS32, 255) << shift;
			shift -= 8;
		}
		answer->fS32 = result;
		return true;
	}

};


class SkAnimatorScript_Unbox : public SkScriptCallBackConvert {
public:
	SkAnimatorScript_Unbox(SkAnimatorScript2* engine) : fEngine(engine) {}

	virtual bool convert(SkOperand2::OpType type, SkOperand2* operand) {
		SkASSERT(type == SkOperand2::kObject);
		SkDisplayable* displayable = (SkDisplayable*) operand->fObject;
		switch (displayable->getType()) {
			case SkType_Array: {
				SkDisplayArray* boxedValue = (SkDisplayArray*) displayable;
				operand->fArray = new SkOpArray(SkAnimatorScript2::ToOpType(boxedValue->values.getType()));
				int count = boxedValue->values.count();
				operand->fArray->setCount(count);
				memcpy(operand->fArray->begin(), boxedValue->values.begin(), count * sizeof(SkOperand2));
				fEngine->track(operand->fArray);
				} break;
			case SkType_Boolean: {
				SkDisplayBoolean* boxedValue = (SkDisplayBoolean*) displayable;
				operand->fS32 = boxedValue->value;
				} break;
			case SkType_Int: {
				SkDisplayInt* boxedValue = (SkDisplayInt*) displayable;
				operand->fS32 = boxedValue->value;
				} break;
			case SkType_Float: {
				SkDisplayFloat* boxedValue = (SkDisplayFloat*) displayable;
				operand->fScalar = boxedValue->value;
				} break;
			case SkType_String: {
				SkDisplayString* boxedValue = (SkDisplayString*) displayable;
				operand->fString = SkNEW_ARGS(SkString, (boxedValue->value));
				} break;
			default: {
				const char* id;
				bool success = fEngine->getMaker().findKey(displayable, &id);
				SkASSERT(success);
				operand->fString = SkNEW_ARGS(SkString, (id));
			}
		}
		return true;
	}

	virtual SkOperand2::OpType getReturnType(int /*index*/, SkOperand2* operand) { 
		SkDisplayable* displayable = (SkDisplayable*) operand->fObject;
		switch (displayable->getType()) {
			case SkType_Array:
				return SkOperand2::kArray;
			case SkType_Int:
				return SkOperand2::kS32;
			case SkType_Float:
				return SkOperand2::kScalar;
			case SkType_String:
			default:
				return SkOperand2::kString;
		}
	}

	virtual Type getType() const { 
		return kUnbox; 
	}

	SkAnimatorScript2* fEngine;
};

SkAnimatorScript2::SkAnimatorScript2(SkAnimateMaker& maker, SkDisplayable* working, SkDisplayTypes type) : 
		SkScriptEngine2(ToOpType(type)), fMaker(maker), fWorking(working) {
	*fCallBackArray.append() = new SkAnimatorScript_Member(this);
	*fCallBackArray.append() = new SkAnimatorScript_MemberFunction(this);
	*fCallBackArray.append() = new SkAnimatorScript_Box();
	*fCallBackArray.append() = new SkAnimatorScript_Unbox(this);
	*fCallBackArray.append() = new SkAnimatorScript_ID(this);
	if (type == SkType_ARGB) {
		*fCallBackArray.append() = new SkAnimatorScript_RGB();
		*fCallBackArray.append() = new SkAnimatorScript_NamedColor();
	}
	if (SkDisplayType::IsEnum(&maker, type)) {
		// !!! for SpiderMonkey, iterate through the enum values, and map them to globals
		const SkDisplayEnumMap& map = GetEnumValues(type);
		*fCallBackArray.append() = new SkAnimatorScript_Enum(map.fValues); 
	}
	*fCallBackArray.append() = new SkAnimatorScript_Eval(this);
#if 0		// !!! no extra support for now
	for (SkExtras** extraPtr = maker.fExtras.begin(); extraPtr < maker.fExtras.end(); extraPtr++) {
		SkExtras* extra = *extraPtr;
		if (extra->fExtraCallBack)
			*fCallBackArray.append() = new propertyCallBack(extra->fExtraCallBack, extra->fExtraStorage);
	}
#endif
}

SkAnimatorScript2::~SkAnimatorScript2() {
	SkScriptCallBack** end = fCallBackArray.end();
	for (SkScriptCallBack** ptr = fCallBackArray.begin(); ptr < end; ptr++)
		delete *ptr;
}

bool SkAnimatorScript2::evalMemberCommon(const SkMemberInfo* info, 
		SkDisplayable* displayable, SkOperand2* value) {
	SkDisplayTypes original;
	SkDisplayTypes type = original = (SkDisplayTypes) info->getType();
	if (info->fType == SkType_Array)
		type = SkType_Array;
	switch (type) {
		case SkType_ARGB:
			type = SkType_Int;
		case SkType_Boolean:
		case SkType_Int:
		case SkType_MSec:
		case SkType_Float:
			SkASSERT(info->getCount() == 1);
			if (info->fType != SkType_MemberProperty && info->fType != SkType_MemberFunction) 
				value->fS32 = *(int32_t*) info->memberData(displayable);	// OK for SkScalar too
			if (type == SkType_MSec) {
				value->fScalar = SkScalarDiv((SkScalar) value->fS32, 1000); // dividing two ints is the same as dividing two scalars 
				type = SkType_Float;
			}
			break;
		case SkType_String: {
			SkString* displayableString;
			if (info->fType != SkType_MemberProperty && info->fType != SkType_MemberFunction) {
				info->getString(displayable, &displayableString);
				value->fString = new SkString(*displayableString);
			}
			} break;
		case SkType_Array: {
			SkASSERT(info->fType != SkType_MemberProperty); // !!! incomplete
			SkTDOperandArray* displayableArray = (SkTDOperandArray*) info->memberData(displayable);
			if (displayable->getType() == SkType_Array) {
				SkDisplayArray* typedArray = (SkDisplayArray*) displayable;
				original = typedArray->values.getType();
			}
			SkASSERT(original != SkType_Unknown);
			SkOpArray* array = value->fArray = new SkOpArray(ToOpType(original));
			track(array);
			int count = displayableArray->count();
			if (count > 0) {
				array->setCount(count);
				memcpy(array->begin(), displayableArray->begin(), count * sizeof(SkOperand2));
			}
			} break;
		default:
			SkASSERT(0); // unimplemented
	}
	return true;
}

const SkDisplayEnumMap& SkAnimatorScript2::GetEnumValues(SkDisplayTypes type) {
	int index = SkTSearch<SkDisplayTypes>(&gEnumMaps[0].fType, gEnumMapCount, type, 
		sizeof(SkDisplayEnumMap));
	SkASSERT(index >= 0);
	return gEnumMaps[index];
}

SkDisplayTypes SkAnimatorScript2::ToDisplayType(SkOperand2::OpType type) {
	int val = type;
	switch (val) {
		case SkOperand2::kNoType:
			return SkType_Unknown;
		case SkOperand2::kS32:
			return SkType_Int;
		case SkOperand2::kScalar:
			return SkType_Float;
		case SkOperand2::kString:
			return SkType_String;
		case SkOperand2::kArray:
			return SkType_Array;
		case SkOperand2::kObject:
			return SkType_Displayable;
		default:
			SkASSERT(0);
			return SkType_Unknown;
	}
}

SkOperand2::OpType SkAnimatorScript2::ToOpType(SkDisplayTypes type) {
	if (SkDisplayType::IsDisplayable(NULL /* fMaker */, type))
		return SkOperand2::kObject;
	if (SkDisplayType::IsEnum(NULL /* fMaker */, type))
		return SkOperand2::kS32;
	switch (type) {
		case SkType_ARGB:
		case SkType_MSec:
		case SkType_Int:
			return SkOperand2::kS32;
		case SkType_Float:
		case SkType_Point:
		case SkType_3D_Point:
			return SkOperand2::kScalar;
		case SkType_Base64:
		case SkType_DynamicString:
		case SkType_String:
			return SkOperand2::kString;
		case SkType_Array:
			return SkOperand2::kArray;
		case SkType_Unknown:
			return SkOperand2::kNoType;
		default:
			SkASSERT(0);
			return SkOperand2::kNoType;
	}
}

bool SkAnimatorScript2::MapEnums(const char* ptr, const char* match, size_t len, int* value) {
	int index = 0;
	bool more = true;
	do {
		const char* last = strchr(ptr, '|');
		if (last == NULL) {
			last = &ptr[strlen(ptr)];
			more = false;
		}
		size_t length = last - ptr;
		if (len == length && strncmp(ptr, match, length) == 0) {
			*value = index;
			return true;
		}
		index++;
		ptr = last + 1;
	} while (more);
	return false;
}

#if defined SK_DEBUG

#include "SkAnimator.h"

static const char scriptTestSetup[]  = 
"<screenplay>"
	"<apply>"
		"<paint>"
			"<emboss id='emboss' direction='[1,1,1]'  />"
		"</paint>"
		"<animateField id='animation' field='direction' target='emboss' from='[1,1,1]' to='[-1,1,1]' dur='1'/>"
		"<set lval='direction[0]' target='emboss' to='-1' />"
	"</apply>"
	"<color id='testColor' color='0 ? rgb(0,0,0) : rgb(255,255,255)' />"
	"<color id='xColor' color='rgb(12,34,56)' />"
	"<typedArray id='emptyArray' />"
	"<typedArray id='intArray' values='[1, 4, 6]' />"
	"<s32 id='idx' value='2' />"
	"<s32 id='idy' value='2' />"
	"<string id='alpha' value='abc' />"
	"<rectangle id='testRect' left='Math.cos(0)' top='2' right='12' bottom='5' />"
	"<event id='evt'>"
		"<input name='x' />"
		"<apply scope='idy'>"
			"<set field='value' to='evt.x.s32' />"
		"</apply>"
	"</event>"
"</screenplay>";

static const SkScriptNAnswer scriptTests[]  = {
	{	"alpha+alpha", SkType_String, 0, 0, "abcabc" },
	{	"0 ? Math.sin(0) : 1", SkType_Int, 1 },
	{	"intArray[4]", SkType_Unknown },
	{	"emptyArray[4]", SkType_Unknown },
	{	"idx", SkType_Int, 2 },
	{	"intArray.length", SkType_Int, 3 },
	{	"intArray.values[0]", SkType_Int, 1 },
	{	"intArray[0]", SkType_Int, 1 },
	{	"idx.value", SkType_Int, 2 },
	{	"alpha.value", SkType_String, 0, 0, "abc" },
	{	"alpha", SkType_String, 0, 0, "abc" },
	{	"alpha.value+alpha.value", SkType_String, 0, 0, "abcabc" },
	{	"alpha+idx", SkType_String, 0, 0, "abc2" },
	{	"idx+alpha", SkType_String, 0, 0, "2abc" },
	{	"intArray[idx]", SkType_Int, 6 },
	{	"alpha.slice(1,2)", SkType_String, 0, 0, "b" },
	{	"alpha.value.slice(1,2)", SkType_String, 0, 0, "b" },
	{	"Math.sin(0)", SkType_Float, 0, SkIntToScalar(0) },
	{	"testRect.left+2", SkType_Float, 0, SkIntToScalar(3) },
	{	"0 ? intArray[0] : 1", SkType_Int, 1 },
	{	"0 ? intArray.values[0] : 1", SkType_Int, 1 },
	{	"0 ? idx : 1", SkType_Int, 1 },
	{	"0 ? idx.value : 1", SkType_Int, 1 },
	{	"0 ? alpha.slice(1,2) : 1", SkType_Int, 1 },
	{	"0 ? alpha.value.slice(1,2) : 1", SkType_Int, 1 },
	{ "idy", SkType_Int, 3 }
};

#define SkScriptNAnswer_testCount	SK_ARRAY_COUNT(scriptTests)

void SkAnimatorScript2::UnitTest() {
#if defined(SK_SUPPORT_UNITTEST)
	SkAnimator animator;
	SkASSERT(animator.decodeMemory(scriptTestSetup, sizeof(scriptTestSetup)-1));
	SkEvent evt;
	evt.setString("id", "evt");
	evt.setS32("x", 3);
	animator.doUserEvent(evt);
	// set up animator with memory script above, then run value tests
	for (int index = 0; index < SkScriptNAnswer_testCount; index++) {
		SkAnimatorScript2 engine(*animator.fMaker, NULL, scriptTests[index].fType);
		SkScriptValue2 value;
		const char* script = scriptTests[index].fScript;
		bool success = engine.evaluateScript(&script, &value);
		if (success == false) {
			SkASSERT(scriptTests[index].fType == SkType_Unknown);
			continue;
		}
		SkASSERT(value.fType == ToOpType(scriptTests[index].fType));
		SkScalar error;
		switch (value.fType) {
			case SkOperand2::kS32:
				SkASSERT(value.fOperand.fS32 == scriptTests[index].fIntAnswer);
				break;
			case SkOperand2::kScalar:
				error = SkScalarAbs(value.fOperand.fScalar - scriptTests[index].fScalarAnswer);
				SkASSERT(error < SK_Scalar1 / 10000);
				break;
			case SkOperand2::kString:
				SkASSERT(value.fOperand.fString->equals(scriptTests[index].fStringAnswer));
				break;
			default:
				SkASSERT(0);
		}
	}
#endif
}

#endif

