"use strict";
// Copyright (c) Jupyter Development Team.
// Distributed under the terms of the Modified BSD License.
Object.defineProperty(exports, "__esModule", { value: true });
// ES6 Promise polyfill
require('es6-promise').polyfill();
require("font-awesome/css/font-awesome.css");
require("@phosphor/widgets/style/index.css");
require("@jupyter-widgets/controls/css/widgets.built.css");
// Element.prototype.matches polyfill
if (Element && !Element.prototype.matches) {
    var proto = Element.prototype;
    proto.matches = proto.matchesSelector ||
        proto.mozMatchesSelector || proto.msMatchesSelector ||
        proto.oMatchesSelector || proto.webkitMatchesSelector;
}
var htmlmanager_1 = require("./htmlmanager");
var _ = require("underscore");
// Load json schema validator
var Ajv = require('ajv');
var widget_state_schema = require('@jupyter-widgets/schema').v2.state;
var widget_view_schema = require('@jupyter-widgets/schema').v2.view;
// BEGIN: Ajv config for json-schema draft 4, from https://github.com/epoberezkin/ajv/releases/tag/5.0.0
// This can be deleted when the schema is moved to draft 6
var ajv = new Ajv({
    meta: false,
    extendRefs: true,
    unknownFormats: 'ignore',
});
var metaSchema = require('ajv/lib/refs/json-schema-draft-04.json');
ajv.addMetaSchema(metaSchema);
ajv._opts.defaultMeta = metaSchema.id;
// optional, using unversioned URI is out of spec, see https://github.com/json-schema-org/json-schema-spec/issues/216
ajv._refs['http://json-schema.org/schema'] = 'http://json-schema.org/draft-04/schema';
// Optionally you can also disable keywords defined in draft-06
ajv.removeKeyword('propertyNames');
ajv.removeKeyword('contains');
ajv.removeKeyword('const');
// END: Ajv config for json-schema draft 4, from https://github.com/epoberezkin/ajv/releases/tag/5.0.0
var model_validate = ajv.compile(widget_state_schema);
var view_validate = ajv.compile(widget_view_schema);
// `LoadInlineWidget` is the main function called on load of the web page.
// All it does is inserting a <script> tag for requirejs in the case it is not
// available and call `renderInlineWidgets`
function loadInlineWidgets(event) {
    var loadRequire = new Promise(function (resolve, reject) {
        if (window.requirejs) {
            resolve();
        }
        else {
            // If requirejs is not on the page on page load, load it from cdn.
            var scriptjs = require('scriptjs');
            scriptjs('https://unpkg.com/requirejs/require.js', function () {
                resolve();
            });
        }
    });
    loadRequire.then(function () {
        // Render inline widgets
        renderInlineWidgets(event);
    });
}
// `renderInlineWidget` will call `renderManager(element, tag)` on each <script>
// tag of mime type
//     "application/vnd.jupyter.widget-state+json"
// contained in `event.element`.
function renderInlineWidgets(event) {
    var element = event.target || document;
    var tags = element.querySelectorAll('script[type="application/vnd.jupyter.widget-state+json"]');
    for (var i = 0; i != tags.length; ++i) {
        renderManager(element, tags[i]);
    }
}
exports.renderInlineWidgets = renderInlineWidgets;
// Function `renderManager(element, tag)` creates a widget embed manager for the
// specified <script> tag (which must have mime type)
//     "application/vnd.jupyter.widget-state+json".
// Then it performs a look up of all script tags under the specified DOM
// element with the mime type
//     "application/vnd.jupyter.widget-view+json".
// For each one of these <script> tags, if the contained json specifies a model id
// known to the aforementioned manager, it is replaced with a view of the model.
//
// Besides, if the view script tag has an <img> sibling DOM node with class `jupyter-widget`,
// the <img> tag is deleted.
function renderManager(element, tag) {
    var widgetStateObject = JSON.parse(tag.innerHTML);
    var valid = model_validate(widgetStateObject);
    if (!valid) {
        console.log(model_validate.errors);
    }
    var manager = new htmlmanager_1.HTMLManager();
    manager.set_state(widgetStateObject).then(function (models) {
        var tags = element.querySelectorAll('script[type="application/vnd.jupyter.widget-view+json"]');
        var _loop_1 = function (i) {
            // TODO: validate view schema
            var viewtag = tags[i];
            var widgetViewObject = JSON.parse(viewtag.innerHTML);
            var valid_1 = view_validate(widgetViewObject);
            if (!valid_1) {
                console.error('View state has errors.', view_validate.errors);
            }
            var model_id = widgetViewObject.model_id;
            var model = _.find(models, function (item) {
                return item.model_id == model_id;
            });
            if (model !== undefined) {
                if (viewtag.previousElementSibling &&
                    viewtag.previousElementSibling.matches('img.jupyter-widget')) {
                    viewtag.parentElement.removeChild(viewtag.previousElementSibling);
                }
                var widgetTag = document.createElement('div');
                widgetTag.className = 'widget-subarea';
                viewtag.parentElement.insertBefore(widgetTag, viewtag);
                manager.display_model(undefined, model, { el: widgetTag });
            }
        };
        for (var i = 0; i != tags.length; ++i) {
            _loop_1(i);
        }
    });
}
// Prevent the embedder to be defined twice.
if (!window._jupyter_widget_embedder) {
    window._jupyter_widget_embedder = true;
    window.addEventListener('load', loadInlineWidgets);
}
