/// class PD.Manage.ModuleZoneContents
// using PD.Web.UI.Controls.Control

PD.Manage.ModuleZoneContents = PD.Web.UI.Controls.Control.extend({

    //===================================
    // FIELDS
    //===================================

    _modules: null,

    //===================================
    // PROPERTIES
    //===================================

    get_modules: function () {
        return this._modules;
    },

    //===================================
    // EVENT HANDLERS
    //===================================

    onInit: function (e) {
        this._modules = new PD.Manage.ModuleCollection();
    },

    template: function (e) {
        return "<div class='-pd-manage-module-contents'></div>";
    },

    onActivate: function (e) {

        PD.context.get_global().get_events().subscribe("Module:Request", this.onModuleRequest, this);
        PD.context.get_global().get_events().subscribe("Module:Focus", this.onModuleFocus, this);
        PD.context.get_global().get_events().subscribe("Module:Unload", this.onModuleUnload, this);
        PD.context.get_global().get_events().subscribe("Module:Unloaded", this.onModuleUnloaded, this);
        PD.context.get_global().get_events().subscribe("Module:UnloadAll", this.onModuleUnloadAll, this);

        PDJS.Manage.EventsHub.moduleChangeDataSubscribe((e) => {
            if (e.id != undefined && e.newId != undefined) {
                this.get_modules().changeId(e.id, e.newId);
            }
        });

    },

    onModuleRequest: function (e) {

        var module = null;
        var moduleId = PD.Type.isString(e) ? e : e.id;
        var isModuleLoaded = this.get_modules().findById(moduleId) != null;

        if (!isModuleLoaded) {
            this.onModuleLoad(e)
        }
        else {
            this.onModuleFocus(moduleId);
        }

    },

    onModuleLoad: function (e) {

        var moduleType = PD.Type.getType(e.script);

        if (moduleType) {
            this.onModuleCreateInstance(moduleType, e);
        }
        else {
            this.onModuleError("Unable to locate module.");
        }

    },

    onModuleUnload: function (e) {

        var module = this.get_modules().findById(e);

        if (module != null) {
            module.unload();
        }

    },

    onModuleUnloaded: function (e) {

        let moduleId = e.data("id");
        let module = this.get_modules().findById(moduleId);
        let fallback = null;

        if (module != null) {
            fallback = this.get_modules().getFallback(moduleId);
            this.get_modules().remove(moduleId);
        }

        if (fallback != null) {
            window.location.hash = fallback.data("route");
        }
        else {
            window.location.hash = "";
            this.showMessageScreen("No modules are currently loaded.<br/><br/>Click here to open the <a href='#/module/overview'>Overview Module</a>.");
        }

    },

    onModuleFocus: function (id) {

        var module = this.get_modules().findById(id);

        if (module != null) {

            this.get_node().children().hide();

            module.focus();

        }

    },

    onModuleCreateInstance: function (moduleType, moduleArguments) {

        var instance = null;

        this.showMessageScreen("<img src='" + PD.Path.toMisc("loading-48x48.gif") + "' style='vertical-align:middle;' />&nbsp;Loading...");

        instance = new moduleType($.extend(true, {
            ready: (module) => {
                this.onModuleReady(module, moduleArguments);
            },
            error: (module, message) => {
                this.onModuleError(module, message);
            }
        }, moduleArguments));

    },

    onModuleReady: function (module, moduleArguments) {

        this.get_modules().add(module);

        PD.context.get_global().get_events().publish("Module:Load", {
            module: module,
            moduleInfo: moduleArguments
        });

        this.get_node().children().hide();

        this.get_children().add(module);

        this.hideMessageScreen();

    },

    onModuleError: function (module, message) {

        Jade.UI.MessageDialog.open({
            dialogStyle: Jade.UI.MessageDialogStyle.Error,
            dialogButtons: Jade.UI.MessageDialogButtonStyle.OK,
            allowClose: true,
            title: "Module Error",
            message: message ? message : "Unable to load module."
        });

        this.hideMessageScreen();

        setTimeout(() => {
            module != null ?
                module.unload() : window.location.hash = "overview";
        }, 100);
        
    },

    //===================================
    // PUBLIC METHODS
    //===================================

    showMessageScreen: function (message) {

        if (message == null) {
            return;
        }

        message = [
            "<div class='module-message'>",
                "<table>",
                    "<tr>",
                        "<td>",
                            "<span class='message'>",
                            $.isArray(message) ? message.join("") : message,
                            "</span>",
                        "</td>",
                    "</tr>",
                "</table>",
            "</div>"
        ].join("")

        this.get_node().append(message);

    },

    hideMessageScreen: function () {
        this.get_node().children("DIV.module-message").remove();
    }

});