/* 
 * Copyright 2006 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
#include "FunctionObject.h"
#include <kjs/array_object.h>

using namespace KJS;

const ClassInfo FunctionObject::info = {"Function", 0, 0, 0};

class CallFunction : public FunctionObject {
public:
	CallFunction(): FunctionObject("call") {
	}

    virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args) {
		// Copied from FunctionProtoFunc::callAsFunction()
		JSValue *thisArg = args[0];
		JSObject *func = thisObj;

		if (!func->implementsCall())
			return throwError(exec, TypeError);

		JSObject *callThis;
		if (thisArg->isUndefinedOrNull())
			callThis = exec->dynamicInterpreter()->globalObject();
		else
			callThis = thisArg->toObject(exec);

		return func->call(exec, callThis, args.copyTail());
	}
};

class ApplyFunction  : public FunctionObject {
public:
	ApplyFunction(): FunctionObject("apply") {
	}

    virtual JSValue *callAsFunction(ExecState *exec, JSObject *thisObj, const List &args) {
		// Copied from FunctionProtoFunc::callAsFunction()
		JSObject *func = thisObj;
		if (!func->implementsCall())
			return throwError(exec, TypeError);

		JSValue *thisArg = args[0];
		JSObject *applyThis;
		if (thisArg->isUndefinedOrNull())
			applyThis = exec->dynamicInterpreter()->globalObject();
		else
			applyThis = thisArg->toObject(exec);

		JSValue *argArray = args[1];
		List applyArgs;
		if (!argArray->isUndefinedOrNull()) {
			if (!argArray->isObject(&ArrayInstance::info))
				return throwError(exec, TypeError);

			JSObject *argArrayObj = static_cast<JSObject *>(argArray);
			unsigned int length = argArrayObj->get(exec, lengthPropertyName)->toUInt32(exec);
			for (unsigned int i = 0; i < length; ++i) {
				applyArgs.append(argArrayObj->get(exec,i));
			}
		}
		return func->call(exec, applyThis, applyArgs);
	}
};


static UString makeFunctionString(const UString& name) {
	return "\nfunction " + name + "() {\n    [native code]\n}\n";
}

JSValue *FunctionObject::getter(ExecState* exec, JSObject* obj, const Identifier& propertyName, const PropertySlot& slot) {
	if (propertyName.ustring() == "toString") {
		return new ToStringFunction();
	} else if (propertyName.ustring() == "call") {
		return new CallFunction();
	} else if (propertyName.ustring() == "apply") {
		return new ApplyFunction();
	}
	return jsUndefined();
}

FunctionObject::FunctionObject(const UString& name): name(name) {
}

bool FunctionObject::getOwnPropertySlot(ExecState *exec, const Identifier& propertyName, PropertySlot& slot) {
	if (propertyName.ustring() == "toString") {
		slot.setCustom(this, getter);
		return true;
	}
	if (propertyName.ustring() == "call") {
		slot.setCustom(this, getter);
		return true;
	}
	if (propertyName.ustring() == "apply") {
		slot.setCustom(this, getter);
		return true;
	}
	return false;
}

bool FunctionObject::canPut(ExecState *exec, const Identifier &propertyName) const {
	return false;
}

void FunctionObject::put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr) {
}

bool FunctionObject::deleteProperty(ExecState *exec, const Identifier &propertyName) {
	return false;
}

JSValue *FunctionObject::defaultValue(ExecState *exec, JSType hint) const {
	return jsString(makeFunctionString(name));
}

bool FunctionObject::implementsCall() const {
	return true;
}

// ToStringFunction

ToStringFunction::ToStringFunction(): FunctionObject("toString") {
}

JSValue *ToStringFunction::callAsFunction(ExecState *exec, JSObject *thisObj, const List &args) {
	if (!thisObj) {
		return throwError(exec, TypeError);
	}
	return jsString(thisObj->toString(exec));
}
