/// 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);
    },

    onModuleRequest: function (e) {

        var module = null,
            moduleId = PD.Type.isString(e) ? e : e.id,
            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();
        }

    },

    onModuleUnloadAll: function (e) {

        var that = this,
            saved = [],
            unsaved = [];

        this._modules.each(function (module) {
            if (!module.data("hasChanges")) {
                saved[saved.length] = module;
            }
            else {
                unsaved[unsaved.length] = module;
            }
        });
        
        _.each(saved, function (module) {
            module.unload();
            that.onModuleUnloaded(module);
        });
        
        if (unsaved.length > 0) {

            PD.Web.UI.MessageDialog.warn({
                title: "Unsaved Changes Detected",
                message: "The application found some open modules with unsaved changes. Should the applicaiton leave these modules or close them and loses unsaved changes?",
                ok: function (e) {

                }
            });

        }

    },

    onModuleUnloaded: function (e) {

        var moduleId = e.data("id"),
            module = this.get_modules().findById(moduleId),
            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 that = this,
            instance = null;

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

        instance = new moduleType($.extend(true, {
            ready: function (module) {
                that.onModuleReady(module, moduleArguments);
            },
            error: function (module, message) {
                that.onModuleError(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 (message) {

        window.location.hash = "#";

        PD.Web.UI.MessageDialog.error({
            title: "Module Error",
            message: message ? message : "Unable to load module."
        });

        this.hideMessageScreen();

    },

    //===================================
    // 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();
    }

});