/*
    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"

#if ENABLE(MEDIA_STREAM)

#include "JSMediaStream.h"

#include "EventNames.h"
#include "ExceptionCode.h"
#include "JSDOMBinding.h"
#include "JSDOMConstructor.h"
#include "JSEventListener.h"
#include "JSMediaStream.h"
#include "JSMediaStreamTrack.h"
#include "MediaStream.h"
#include "MediaStreamTrack.h"
#include "URL.h"
#include "WebCoreJSClientData.h"
#include <runtime/Error.h>
#include <runtime/JSArray.h>
#include <runtime/JSString.h>
#include <wtf/GetPtr.h>

using namespace JSC;

namespace WebCore {

// Functions

JSC::EncodedJSValue JSC_HOST_CALL jsMediaStreamPrototypeFunctionGetAudioTracks(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsMediaStreamPrototypeFunctionGetVideoTracks(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsMediaStreamPrototypeFunctionGetTracks(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsMediaStreamPrototypeFunctionGetTrackById(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsMediaStreamPrototypeFunctionAddTrack(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsMediaStreamPrototypeFunctionRemoveTrack(JSC::ExecState*);
JSC::EncodedJSValue JSC_HOST_CALL jsMediaStreamPrototypeFunctionClone(JSC::ExecState*);

// Attributes

JSC::EncodedJSValue jsMediaStreamId(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsMediaStreamActive(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
JSC::EncodedJSValue jsMediaStreamOnactive(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSMediaStreamOnactive(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsMediaStreamOninactive(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSMediaStreamOninactive(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsMediaStreamOnaddtrack(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSMediaStreamOnaddtrack(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsMediaStreamOnremovetrack(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSMediaStreamOnremovetrack(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);
JSC::EncodedJSValue jsMediaStreamConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::PropertyName);
bool setJSMediaStreamConstructor(JSC::ExecState*, JSC::EncodedJSValue, JSC::EncodedJSValue);

class JSMediaStreamPrototype : public JSC::JSNonFinalObject {
public:
    typedef JSC::JSNonFinalObject Base;
    static JSMediaStreamPrototype* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure)
    {
        JSMediaStreamPrototype* ptr = new (NotNull, JSC::allocateCell<JSMediaStreamPrototype>(vm.heap)) JSMediaStreamPrototype(vm, globalObject, structure);
        ptr->finishCreation(vm);
        return ptr;
    }

    DECLARE_INFO;
    static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
    {
        return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
    }

private:
    JSMediaStreamPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
        : JSC::JSNonFinalObject(vm, structure)
    {
    }

    void finishCreation(JSC::VM&);
};

typedef JSDOMConstructor<JSMediaStream> JSMediaStreamConstructor;

static inline EncodedJSValue constructJSMediaStream1(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    auto* castedThis = jsCast<JSMediaStreamConstructor*>(state->callee());
    ASSERT(castedThis);
    ScriptExecutionContext* context = castedThis->scriptExecutionContext();
    if (UNLIKELY(!context))
        return throwConstructorScriptExecutionContextUnavailableError(*state, throwScope, "MediaStream");
    auto object = MediaStream::create(*context);
    return JSValue::encode(toJSNewlyCreated(state, castedThis->globalObject(), WTFMove(object)));
}

static inline EncodedJSValue constructJSMediaStream2(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    auto* castedThis = jsCast<JSMediaStreamConstructor*>(state->callee());
    ASSERT(castedThis);
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    auto stream = JSMediaStream::toWrapped(state->uncheckedArgument(0));
    if (UNLIKELY(!stream))
        return throwArgumentTypeError(*state, throwScope, 0, "stream", "MediaStream", nullptr, "MediaStream");
    ScriptExecutionContext* context = castedThis->scriptExecutionContext();
    if (UNLIKELY(!context))
        return throwConstructorScriptExecutionContextUnavailableError(*state, throwScope, "MediaStream");
    auto object = MediaStream::create(*context, *stream);
    return JSValue::encode(toJSNewlyCreated(state, castedThis->globalObject(), WTFMove(object)));
}

static inline EncodedJSValue constructJSMediaStream3(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    auto* castedThis = jsCast<JSMediaStreamConstructor*>(state->callee());
    ASSERT(castedThis);
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    auto tracks = toRefPtrNativeArray<MediaStreamTrack, JSMediaStreamTrack>(*state, state->uncheckedArgument(0));
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    ScriptExecutionContext* context = castedThis->scriptExecutionContext();
    if (UNLIKELY(!context))
        return throwConstructorScriptExecutionContextUnavailableError(*state, throwScope, "MediaStream");
    auto object = MediaStream::create(*context, WTFMove(tracks));
    return JSValue::encode(toJSNewlyCreated(state, castedThis->globalObject(), WTFMove(object)));
}

#if ENABLE(MEDIA_STREAM)
template<> EncodedJSValue JSC_HOST_CALL JSMediaStreamConstructor::construct(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    size_t argsCount = std::min<size_t>(1, state->argumentCount());
    if (argsCount == 0) {
#if ENABLE(MEDIA_STREAM)
        return constructJSMediaStream1(state);
#endif
    }
    if (argsCount == 1) {
        JSValue distinguishingArg = state->uncheckedArgument(0);
#if ENABLE(MEDIA_STREAM)
        if (distinguishingArg.isObject() && asObject(distinguishingArg)->inherits(JSMediaStream::info()))
            return constructJSMediaStream2(state);
#endif
#if ENABLE(MEDIA_STREAM)
        if (hasIteratorMethod(*state, distinguishingArg))
            return constructJSMediaStream3(state);
#endif
    }
    return throwVMTypeError(state, throwScope);
}
#endif

template<> JSValue JSMediaStreamConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
{
    return JSEventTarget::getConstructor(vm, &globalObject);
}

template<> void JSMediaStreamConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
{
    putDirect(vm, vm.propertyNames->prototype, JSMediaStream::prototype(vm, &globalObject), DontDelete | ReadOnly | DontEnum);
    putDirect(vm, vm.propertyNames->name, jsNontrivialString(&vm, String(ASCIILiteral("MediaStream"))), ReadOnly | DontEnum);
    putDirect(vm, vm.propertyNames->length, jsNumber(0), ReadOnly | DontEnum);
}

template<> const ClassInfo JSMediaStreamConstructor::s_info = { "MediaStream", &Base::s_info, 0, CREATE_METHOD_TABLE(JSMediaStreamConstructor) };

/* Hash table for prototype */

static const HashTableValue JSMediaStreamPrototypeTableValues[] =
{
    { "constructor", DontEnum, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMediaStreamConstructor), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSMediaStreamConstructor) } },
    { "id", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMediaStreamId), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "active", ReadOnly | CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMediaStreamActive), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(0) } },
    { "onactive", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMediaStreamOnactive), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSMediaStreamOnactive) } },
    { "oninactive", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMediaStreamOninactive), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSMediaStreamOninactive) } },
    { "onaddtrack", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMediaStreamOnaddtrack), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSMediaStreamOnaddtrack) } },
    { "onremovetrack", CustomAccessor, NoIntrinsic, { (intptr_t)static_cast<PropertySlot::GetValueFunc>(jsMediaStreamOnremovetrack), (intptr_t) static_cast<PutPropertySlot::PutValueFunc>(setJSMediaStreamOnremovetrack) } },
    { "getAudioTracks", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsMediaStreamPrototypeFunctionGetAudioTracks), (intptr_t) (0) } },
    { "getVideoTracks", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsMediaStreamPrototypeFunctionGetVideoTracks), (intptr_t) (0) } },
    { "getTracks", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsMediaStreamPrototypeFunctionGetTracks), (intptr_t) (0) } },
    { "getTrackById", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsMediaStreamPrototypeFunctionGetTrackById), (intptr_t) (1) } },
    { "addTrack", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsMediaStreamPrototypeFunctionAddTrack), (intptr_t) (1) } },
    { "removeTrack", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsMediaStreamPrototypeFunctionRemoveTrack), (intptr_t) (1) } },
    { "clone", JSC::Function, NoIntrinsic, { (intptr_t)static_cast<NativeFunction>(jsMediaStreamPrototypeFunctionClone), (intptr_t) (0) } },
};

const ClassInfo JSMediaStreamPrototype::s_info = { "MediaStreamPrototype", &Base::s_info, 0, CREATE_METHOD_TABLE(JSMediaStreamPrototype) };

void JSMediaStreamPrototype::finishCreation(VM& vm)
{
    Base::finishCreation(vm);
    reifyStaticProperties(vm, JSMediaStreamPrototypeTableValues, *this);
    JSVMClientData& clientData = *static_cast<JSVMClientData*>(vm.clientData);
    putDirect(vm, clientData.builtinNames().getTracksPrivateName(), JSFunction::create(vm, globalObject(), 0, String(), jsMediaStreamPrototypeFunctionGetTracks), ReadOnly | DontEnum);
}

const ClassInfo JSMediaStream::s_info = { "MediaStream", &Base::s_info, 0, CREATE_METHOD_TABLE(JSMediaStream) };

JSMediaStream::JSMediaStream(Structure* structure, JSDOMGlobalObject& globalObject, Ref<MediaStream>&& impl)
    : JSEventTarget(structure, globalObject, WTFMove(impl))
{
}

JSObject* JSMediaStream::createPrototype(VM& vm, JSGlobalObject* globalObject)
{
    return JSMediaStreamPrototype::create(vm, globalObject, JSMediaStreamPrototype::createStructure(vm, globalObject, JSEventTarget::prototype(vm, globalObject)));
}

JSObject* JSMediaStream::prototype(VM& vm, JSGlobalObject* globalObject)
{
    return getDOMPrototype<JSMediaStream>(vm, globalObject);
}

EncodedJSValue jsMediaStreamId(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSMediaStream*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "MediaStream", "id");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsStringWithCache(state, impl.id());
    return JSValue::encode(result);
}


EncodedJSValue jsMediaStreamActive(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSMediaStream*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "MediaStream", "active");
    }
    auto& impl = castedThis->wrapped();
    JSValue result = jsBoolean(impl.active());
    return JSValue::encode(result);
}


EncodedJSValue jsMediaStreamOnactive(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSMediaStream*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "MediaStream", "onactive");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().activeEvent));
}


EncodedJSValue jsMediaStreamOninactive(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSMediaStream*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "MediaStream", "oninactive");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().inactiveEvent));
}


EncodedJSValue jsMediaStreamOnaddtrack(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSMediaStream*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "MediaStream", "onaddtrack");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().addtrackEvent));
}


EncodedJSValue jsMediaStreamOnremovetrack(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    UNUSED_PARAM(thisValue);
    JSValue decodedThisValue = JSValue::decode(thisValue);
    auto* castedThis = jsDynamicCast<JSMediaStream*>(decodedThisValue);
    if (UNLIKELY(!castedThis)) {
        return throwGetterTypeError(*state, throwScope, "MediaStream", "onremovetrack");
    }
    UNUSED_PARAM(state);
    return JSValue::encode(eventHandlerAttribute(castedThis->wrapped(), eventNames().removetrackEvent));
}


EncodedJSValue jsMediaStreamConstructor(ExecState* state, EncodedJSValue thisValue, PropertyName)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    JSMediaStreamPrototype* domObject = jsDynamicCast<JSMediaStreamPrototype*>(JSValue::decode(thisValue));
    if (UNLIKELY(!domObject))
        return throwVMTypeError(state, throwScope);
    return JSValue::encode(JSMediaStream::getConstructor(state->vm(), domObject->globalObject()));
}

bool setJSMediaStreamConstructor(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    JSValue value = JSValue::decode(encodedValue);
    JSMediaStreamPrototype* domObject = jsDynamicCast<JSMediaStreamPrototype*>(JSValue::decode(thisValue));
    if (UNLIKELY(!domObject)) {
        throwVMTypeError(state, throwScope);
        return false;
    }
    // Shadowing a built-in constructor
    return domObject->putDirect(state->vm(), state->propertyNames().constructor, value);
}

bool setJSMediaStreamOnactive(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue value = JSValue::decode(encodedValue);
    UNUSED_PARAM(thisValue);
    JSMediaStream* castedThis = jsDynamicCast<JSMediaStream*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "MediaStream", "onactive");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().activeEvent, value);
    return true;
}


bool setJSMediaStreamOninactive(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue value = JSValue::decode(encodedValue);
    UNUSED_PARAM(thisValue);
    JSMediaStream* castedThis = jsDynamicCast<JSMediaStream*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "MediaStream", "oninactive");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().inactiveEvent, value);
    return true;
}


bool setJSMediaStreamOnaddtrack(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue value = JSValue::decode(encodedValue);
    UNUSED_PARAM(thisValue);
    JSMediaStream* castedThis = jsDynamicCast<JSMediaStream*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "MediaStream", "onaddtrack");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().addtrackEvent, value);
    return true;
}


bool setJSMediaStreamOnremovetrack(ExecState* state, EncodedJSValue thisValue, EncodedJSValue encodedValue)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue value = JSValue::decode(encodedValue);
    UNUSED_PARAM(thisValue);
    JSMediaStream* castedThis = jsDynamicCast<JSMediaStream*>(JSValue::decode(thisValue));
    if (UNLIKELY(!castedThis)) {
        return throwSetterTypeError(*state, throwScope, "MediaStream", "onremovetrack");
    }
    setEventHandlerAttribute(*state, *castedThis, castedThis->wrapped(), eventNames().removetrackEvent, value);
    return true;
}


JSValue JSMediaStream::getConstructor(VM& vm, const JSGlobalObject* globalObject)
{
    return getDOMConstructor<JSMediaStreamConstructor>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
}

EncodedJSValue JSC_HOST_CALL jsMediaStreamPrototypeFunctionGetAudioTracks(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSMediaStream*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "MediaStream", "getAudioTracks");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSMediaStream::info());
    auto& impl = castedThis->wrapped();
    JSValue result = jsArray(state, castedThis->globalObject(), impl.getAudioTracks());
    return JSValue::encode(result);
}

EncodedJSValue JSC_HOST_CALL jsMediaStreamPrototypeFunctionGetVideoTracks(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSMediaStream*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "MediaStream", "getVideoTracks");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSMediaStream::info());
    auto& impl = castedThis->wrapped();
    JSValue result = jsArray(state, castedThis->globalObject(), impl.getVideoTracks());
    return JSValue::encode(result);
}

EncodedJSValue JSC_HOST_CALL jsMediaStreamPrototypeFunctionGetTracks(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSMediaStream*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "MediaStream", "getTracks");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSMediaStream::info());
    auto& impl = castedThis->wrapped();
    JSValue result = jsArray(state, castedThis->globalObject(), impl.getTracks());
    return JSValue::encode(result);
}

EncodedJSValue JSC_HOST_CALL jsMediaStreamPrototypeFunctionGetTrackById(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSMediaStream*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "MediaStream", "getTrackById");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSMediaStream::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    auto trackId = state->uncheckedArgument(0).toWTFString(state);
    RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
    JSValue result = toJS(state, castedThis->globalObject(), impl.getTrackById(WTFMove(trackId)));
    return JSValue::encode(result);
}

EncodedJSValue JSC_HOST_CALL jsMediaStreamPrototypeFunctionAddTrack(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSMediaStream*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "MediaStream", "addTrack");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSMediaStream::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    auto track = JSMediaStreamTrack::toWrapped(state->uncheckedArgument(0));
    if (UNLIKELY(!track))
        return throwArgumentTypeError(*state, throwScope, 0, "track", "MediaStream", "addTrack", "MediaStreamTrack");
    impl.addTrack(*track);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsMediaStreamPrototypeFunctionRemoveTrack(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSMediaStream*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "MediaStream", "removeTrack");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSMediaStream::info());
    auto& impl = castedThis->wrapped();
    if (UNLIKELY(state->argumentCount() < 1))
        return throwVMError(state, throwScope, createNotEnoughArgumentsError(state));
    auto track = JSMediaStreamTrack::toWrapped(state->uncheckedArgument(0));
    if (UNLIKELY(!track))
        return throwArgumentTypeError(*state, throwScope, 0, "track", "MediaStream", "removeTrack", "MediaStreamTrack");
    impl.removeTrack(*track);
    return JSValue::encode(jsUndefined());
}

EncodedJSValue JSC_HOST_CALL jsMediaStreamPrototypeFunctionClone(ExecState* state)
{
    VM& vm = state->vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    UNUSED_PARAM(throwScope);
    JSValue thisValue = state->thisValue();
    auto castedThis = jsDynamicCast<JSMediaStream*>(thisValue);
    if (UNLIKELY(!castedThis))
        return throwThisTypeError(*state, throwScope, "MediaStream", "clone");
    ASSERT_GC_OBJECT_INHERITS(castedThis, JSMediaStream::info());
    auto& impl = castedThis->wrapped();
    JSValue result = toJS(state, castedThis->globalObject(), impl.clone());
    return JSValue::encode(result);
}

void JSMediaStream::visitChildren(JSCell* cell, SlotVisitor& visitor)
{
    auto* thisObject = jsCast<JSMediaStream*>(cell);
    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
    Base::visitChildren(thisObject, visitor);
    thisObject->wrapped().visitJSEventListeners(visitor);
}

#if ENABLE(BINDING_INTEGRITY)
#if PLATFORM(WIN)
#pragma warning(disable: 4483)
extern "C" { extern void (*const __identifier("??_7MediaStream@WebCore@@6B@")[])(); }
#else
extern "C" { extern void* _ZTVN7WebCore11MediaStreamE[]; }
#endif
#endif

JSC::JSValue toJSNewlyCreated(JSC::ExecState*, JSDOMGlobalObject* globalObject, Ref<MediaStream>&& impl)
{

#if ENABLE(BINDING_INTEGRITY)
    void* actualVTablePointer = *(reinterpret_cast<void**>(impl.ptr()));
#if PLATFORM(WIN)
    void* expectedVTablePointer = reinterpret_cast<void*>(__identifier("??_7MediaStream@WebCore@@6B@"));
#else
    void* expectedVTablePointer = &_ZTVN7WebCore11MediaStreamE[2];
#if COMPILER(CLANG)
    // If this fails MediaStream does not have a vtable, so you need to add the
    // ImplementationLacksVTable attribute to the interface definition
    static_assert(__is_polymorphic(MediaStream), "MediaStream is not polymorphic");
#endif
#endif
    // If you hit this assertion you either have a use after free bug, or
    // MediaStream has subclasses. If MediaStream has subclasses that get passed
    // to toJS() we currently require MediaStream you to opt out of binding hardening
    // by adding the SkipVTableValidation attribute to the interface IDL definition
    RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer);
#endif
    return createWrapper<MediaStream>(globalObject, WTFMove(impl));
}

JSC::JSValue toJS(JSC::ExecState* state, JSDOMGlobalObject* globalObject, MediaStream& impl)
{
    return wrap(state, globalObject, impl);
}

MediaStream* JSMediaStream::toWrapped(JSC::JSValue value)
{
    if (auto* wrapper = jsDynamicCast<JSMediaStream*>(value))
        return &wrapper->wrapped();
    return nullptr;
}

}

#endif // ENABLE(MEDIA_STREAM)
