(function() {
    /**
    * PopupManager is a object that manages all the popup available on a page. All config object that are registered 
    * with this object will be sorted by priority, check for availability and displayed on the page.  All popups processed
    * by the manager geeds to implement <a href="SALEM.widget.PopupBase.html">SALEM.widget.PopupBase</a>
    * @module controllers 
    * @namespace SALEM.controllers
    * @class SALEM.controllers.PopupManager
    * @constructor
    */
    SALEM.namespace("controllers");

    SALEM.controllers.PopupManager = function() {

        /**
        * The popup that will be shown first no matter its prority.
        *
        * @property mandatoryTop
        * @private
        */
        var mandatoryTop = null;

        /**
        * Array holding the config objects.
        *
        * @property configs
        * @private
        */
        var configs = [];

        /**
        * This function handles the determining by priority which
        * array element is greater than the other.
        *
        * @property compare
        * @private
        */
        var compare = function(a, b) {

            if (a.priority < b.priority) {
                return -1;
            }
            if (a.priority > b.priority) {
                return 1;
            }
            if (a.priority === b.priority) {
                return 0;
            }
        };

        /**
        * This function handles calls to google Analytics event tracking.
        *
        * @property googlEvents
        * @private
        */
        var googlEvents = function() {

            return {
                sendGoogleEvent: function(label, message) {
                    try {
                        if (typeof pageTracker !== "undefined" &
						    pageTracker !== null) {
                            pageTracker._trackEvent('popups', message, label);
                        }
                    }
                    catch (Error) {
                    }

                }

            };
        } ();

        return {
            /**
            * This function inserts the passed in cinfig into the configs array.
            *
            * @method RegisterConfig
            * @param  {Config} config A object literal that represents the configuration of a popup. Must have mandatoryTop as a 
            * property
            */
            RegisterConfig: function(config) {

                if (config.isMandatoryTop) {  //Set the madatory variable equal to the config
                    mandatoryTop = config;
                }
                else {//Insert the configuration object into the array else
                    configs.push(config);
                }

            },

            /**
            * Show the first available popup.
            *
            * @method show
            * @param  {int} index (Optional) This is an parameter that is used by the method. You should not use it.
            */
            show: function(index) {

                //Ensure that the index is not null or undefined. If it is then
                //set it to 0 
                if (typeof index === "undefined" ||
				   index === null) {

                    //Sort all of the registered configs               
                    configs.sort(compare);

                    //If there is a mandetory top config then
                    //insert it into first element of the configs array  
                    if (mandatoryTop) {
                        configs.unshift(mandatoryTop);
                    }
                    index = 0;
                }


                if (index < configs.length) {
                    var pMGR = this;

                    //Load the required includes the popup needs
                    var loader = new YAHOO.util.YUILoader();
                    var moduleNames = [];
                    for (var reqCounter = 0; reqCounter < configs[index].require.length; reqCounter++) {
                        if (configs[index].require[reqCounter].fullpath != null) {
                            loader.addModule(configs[index].require[reqCounter]);
                        }
                        moduleNames.push(configs[index].require[reqCounter].name);
                    }


                    loader.require(moduleNames);

                    loader.onFailure = function(msg, xhrobj) {
                        googlEvents.sendGoogleEvent(configs[index].name, "Failure To Load Requirements: " + msg);
                    };

                    loader.onSuccess = function() {
                    
                        //Call the popup's create method
                        var popup = configs[index].create();

                        //Check to see if the popup can be shown
                        if (popup.isAvailable()) {
                            popup.show();
                        }
                        else {
                            //Show the next popup described in the config array
                            pMGR.show(++index);
                        }

                    };

                    loader.insert();

                }
            }
        };
    } ();
})();

