/*
 * The contents of this file are subject to the Netscape Public
 * License Version 1.1 (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.mozilla.org/NPL/

 * Software distributed under the License is distributed on an "AS
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * rights and limitations under the License.

 * The Original Code is Rhino code, released
 * May 6, 1999.

 * The Initial Developer of the Original Code is Netscape
 * Communications Corporation.  Portions created by Netscape are
 * Copyright (C) 1997-1999 Netscape Communications Corporation. All
 * Rights Reserved.

 * Contributor(s): 

 * Alternatively, the contents of this file may be used under the
 * terms of the GNU Public License (the "GPL"), in which case the
 * provisions of the GPL are applicable instead of those above.
 * If you wish to allow use of your version of this file only
 * under the terms of the GPL and not to allow others to use your
 * version of this file under the NPL, indicate your decision by
 * deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL.  If you do not delete
 * the provisions above, a recipient may use your version of this
 * file under either the NPL or the GPL.
 */
/* Header file */
#include "js-objectadapter.h"
#include "js-scriptruntime.h"
#include "js-nativeboolean.h"

/* Internal data */
const jsString_t JSNativeBoolean::className = "Boolean";

/* Procedures */
void JSNativeBoolean::finishInit(JSContext * cx, JSScriptable * scope, JSFunctionObject * ctor, JSScriptable * proto)
{
    class BooleanAdapter:public JSObjectAdapter {
      public:
        JS_OA_DefineFunction(toString, JSNativeBoolean) JS_OA_DefineFunction(valueOf, JSNativeBoolean)
    };
    static jsFunction_t functions[] = {
#define	ItemAdapter(name, clazz, length)	\
			{ #name,  clazz::name, length }
        ItemAdapter(toString, BooleanAdapter, 0),
        ItemAdapter(valueOf, BooleanAdapter, 0),
#undef	Item
    };

    ((JSScriptableObject *) proto)->defineFunctionProperties(cx, className, TableSize(functions), functions, JS_PA_DontEnum);
}
jsVal_t JSNativeBoolean::jsConstructor(JSContext * cx, int numArgs, jsVal_t * args, JSFunction * ctorObj, jsBool_t inNewExpr)
{
    jsBool_t b = numArgs >= 1 ? JSScriptRuntime::toBoolean(cx, args[0])
            : FALSE;

    if (inNewExpr) {
        // new Boolean(val) creates a new boolean object.
        return JS_OBJECT_TO_VAL(new(cx) JSNativeBoolean(b));
    }

    // Boolean(val) converts val to a boolean.
    return b ? JS_VAL_TRUE : JS_VAL_FALSE;
}

void JSNativeBoolean::defineClass(JSContext * cx, JSScriptable * scope)
{
    JSScriptable *proto = new(cx) JSNativeBoolean();

    JSScriptableObject::defineClass(cx, scope, proto, jsConstructor, finishInit);
}

jsVal_t JSNativeBoolean::jsFunction_toString(JSContext * cx)
{
    return JS_STRING_TO_VAL(JS_NewGCString(cx, booleanValue ? (jsString_t) "true" : (jsString_t) "false"));
}

jsVal_t JSNativeBoolean::jsFunction_valueOf(JSContext * cx)
{
    return JS_BOOLEAN_TO_VAL(booleanValue);
}

jsBool_t JSNativeBoolean::isInstanceOf(const jsString_t className)
{
    if (className == JSNativeBoolean::className)
        return TRUE;
    return JSScriptableObject::isInstanceOf(className);
}

jsString_t JSNativeBoolean::getClassName(JSContext * cx)
{
    return JSNativeBoolean::className;
}

jsVal_t JSNativeBoolean::getDefaultValue(JSContext * cx, jsType_t typeHint)
{
    // This is actually non-ECMA, but will be proposed
    // as a change in round 2.
    if (typeHint == JS_T_Boolean) {
        return JS_BOOLEAN_TO_VAL(booleanValue);
    }
    return JSScriptableObject::getDefaultValue(cx, typeHint);
}

JSNativeBoolean::JSNativeBoolean()
{
    booleanValue = FALSE;
}

JSNativeBoolean::JSNativeBoolean(jsBool_t b)
{
    booleanValue = b;
}
