{% from "macros.tmpl" import license %}
{{ license() }}

#include "config.h"
#include "V8{{namespace}}ElementWrapperFactory.h"

#include "{{namespace}}Names.h"
#include "bindings/core/v8/CustomElementWrapper.h"
{% for tag in tags|sort if tag.has_js_interface %}
#include "bindings/core/v8/V8{{tag.interface}}.h"
{% endfor %}
{% for tag in tags|sort if tag.has_js_interface %}
#include "core/{{namespace|lower}}/{{tag.js_interface}}.h"
{% endfor %}
#include "core/{{namespace|lower}}/{{fallback_js_interface}}.h"
#include "core/dom/Document.h"
#include "core/frame/Settings.h"
#include "gen/sky/platform/RuntimeEnabledFeatures.h"
#include "wtf/StdLibExtras.h"

namespace blink {

using namespace {{namespace}}Names;

typedef v8::Handle<v8::Object> (*Create{{namespace}}ElementWrapperFunction)({{namespace}}Element*, v8::Handle<v8::Object> creationContext, v8::Isolate*);

static v8::Handle<v8::Object> create{{namespace}}ElementWrapper({{namespace}}Element*, v8::Handle<v8::Object>, v8::Isolate*)
{
    ASSERT_NOT_REACHED();
    return v8::Handle<v8::Object>();
}
{% for js_interface, list in tags|sort|selectattr('has_js_interface')|groupby('js_interface') %}
{% filter enable_conditional(list[0].Conditional) %}
static v8::Handle<v8::Object> create{{js_interface}}Wrapper({{namespace}}Element* element, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
{
    {% if list[0].runtimeEnabled %}
    if (!RuntimeEnabledFeatures::{{list[0].runtimeEnabled}}Enabled())
        return createV8{{namespace}}FallbackWrapper(to{{fallback_js_interface}}(element), creationContext, isolate);
    {% endif %}
    return wrap(static_cast<{{js_interface}}*>(element), creationContext, isolate);
}
{% endfilter %}
{% endfor %}

v8::Handle<v8::Object> createV8{{namespace}}Wrapper({{namespace}}Element* element, v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
{
    typedef HashMap<StringImpl*, Create{{namespace}}ElementWrapperFunction> FunctionMap;
    DEFINE_STATIC_LOCAL(FunctionMap, map, ());
    if (map.isEmpty()) {
    {% for tag in tags|sort %}
    {% filter enable_conditional(tag.Conditional) %}
        map.set({{tag|symbol}}Tag.localName().impl(), create{{tag.js_interface}}Wrapper);
    {% endfilter %}
    {% endfor %}
    }

    Create{{namespace}}ElementWrapperFunction createWrapperFunction = map.get(element->localName().impl());
    if (createWrapperFunction == create{{namespace}}ElementWrapper)
        createWrapperFunction = createV8{{namespace}}DirectWrapper;
    if (element->isCustomElement())
        return CustomElementWrapper<{{namespace}}Element, V8{{namespace}}Element>::wrap(element, creationContext, isolate, createWrapperFunction);

    if (createWrapperFunction)
        return createWrapperFunction(element, creationContext, isolate);
    {% if fallback_js_interface == namespace + 'Element' %}
    return V8{{fallback_js_interface}}::createWrapper(element, creationContext, isolate);
    {% else %}
    return wrap(to{{fallback_js_interface}}(element), creationContext, isolate);
    {% endif %}
}

const WrapperTypeInfo* findWrapperTypeFor{{namespace}}TagName(const AtomicString& name)
{
    typedef HashMap<StringImpl*, const WrapperTypeInfo*> NameTypeMap;
    DEFINE_STATIC_LOCAL(NameTypeMap, map, ());
    if (map.isEmpty()) {
        // FIXME: This seems wrong. We should list every interface here, not
        // just the ones that have specialized JavaScript interfaces.
        {% for tag in tags|sort if tag.has_js_interface %}
        {% filter enable_conditional(tag.Conditional) %}
        map.set({{tag|symbol}}Tag.localName().impl(), &V8{{tag.js_interface}}::wrapperTypeInfo);
        {% endfilter %}
        {% endfor %}
    }

    if (const WrapperTypeInfo* result = map.get(name.impl()))
        return result;

    return &V8{{fallback_js_interface}}::wrapperTypeInfo;
}

}
