/*
    This file is part of the WebKit open source project.
    This file has been generated by generate-bindings.pl. DO NOT MODIFY!

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.
*/

#include "config.h"
#include "JSNavigator.h"

#include "JSMimeTypeArray.h"
#include "JSPluginArray.h"
#include "KURL.h"
#include "MimeTypeArray.h"
#include "Navigator.h"
#include "PluginArray.h"
#include <runtime/Error.h>
#include <runtime/JSString.h>
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

ASSERT_CLASS_FITS_IN_CELL(JSNavigator);

/* Hash table */

static const HashTableValue JSNavigatorTableValues[15] =
{
    { "appCodeName", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorAppCodeName), (intptr_t)0 },
    { "appName", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorAppName), (intptr_t)0 },
    { "appVersion", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorAppVersion), (intptr_t)0 },
    { "language", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorLanguage), (intptr_t)0 },
    { "userAgent", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorUserAgent), (intptr_t)0 },
    { "platform", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorPlatform), (intptr_t)0 },
    { "plugins", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorPlugins), (intptr_t)0 },
    { "mimeTypes", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorMimeTypes), (intptr_t)0 },
    { "product", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorProduct), (intptr_t)0 },
    { "productSub", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorProductSub), (intptr_t)0 },
    { "vendor", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorVendor), (intptr_t)0 },
    { "vendorSub", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorVendorSub), (intptr_t)0 },
    { "cookieEnabled", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorCookieEnabled), (intptr_t)0 },
    { "onLine", DontDelete|ReadOnly, (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsNavigatorOnLine), (intptr_t)0 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSNavigatorTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 511, JSNavigatorTableValues, 0 };
#else
    { 36, 31, JSNavigatorTableValues, 0 };
#endif

/* Hash table for prototype */

static const HashTableValue JSNavigatorPrototypeTableValues[5] =
{
    { "javaEnabled", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsNavigatorPrototypeFunctionJavaEnabled), (intptr_t)0 },
    { "getStorageUpdates", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsNavigatorPrototypeFunctionGetStorageUpdates), (intptr_t)0 },
    { "registerProtocolHandler", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsNavigatorPrototypeFunctionRegisterProtocolHandler), (intptr_t)3 },
    { "registerContentHandler", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsNavigatorPrototypeFunctionRegisterContentHandler), (intptr_t)3 },
    { 0, 0, 0, 0 }
};

static JSC_CONST_HASHTABLE HashTable JSNavigatorPrototypeTable =
#if ENABLE(PERFECT_HASH_SIZE)
    { 31, JSNavigatorPrototypeTableValues, 0 };
#else
    { 9, 7, JSNavigatorPrototypeTableValues, 0 };
#endif

const ClassInfo JSNavigatorPrototype::s_info = { "NavigatorPrototype", 0, &JSNavigatorPrototypeTable, 0 };

JSObject* JSNavigatorPrototype::self(ExecState* exec, JSGlobalObject* globalObject)
{
    return getDOMPrototype<JSNavigator>(exec, globalObject);
}

bool JSNavigatorPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticFunctionSlot<JSObject>(exec, &JSNavigatorPrototypeTable, this, propertyName, slot);
}

bool JSNavigatorPrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticFunctionDescriptor<JSObject>(exec, &JSNavigatorPrototypeTable, this, propertyName, descriptor);
}

const ClassInfo JSNavigator::s_info = { "Navigator", 0, &JSNavigatorTable, 0 };

JSNavigator::JSNavigator(NonNullPassRefPtr<Structure> structure, JSDOMGlobalObject* globalObject, PassRefPtr<Navigator> impl)
    : DOMObjectWithGlobalPointer(structure, globalObject)
    , m_impl(impl)
{
}

JSNavigator::~JSNavigator()
{
    forgetDOMObject(this, impl());
}

JSObject* JSNavigator::createPrototype(ExecState* exec, JSGlobalObject* globalObject)
{
    return new (exec) JSNavigatorPrototype(JSNavigatorPrototype::createStructure(globalObject->objectPrototype()));
}

bool JSNavigator::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
    return getStaticValueSlot<JSNavigator, Base>(exec, &JSNavigatorTable, this, propertyName, slot);
}

bool JSNavigator::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
{
    return getStaticValueDescriptor<JSNavigator, Base>(exec, &JSNavigatorTable, this, propertyName, descriptor);
}

JSValue jsNavigatorAppCodeName(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSNavigator* castedThis = static_cast<JSNavigator*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    Navigator* imp = static_cast<Navigator*>(castedThis->impl());
    JSValue result = jsString(exec, imp->appCodeName());
    return result;
}

JSValue jsNavigatorAppName(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSNavigator* castedThis = static_cast<JSNavigator*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    Navigator* imp = static_cast<Navigator*>(castedThis->impl());
    JSValue result = jsString(exec, imp->appName());
    return result;
}

JSValue jsNavigatorAppVersion(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSNavigator* castedThis = static_cast<JSNavigator*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    Navigator* imp = static_cast<Navigator*>(castedThis->impl());
    JSValue result = jsString(exec, imp->appVersion());
    return result;
}

JSValue jsNavigatorLanguage(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSNavigator* castedThis = static_cast<JSNavigator*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    Navigator* imp = static_cast<Navigator*>(castedThis->impl());
    JSValue result = jsString(exec, imp->language());
    return result;
}

JSValue jsNavigatorUserAgent(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSNavigator* castedThis = static_cast<JSNavigator*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    Navigator* imp = static_cast<Navigator*>(castedThis->impl());
    JSValue result = jsString(exec, imp->userAgent());
    return result;
}

JSValue jsNavigatorPlatform(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSNavigator* castedThis = static_cast<JSNavigator*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    Navigator* imp = static_cast<Navigator*>(castedThis->impl());
    JSValue result = jsString(exec, imp->platform());
    return result;
}

JSValue jsNavigatorPlugins(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSNavigator* castedThis = static_cast<JSNavigator*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    Navigator* imp = static_cast<Navigator*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->plugins()));
    return result;
}

JSValue jsNavigatorMimeTypes(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSNavigator* castedThis = static_cast<JSNavigator*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    Navigator* imp = static_cast<Navigator*>(castedThis->impl());
    JSValue result = toJS(exec, castedThis->globalObject(), WTF::getPtr(imp->mimeTypes()));
    return result;
}

JSValue jsNavigatorProduct(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSNavigator* castedThis = static_cast<JSNavigator*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    Navigator* imp = static_cast<Navigator*>(castedThis->impl());
    JSValue result = jsString(exec, imp->product());
    return result;
}

JSValue jsNavigatorProductSub(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSNavigator* castedThis = static_cast<JSNavigator*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    Navigator* imp = static_cast<Navigator*>(castedThis->impl());
    JSValue result = jsString(exec, imp->productSub());
    return result;
}

JSValue jsNavigatorVendor(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSNavigator* castedThis = static_cast<JSNavigator*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    Navigator* imp = static_cast<Navigator*>(castedThis->impl());
    JSValue result = jsString(exec, imp->vendor());
    return result;
}

JSValue jsNavigatorVendorSub(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSNavigator* castedThis = static_cast<JSNavigator*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    Navigator* imp = static_cast<Navigator*>(castedThis->impl());
    JSValue result = jsString(exec, imp->vendorSub());
    return result;
}

JSValue jsNavigatorCookieEnabled(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSNavigator* castedThis = static_cast<JSNavigator*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    Navigator* imp = static_cast<Navigator*>(castedThis->impl());
    JSValue result = jsBoolean(imp->cookieEnabled());
    return result;
}

JSValue jsNavigatorOnLine(ExecState* exec, JSValue slotBase, const Identifier&)
{
    JSNavigator* castedThis = static_cast<JSNavigator*>(asObject(slotBase));
    UNUSED_PARAM(exec);
    Navigator* imp = static_cast<Navigator*>(castedThis->impl());
    JSValue result = jsBoolean(imp->onLine());
    return result;
}

JSValue JSC_HOST_CALL jsNavigatorPrototypeFunctionJavaEnabled(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSNavigator::s_info))
        return throwError(exec, TypeError);
    JSNavigator* castedThisObj = static_cast<JSNavigator*>(asObject(thisValue));
    Navigator* imp = static_cast<Navigator*>(castedThisObj->impl());


    JSC::JSValue result = jsBoolean(imp->javaEnabled());
    return result;
}

JSValue JSC_HOST_CALL jsNavigatorPrototypeFunctionGetStorageUpdates(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSNavigator::s_info))
        return throwError(exec, TypeError);
    JSNavigator* castedThisObj = static_cast<JSNavigator*>(asObject(thisValue));
    Navigator* imp = static_cast<Navigator*>(castedThisObj->impl());

    imp->getStorageUpdates();
    return jsUndefined();
}

JSValue JSC_HOST_CALL jsNavigatorPrototypeFunctionRegisterProtocolHandler(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSNavigator::s_info))
        return throwError(exec, TypeError);
    JSNavigator* castedThisObj = static_cast<JSNavigator*>(asObject(thisValue));
    Navigator* imp = static_cast<Navigator*>(castedThisObj->impl());
    ExceptionCode ec = 0;
    const UString& scheme = args.at(0).toString(exec);
    const UString& url = args.at(1).toString(exec);
    const UString& title = args.at(2).toString(exec);

    imp->registerProtocolHandler(scheme, url, title, ec);
    setDOMException(exec, ec);
    return jsUndefined();
}

JSValue JSC_HOST_CALL jsNavigatorPrototypeFunctionRegisterContentHandler(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UNUSED_PARAM(args);
    if (!thisValue.inherits(&JSNavigator::s_info))
        return throwError(exec, TypeError);
    JSNavigator* castedThisObj = static_cast<JSNavigator*>(asObject(thisValue));
    Navigator* imp = static_cast<Navigator*>(castedThisObj->impl());
    ExceptionCode ec = 0;
    const UString& mimeType = args.at(0).toString(exec);
    const UString& url = args.at(1).toString(exec);
    const UString& title = args.at(2).toString(exec);

    imp->registerContentHandler(mimeType, url, title, ec);
    setDOMException(exec, ec);
    return jsUndefined();
}

JSC::JSValue toJS(JSC::ExecState* exec, JSDOMGlobalObject* globalObject, Navigator* object)
{
    return getDOMObjectWrapper<JSNavigator>(exec, globalObject, object);
}
Navigator* toNavigator(JSC::JSValue value)
{
    return value.inherits(&JSNavigator::s_info) ? static_cast<JSNavigator*>(asObject(value))->impl() : 0;
}

}
