#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

