/*
Class: Mindscape.core
  A class that provides management of modules for the Mindscape JavaScript application architecture framework.
*/
Mindscape.core = Mindscape.core || (function (undefined) {
    var moduleData = {}, self = {

        /*
        Property: modules
        The dictionary property for storing registered modules.
        */
        modules: moduleData,

        /*
        Function: register
        The function for registering a new module.

        Parameters:
        moduleSelector - The string that identifies the module's container DOM element.
        constructor - The function that is used as the module's constructor.

        See:
        <unregister>
        */
        register: function (moduleSelector, constructor) {
            var hub, module;

            if (typeof moduleSelector === 'string' && typeof constructor === 'function') {
                hub = Mindscape.hub.create(self, moduleSelector);

                if (hub.container && hub.container.length) {
                    module = constructor(hub);

                    module.hub = hub;

                    if (module.construct && typeof module.construct === 'function' && module.destruct && typeof module.destruct === 'function') {
                        moduleData[moduleSelector] = module;

                        return module;
                    } else {
                        Mindscape.util.log(1, 'Register Module \'' + moduleSelector + '\': FAILED: module instance has no construct or destruct functions');
                    }
                } /*else {
                    Mindscape.util.log(1, 'Register Module \'' + moduleSelector + '\': FAILED: hub could not find the module container');
                }*/
            } else {
                Mindscape.util.log(1, 'Register Module \'' + moduleSelector + '\': FAILED: one or more arguments are wrong type');
            }

            return undefined;
        },

        /*
        Function: unregister
        The function for unregistering an existing module.

        Parameters:
        moduleId - The string that identifies the module's container HTML element.

        See:
        <register>
        */
        unregister: function (moduleId) {
            var module = moduleData[moduleId];

            if (module && module.destruct && typeof module.destruct === 'function') {
                module.destruct();
                module = null;
            } else {
                Mindscape.util.log(1, 'Unregister Module \'' + moduleId + '\': FAILED: module does not exist or has already been unregistered');
            }
        },

        /*
        Function: start
        The function for starting an existing module.

        Parameters:
        moduleId - The string that identifies the module's container HTML element.

        See:
        <stop>
        */
        start: function (moduleId) {
            var module = moduleData[moduleId];

            if (module && module.construct && typeof module.construct === 'function') {
                module.construct();
            }
        },

        /*
        Function: startAll
        The function for starting all existing modules.

        See:
        <stopAll>
        */
        startAll: function () {
            var moduleId;

            for (moduleId in moduleData) {
                if (moduleData.hasOwnProperty(moduleId)) {
                    this.start(moduleId);
                }
            }
        },

        /*
        Function: stop
        The function for stopping an existing module.

        Parameters:
        moduleId - The string that identifies the module's container HTML element.

        See:
        <start>
        */
        stop: function (moduleId) {
            var module = moduleData[moduleId];

            if (module && module.destruct && typeof module.destruct === 'function') {
                module.destruct();
            } else {
                Mindscape.util.log(1, 'Stop Module \'' + moduleId + '\': FAILED: module does not exist or has not been started');
            }
        },

        /*
        Function: stopAll
        The function for stopping all existing modules.

        See:
        <startAll>
        */
        stopAll: function () {
            var moduleId;

            for (moduleId in moduleData) {
                if (moduleData.hasOwnProperty(moduleId)) {
                    this.stop(moduleId);
                }
            }
        },

        /*
        Function: registerEvents
        The function for registering event observers.

        Parameters:
        events - The events to be registered for observation.
        moduleId - The module where the events exist.

        See:
        <triggerEvent>
        <unregisterEvents>
        */
        registerEvents: function (events, moduleId) {
            if (Mindscape.util.isObject(events) && moduleId) {
                var module = moduleData[moduleId];

                if (module) {
                    module.events = events;
                } else {
                    Mindscape.util.log(1, 'Register Events \'' + moduleId + '\': FAILED: module does not exist');
                }
            } else {
                Mindscape.util.log(1, 'Register Events: FAILED: one or more arguments are wrong type');
            }
        },

        /*
        Function: triggerEvent
        The function for triggering an event observer.

        Parameters:
        event - The event to be triggered for notification.

        See:
        <registerEvents>
        <unregisterEvents>
        */
        triggerEvent: function (event) {
            if (Mindscape.util.isObject(event) && event.type) {
                var mod;

                for (mod in moduleData) {
                    if (moduleData.hasOwnProperty(mod)) {
                        mod = moduleData[mod];
                        if (mod.events && mod.events[event.type]) {
                            mod.events[event.type](event.data);
                        }
                    }
                }
            }
        },

        /*
        Function: unregisterEvents
        The function for unregistering event observers.

        Parameters:
        events - The events to be unregistered from observation.
        moduleId - The module where the events existed.

        See:
        <registerEvents>
        <triggerEvent>
        */
        unregisterEvents: function (events, moduleId) {
            if (Mindscape.util.isArray(events) && moduleId && (module = moduleData[moduleId]) && module.events) {
                delete module.events;
            }
        }
    };

    return self;
})();
