var Popups = ( function ( ) {
	var popup_counter = 0;
    var popupElements = {
		br: new Element("br")
		,ok: new Element("input", { type: "submit", styles: { width: 70 }})
		,cancel: new Element("input", { type: "submit", styles: { width: 70 }})
		,close: new Element( "span", { "class": "popupClose", title: "Close" })
        ,maximize: new Element("span", { "class": "popupMaximize", title: "Maximize" })
        ,minimize: new Element("span", { "class": "popupMinimize displayNone", title: "Minimize" })
		,overflowDiv: new Element( "div", { styles: { overflow : "auto" }})
	};

	var loadForm = function (container, info, ph, loadingPanel, obj, title, functionCall, containerWrapper) {
        ph.adopt ( info );
        container.store("InfoID", info.id);
        info.replaces(loadingPanel);
        Popups.resizeShadow(container);
        ph.dispose();
		if (obj["loadjs"]) { loadJS( { code: obj["loadjs"] } ); } else { loadJS( { code: obj["js"] } ); }
        if (functionCall) { eval(functionCall); }
        EFX.dragContainerInit( title, containerWrapper );
		if( container.postShowPopup ) { container.postShowPopup(obj); };
	};

	return {
		br : function ( ) {
			return popupElements["br"].clone(true, true);
		},
		close : function ( ) {
			return popupElements["close"].clone(true, true);
		},
		overflowDiv : function ( ) {
			return popupElements["overflowDiv"].clone(true, true);
		},
		/**
	     * IE 6 hack for popups to show over select elements.
	     *
	     * @author Michael Simmons <msimmons@guidepointglobal.com>
	     * @param {Object} popupWrapper - popup wrapper element
	     * @param {Object} popupWrapper - popup element
	     *
	     */
		ieZIndexHack: function(popupWrapper, popup) {
			var browser = BrowserAPI.getBrowser();
			if (browser.type == "IE" && browser.ver == 6) {
	            popupWrapper.adopt(
		            new Element("iframe", {
		            	id: popup.id + "_IE6Hack_Iframe"
		    			,styles: { position: "absolute", width: popup.offsetWidth, height: popup.offsetHeight, top: 0, left: 0, "z-Index": -1 }
		    		})
		    	);
			}
		},

        /**
         * Creates the header div of the Popup.
         *
         * @param {Object} parms {
         *                 container: (required) Popup element.
         *                 titleStyle: css styles for title of popup.
         *                 titleAdopts: elements that title element will adopt.
         *                 headingAdopts: elements that the heading element will adopt.
         *                 titleText: text for title of popup.
         *                 options: {
         *                     background: background of popup header. Defaults to #8ab9d5.
         *                 }
         *         }
         */
		createPopupHeader : function ( parms ) {
            var o = parms["options"] || { background: "#8ab9d5" };
            var titleStyles = (parms["titleStyle"]) ? $extend(parms["titleStyle"], { background : o["background"] + " url(/core/images/gripAll.gif) no-repeat"}) : "";
            var headingDiv = new Element ( "div", { "class" : "popupHeader", styles: o });
            var title = new Element ( "div", { "class": (parms["titleText"]) ? "popupTitle" : "", styles: parms["titleStyle"] }).set("text", parms["titleText"]).inject( headingDiv );

            if ( parms["titleAdopts"] ) {
				for (el in parms["titleAdopts"]) {
					title.adopt( parms["titleAdopts"][el] );
				}
			}

            if ( parms["headingAdopts"] ) {
				for (el in parms["headingAdopts"]) {
					headingDiv.adopt( parms["headingAdopts"][el] );
				}
			}

			var close = popupElements["close"].clone().addEvent("click", function(){
				var colorPicker = $("RTEColorPicker");
				if (colorPicker) colorPicker.destroy();
				parms["container"].parentNode.dispose();
			}).inject(headingDiv);

			var maximize = popupElements["maximize"].clone().addEvent("click", function(){ Popups.maximizePopup(this, parms["container"]); }).inject(headingDiv);
            var minimize = popupElements["minimize"].clone().addEvent("click", function(){ Popups.minimizePopup(this, parms["container"]); }).inject(headingDiv);

			return { headingDiv: headingDiv, title: title, close: close, maximize: maximize, minimize: minimize };
		},

		getPopupHeight : function ( container ) {
			return ($type( container ) == 'string' ) ? $(container).getSize()["size"]["y"] : container.getSize()["size"]["y"];
		},
		getPopupWidth : function ( container ) {
			return ($type( container ) == 'string' ) ? $(container).getSize()["size"]["x"] : container.getSize()["size"]["x"];
		},

        /**
        * Give coordinates if you want popup to be located in the center of the page.
        * Pass in width and height of your popup.
        *
        * @param {Integer} popupWidth - width of element
        * @param {Integer} popupHeight - height of element
        *
        */
        getPopupLocation : function ( popupWidth, popupHeight ) {
            var windowSize = window.getSize(), windowScroll = window.getScroll();
            var leftPosition = (windowScroll.x + ((windowSize.x - popupWidth) / 2)).toInt();
            var topPosition = (windowScroll.y + ((windowSize.y - popupHeight) / 2)).toInt();
            return { left: (leftPosition > 0) ? leftPosition : 0, top: (topPosition > 0) ? topPosition : 0 };
        },

		showAlert : function( message, options, properties ) {
			var mpopup = createModalPopup( options );
			mpopup.build( "alert", message, properties );
		},

		showConfirm : function( message, options, properties ) {
			var mpopup = createModalPopup( options );
			mpopup.build( "confirm", message, properties );
		},

		showModalPopup : function ( container, loadingPanel, info_id, headElements, api_request, options ) {
			new ModalPopup( options, container, headElements ).display( 1 );
			var ph = new Element ( "div", { styles : { height : 0, overflow : "hidden" } } ).inject ( container );
			if ( api_request["url"] ) {
				var options = {
					override_cache : true,
					onComplete : function (obj ) {
						loadForm( container, new Element( "div", { id : info_id } ).set("html", obj["html"] ), ph, loadingPanel, obj, headElements["title"] );
					}
				};
				API.request( api_request["url"], api_request["data"] || {}, options  );
			}
			if ( api_request["info"] ) {
				loadForm( container, api_request["info"], ph, loadingPanel, {}, headElements["title"] );
			}
		},

		showPopup : function ( location, container, loadingPanel, info_id, headElements, api_request, functionCall, is_showing ) {
            if (is_showing == "Y") {
                var popupWrapper = container.parentNode;
            } else {
                var popupWrapper = new Element("div", { id: container.id + "_Wrapper", "class": "popupWrapper", styles: { position: "absolute", top: location.top, left: location.left, "zIndex": 10 } });
                popupWrapper.adopt(container.addClass("popupInfo")).inject(document.body);
            }

            var ph = new Element ( "div", { styles: { height: 0, overflow: "hidden" } } ).inject(container);

            if (is_showing == "Y") { Popups.resizeShadow(container); } else { Popups.dropShadow(container); }

            if ( api_request["url"] ) {
                var options = {
					override_cache : true,
                    onComplete: function(obj){
                        loadForm(container, new Element("div", { id: info_id }).set("html", obj["html"]), ph, loadingPanel, obj, headElements["title"], functionCall, popupWrapper);
                        Popups.addPopupExtras(popupWrapper, headElements["title"]);
                    }
				};
				API.request( api_request["url"], api_request["data"] || {}, options  );
			}

			if ( api_request["info"] ) {
				loadForm( container, api_request["info"], ph, loadingPanel, {}, headElements["title"], functionCall, popupWrapper);
                Popups.addPopupExtras(popupWrapper, headElements["title"]);
			}
		},

        addPopupExtras : function( popupWrapper, dragElement ) {
            var containerPopup = popupWrapper.firstChild;
            var containerInfo = popupWrapper.firstChild.lastChild;
            dragElement.addEvents({
                "mousedown": function(){
                    Popups.bringToFront(popupWrapper);
                    containerPopup.setStyle("opacity", 0.7);
                    containerInfo.addClass("hidden");
                    Popups.resizeShadow(containerPopup);
                },
                "mouseup": function(){
                    containerPopup.setStyle("opacity", 1);
                    containerInfo.removeClass("hidden");
                    Popups.resizeShadow(containerPopup);
                }
            });
        },

		showPrompt : function( message, options, properties ) {
			var mpopup = createModalPopup( options );
			mpopup.build( "prompt", message, properties );
		},

		showIForm : function ( el ) {
			var tmp = el.id.split("_"), advisorID = tmp[1], requestID = (tmp[2]) ? tmp[2] : "-1", icformPopupWidth = 430, icformPopupHeight = 525;
			if (!$("icForm_" + tmp[1]) && !$("icForm_" + advisorID + "_" + requestID)) {
				var icform = new Element("div", { "class" : "icForm", id : "icForm_" + advisorID + "_" + requestID } );
				var headElements = Popups.createPopupHeader({ container: icform, titleAdopt: { "advisorInfo" : new Element("span", { id : "advInfo_" + advisorID + "_" + requestID, "class" : "advInfo" } ) }, titleText: "Create New Invoice" });
				icform.adopt(headElements["headingDiv"]);
				Popups.showPopup(Popups.getPopupLocation(icformPopupWidth, icformPopupHeight), icform, EFX.loadingImg({ inject : icform }), "info_" + advisorID + "_" + requestID, headElements, { url : "/invoices/buildInvoiceForm/"+ $random(1, 100), data : { advisor_id : advisorID, request_id : requestID, "isPopup" : 1 } } );
			} else {
				Popups.showAlert("New invoice form already open for this advisor.");
			}
	    },



       /**
        * gets radio inputs to choose between text and html emails
        *
        * @param {String} composerContainerID - ID of email container
        */
	    getHtmlEmailElements : function(composerContainerID) {
            var emailRadioStyles = { position: "relative", top: 2 }, emailLabelStyles = { padding: "0 10px 0 3px" };

            var textEmailRadio = new Element("input", { id: "textEmailRadio", name: "rteEmail", type: "radio"
            	,styles: emailRadioStyles
            	,events: { click: function(e) {
            		if (this.checked) EmailPopupsAPI.rteUnSet({ el: this, composerContainerID: composerContainerID, event: e });
            	}}
            });

            var textEmailLabel = new Element("label", { id: "textEmailLabel", "for": "textEmailRadio", styles: emailLabelStyles }).set("text", "Text Email");

            var htmlEmailRadio = new Element("input", { id: "htmlEmailRadio", name: "rteEmail", type: "radio", checked: true, selectedBefore: 0
            	, styles: emailRadioStyles
            	, events: { click: function(e) {
            		if (this.checked) EmailPopupsAPI.rteSetup({ el: this, composerContainerID: composerContainerID, event: e });
            	}}
            });
            var htmlEmailLabel = new Element("label", { id: "htmlEmailLabel", "for": "htmlEmailRadio", styles: emailLabelStyles }).set("text", "HTML Email");

            return new Element("span", { "class": "popupOption" }).adopt(textEmailRadio, textEmailLabel, htmlEmailRadio, htmlEmailLabel);
	    },

        showResponseEmail : function ( el, advisorID, requestID, direction ) {
            var location = el.getCoordinates(), responseEmailID = "Response_" + advisorID + "_" + requestID;
            if (!$(responseEmailID)) {
                var responseEmail = new Element("div", { "class": "ViewResponseEmailPopup", id: responseEmailID, styles: { width: 515 }, events: { "mouseleave": function(){ this.parentNode.dispose(); } } });
                var headElements = Popups.createPopupHeader({ container: responseEmail });
                responseEmail.adopt(headElements["close"].setStyles({ top: 2, right: 2 }));
                Popups.showPopup( { top: location.top, left: (direction == "left") ? location.left - 507 : location.left }, responseEmail, EFX.loadingImg ( { inject : responseEmail } ), "info_responseEmail", headElements, {url : "/advisors/getSingleAdvisorResponseEmail/0", data : { AdvisorID: advisorID, RequestID: requestID } } );
            }
        },

	    showClientEventResponse : function ( el, clientID, eventID, eventStatus, direction ) {
	        var location = el.getCoordinates(), eventResponseID = "EventResponse_" + clientID + "_" + eventID;
	        if (!$(eventResponseID)) {
	            var eventResponse = new Element("div", { "class": "ViewEventResponsePopup", id: eventResponseID, styles: { width: 515 }, events: { "mouseleave": function(){ this.parentNode.dispose(); } } });
	            var headElements = Popups.createPopupHeader({ container: eventResponse });
	            eventResponse.adopt(headElements["close"].setStyles({ top: 2, right: 2 }));
	            Popups.showPopup(  { top: location.top, left: (direction == "left") ? location.left - 507 : location.left }, eventResponse, EFX.loadingImg ( { inject : eventResponse } ), "info_eventResponse", headElements, {url : "/events/getEventClientResponse/0", data : { clientID: clientID, eventID: eventID, eventStatus: eventStatus } } );
	        }
	    },

        showMsg : function ( el, event, actionURL, options ) {
            var location = el.getCoordinates(), msgPopup = "Msg_" + options["ID"], opt = { width: (options["min-width"]) ? "" : 545 };
            $extend(opt, options);

            if (!$(msgPopup)) {
                var msgPopup = new Element ( "div", { "class" : opt["Class"], id : "Msg_" + opt["ID"], styles : opt });
                var headElements = Popups.createPopupHeader({ container: msgPopup });
                msgPopup.adopt( headElements["close"] );
                Popups.showPopup( { top: location.top, left: (opt["left"] == "left") ? location.left - ( 400 - el.getSize().x ) : location.left }, msgPopup, EFX.loadingImg ( { inject : msgPopup } ), "info_msgPopup", headElements, {url : actionURL + "/0", data : opt["Data"] } );
            }
        },

        showAdvisorEmail : function ( el, data, direction ) {
        	data["EmailPopupID"] = "showAdvisorEmail_" + data["mailtype"] + "_" + data["ID"] + "_ext";
        	if ($(data["EmailPopupID"])) { return; }
            var elPos = el.getPosition(), elSize = el.getSize(), width = 580;
            var responseEmail = new Element ( "div", { "class" : "ViewResponseEmailPopup", id : data["EmailPopupID"], styles : { width: width, "zIndex": 1000 } } );
            var headElements = Popups.createPopupHeader({ container:  responseEmail, titleStyle: { height: 100}, titleText: "Email" });

            responseEmail.postShowPopup = function () {
                var location = Popups.getPopupLocation(width, responseEmail.getSize().y);
            	responseEmail.setStyles({ top: location.top, left: location.left });
            };
            Popups.showPopup( {} , responseEmail, EFX.loadingImg ( { inject : responseEmail } ), "info_responseEmail", headElements, {url : "/advisors/getAdvisorEmail/0", data : data } );
        },
        /** Adds drop shadow to an element.
         *
         * @author Michael Simmons <msimmons@guidepointglobal.com>
         * @param {Object} el - required.  Can be an element or a to add drop shadow to.
         * @param {Object} options {
                        	left    : {Integer} (default = 4) - The left parameters specify the distance and direction, in
                        	            pixels, to offset the shadow. Zero values position the shadow directly behind the element.
                                        Positive values shift the shadow to the right, while negative values shift the shadow to
                                        the left.
                        	,top     : {Integer} (default = 4) - The top parameters specify the distance and direction, in
                        	            pixels, to offset the shadow. Zero values position the shadow directly behind the element.
                                    	Positive values shift the shadow to the down, while negative values shift the shadow to
                                    	the left.
                        	,blur    : {Integer} (default = 2) - 	The blur parameter specifies the spread, or dispersion, of the
                        	            shadow. Zero produces a sharp shadow, one or two produces a normal shadow, and three or
                        	            four produces a softer shadow. Higher values increase the processing load.
                        	,opacity : {Integer} (default = 0.5) - The opacity parameter should be a decimal value, usually less
                        	            than one. You can use a value	higher than one in special situations, e.g. with extreme
                        	            blurring.
                        	,color   : {String} (default = "black") - Color is specified in the usual manner, with a color name or
                        	            hex value. The color parameter does not apply with transparent images.
                        	,swap    : boolean (default = false) - The swap parameter reverses the stacking order of the original
                        	            and the shadow. This can be used for special effects, like an embossed or engraved look.
         */
        dropShadow : function( el, options ) {
            var browser = BrowserAPI.getBrowser();
            var notForThisBrowser = (browser.type == "IE" && browser.ver <= 6 ) ? "Y" : "";

            if (notForThisBrowser != "Y" ) {
                // Default options
            	var mooThis = ($type(el) == "element") ? el : $(el);
                var mooPosition = mooThis.getPosition();
                var mooSize = mooThis.getSize();
                var mooCoords = mooThis.getCoordinates();
                var mooThisZindex = mooThis.getStyle("zIndex");
                var opt = $extend({ left: 5, top: 5, blur: 2, opacity: .5, color: "black", swap: false }, options);
                var dropShadowZindex = (mooThisZindex == "auto") ? 1 : mooThisZindex; //z-index counter
                var shadows = [];
                var blur = (opt.blur <= 0) ? 0 : opt.blur;
                var opacity = (blur == 0) ? opt.opacity : opt.opacity / (blur * 8);
                var zOriginal = (opt.swap) ? dropShadowZindex : dropShadowZindex + 1;
                var zShadow = (opt.swap) ? dropShadowZindex - 1 : dropShadowZindex;

                // Create ID for shadow
                var shadowId = (mooThis.id) ? mooThis.id + "_dropShadow" : "ds" + (1 + Math.floor(9999 * Math.random()));

                // Modify original element
                mooThis.setProperty("shadowId", shadowId).setStyle("zIndex", zOriginal);

                if (mooThis.getStyle("position") != "absolute") {
                    mooThis.setStyles({ position: "relative", zoom: 1 }); //for IE layout
                }

                // Create first shadow layer
                bgColor = mooThis.getStyle("backgroundColor");

                if (bgColor == "rgba(0, 0, 0, 0)") { bgColor = "transparent"; } //Safari
                if (bgColor != "transparent" || mooThis.getStyle("backgroundImage") != "none" || mooThis.nodeName == "SELECT" || mooThis.nodeName == "INPUT" || mooThis.nodeName == "TEXTAREA") {
                    shadows[0] = new Element("div", {}).setStyle("background", opt.color);
                } else {
                    shadows[0] = mooThis.clone().empty().removeProperties("id", "name", "shadowId", "class").setStyle("background", opt.color);
                }
                shadows[0].addClass("dropShadow").setStyles({ height: mooSize.y, left: blur, opacity: opacity, position: "absolute", top: blur, width: mooSize.x, zIndex: zShadow });

                // Create other shadow layers
                var layers = (8 * blur) + 1;
                for (i = 1; i < layers; i++) {
                    shadows[i] = shadows[0].clone(false);
                }

                // Position layers
                var i = 1;
                var j = blur;
                while (j > 0) {
                    shadows[i].setStyles({ left: j * 2, top: 0 }); //top
                    shadows[i + 1].setStyles({ left: j * 4, top: j * 2 }); //right
                    shadows[i + 2].setStyles({ left: j * 2, top: j * 4 }); //bottom
                    shadows[i + 3].setStyles({ left: 0, top: j * 2 }); //left
                    shadows[i + 4].setStyles({ left: j * 3, top: j }); //top-right
                    shadows[i + 5].setStyles({ left: j * 3, top: j * 3 }); //bottom-right
                    shadows[i + 6].setStyles({ left: j, top: j * 3 }); //bottom-left
                    shadows[i + 7].setStyles({ left: j, top: j }); //top-left
                    i += 8;
                    j--;
                }

                // Create element
                var divShadow = new Element("div", { id: shadowId, "class": "dropShadow", styles: { position: "absolute", left: opt.left - blur, top: opt.top - blur, zIndex: zShadow } });

                // Add layers to element
                for (i = 0; i < layers; i++) {
                    shadows[i].inject(divShadow);
                }

                // Add element to DOM
                divShadow.inject(mooThis, "after");

                // Increment z-index counter
                dropShadowZindex += 2;
            }
        },

        /**
         * Resizes drop shadow on object
         *
         * @author Michael Simmons <msimmons@guidepointglobal.com>
         * @param {Object} el - (required) object that the drop shadow is on.
         *
         */
        resizeShadow : function(el) {
        	var mooThis = ($type(el) == "element") ? el : $(el);
           	var newSize = mooThis.getSize();
           	$(mooThis.id + "_dropShadow").getElements("div.dropShadow").each( function( shadowDiv ) { shadowDiv.setStyles({ "width": newSize.x, "height": newSize.y }); });
        },

        /**
         * Brings object to the front if there are elements stacked on top of each other.
         *
         * @author Michael Simmons <msimmons@guidepointglobal.com>
         * @param {Object} el - (required) element to bring to front.
         *
         */
        bringToFront : function( el ) {
            var popupArr = $$("div.popupWrapper");
            if (popupArr.length > 1) {
                popupArr.each(function(popup){
                    popup.setStyle("zIndex", 1).addEvent("click", function(){
                        Popups.bringToFront(this);
                    });
                });
            }
            el.setStyle("zIndex", 5).removeEvents("click");
        },

        /** Creates a modal Overlay
         *
         * @param {Object} options {
         *                 backgroundColor: {String} (default = "#000000") - Color is specified in the usual manner, with a hex value or color name.
         *                 ,zIndex: {Integer} (default = 5000) - Sets the stack order of an element.
         *                 ,fade: {Integer} (default = 0.7) - The opacity parameter should be a decimal value, less than one.
         *             }
         */
        createModal : function ( options ) {
    		var o = options || {}, defaultOptions = { backgroundColor: "#000000", zIndex: 65555, fade: 0.7 }, modalOptions = {};
            for ( opt in defaultOptions ) { modalOptions[opt] = o[opt] || defaultOptions[opt]; };
            var modal = new Element( "div", {
            	id : "ModalOverlay"
            	,styles : {
            		"background-color": modalOptions["backgroundColor"]
            		,width: window.getScrollWidth()
            		,height: window.getScrollHeight()
            		,position: "absolute"
            		,top: 0
            		,left: 0
            		,opacity: 0
            		,"z-index": modalOptions["zIndex"]
            	}
            }).fade(modalOptions["fade"]).inject(document.body);
    	},

        /* Hides modal Overlay */
        hideModal : function ( ) {
            $("ModalOverlay").fade(0).destroy();
        },

        /** Centers Object when scrolling
         *
         * @author David Rydell
         * @author Michael Simmons <msimmons@guidepointglobal.com>
         * @param {Object} el - element to center.
         *
         */
        centerPopup: function( el ){
            window.addEvent("scroll", function() {
            	if (el && el.getStyle("display") !== "none") {
                    var size = el.getSize()
                        ,position = Popups.getPopupLocation(size.x, size.y)
                        ,morphEfx = new Fx.Morph(el, { duration: "short", transition: Fx.Transitions.Circ.easeIn });

					morphEfx.start({ left: position.left, top: position.top });
                }
             });
        },

        /** Creates a animated popup message
         *
         * @author Michael Simmons <msimmons@guidepointglobal.com>
         * @param {Object} el - (required) element that has the event that invokes this function
         * @param {Integer}/{Object} obj - (required) ID of message object or message object to be insert into popup
         * @param {Object} options - {
         *                     messageDivID: message Div ID
         *                     ,messageDivClass: message Div class
         *                     ,color: font color.  Defaults to "#999999"
         *                     ,font-size: Defaults to 24
         *                     ,width: width of Popup.  Defaults to 50px
         *                     ,height: height of Popup.  Defaults to 120px
         *                     ,padding: Defaults to "20px 10px"
         *                     ,border: Popup border.  Defaults to "1px solid #ce0101"
         *                     ,position: Position of popup. Defaults to absolute
         *                     ,zIndex: Defaults to 101
         *                     ,location: Location where popup will end up
         *                     ,transition: Effect of popup when it becomes visible
         *                     ,duration: Duration of popup when is becomes visible
         *                     ,popupTitle: Popup Title
         *                     ,popupTitleClass: Popup Title Class
         *                 }
         *
         */
        animatedPopupMessage: function ( el, obj, options ) {
            var msg = ($type(obj) == "string") ? $(obj) : obj,
                msgObj = msg.clone(true, true)
                ,elCoords = CoordinatesAPI.getCoordinates(el)
                ,DEFAULT_OPTIONS = {
                    messageDivID: "popupMessage"
                    ,messageDivClass: "popupInfo"
                    ,color: "#999999"
                    ,"font-size": 24
                    ,width: 600
                    ,height: 120
                    ,padding: "90px 0 0 0"
                    ,position: "absolute"
                    ,zIndex: 101
                    ,location: ""
                    ,transition: Fx.Transitions.Sine.easeOut
                    ,duration: 500
                    ,popupTitle: ""
                    ,popupTitleClass: ""
                    ,border: "1px solid #666666"
                };
            $extend(DEFAULT_OPTIONS, options);

            if (!$chk($(msgObj.id + "_" + DEFAULT_OPTIONS["messageDivID"] + "_Wrapper"))) {
                var messageDivWrapper = new Element("div", {
                    id: msgObj.id + "_" + DEFAULT_OPTIONS["messageDivID"] + "_Wrapper", "class": DEFAULT_OPTIONS["messageDivID"] + "_Wrapper popupWrapper"
                    ,styles: { position: DEFAULT_OPTIONS["position"], zIndex: DEFAULT_OPTIONS["zIndex"] }
                });

                var messageDiv = new Element("div", {
                    id: DEFAULT_OPTIONS["messageDivID"], "class": DEFAULT_OPTIONS["messageDivID"]
                    ,styles: { "text-align": "left", background: "#ffffff", color: "#000000", padding: DEFAULT_OPTIONS["padding"], border: DEFAULT_OPTIONS["border"], zIndex: 2 }
                });

                Popups.ieZIndexHack(messageDivWrapper, messageDiv);
    			messageDivWrapper.adopt(messageDiv).inject(document.body);
                Popups.centerPopup(messageDivWrapper);
    			messageDivLocation = Popups.getPopupLocation(DEFAULT_OPTIONS["width"], DEFAULT_OPTIONS["height"]);

                var animateMessageDivWrapper = new Fx.Morph(messageDivWrapper, { duration: DEFAULT_OPTIONS["duration"], transition: DEFAULT_OPTIONS["transition"] });
                animateMessageDivWrapper.start({ left: [elCoords.left, messageDivLocation["left"]], top: [elCoords.top, messageDivLocation["top"]] });

                var animateMessageDiv = new Fx.Morph(messageDiv, { duration: DEFAULT_OPTIONS["duration"], transition: DEFAULT_OPTIONS["transition"] });
                animateMessageDiv.start({ width: [0, DEFAULT_OPTIONS["width"]], height: [0, DEFAULT_OPTIONS["height"]] });

                var ie6HackIframe = $(messageDiv.id + "_IE6Hack_Iframe");
                if (ie6HackIframe) {
                	var animateIE6HackIframe = new Fx.Morph(ie6HackIframe, { duration: DEFAULT_OPTIONS["duration"], transition: DEFAULT_OPTIONS["transition"] });
					animateIE6HackIframe.start({ width: DEFAULT_OPTIONS["width"], height: DEFAULT_OPTIONS["height"] });
				}

                ( function() {
                    var title = new Element("span", { "class": DEFAULT_OPTIONS["popupTitleClass"] }).set("text", DEFAULT_OPTIONS["popupTitle"])
                        ,closeBtn = popupElements["close"].addEvent( "click", function(){ messageDivWrapper.fade("out").destroy(); })
                        ,titleDiv = new Element("div", {}).adopt(title).adopt(closeBtn).inject(messageDiv)
                        ,infoDiv = new Element("div", { styles: { width: DEFAULT_OPTIONS["width"], height: DEFAULT_OPTIONS["height"], padding: 1, overflow: "auto" }}).adopt(msgObj).inject(messageDiv);

                    msgObj.removeClass("displayNone").removeClass("hidden");
                    messageDiv.removeClass("displayNone");
                    Popups.dropShadow(messageDiv);
                 }).delay(DEFAULT_OPTIONS["duration"]);
            }
        },


        /** Creates a popup message as a feedback to inform the user an action has been preformed
         *
         * @author Ben Ng
         * @author Michael Simmons <msimmons@guidepointglobal.com>
         * @param {String} message - (required) message to show in popup.  Can be text or html.
         * @param {Object} options - {
         *                     messageDivID: message Div ID
         *                     ,messageDivClass: message Div class
         *                     ,color: font color.  Defaults to "#999999"
         *                     ,font-size: Defaults to 24
         *                     ,width: width of Popup.  Defaults to 50px
         *                     ,height: height of Popup.  Defaults to 120px
         *                     ,padding: Defaults to "20px 10px"
         *                     ,border: Popup border.  Defaults to "1px solid #ce0101"
         *                     ,position: Position of popup. Defaults to absolute
         *                     ,zIndex: Defaults to 101
         *                     ,destroyMsg: true
         *                     ,fadeDelayTime: Time it takes for popup to start fading.  Defaults to 2500
         *                     ,destroyDelayTime: Time it takes for popup to be destroy from memory.  Defaults to 3000
         *                 }
         *
         */
        popupMessage: function ( message, options ) {
			var opt = {
                messageDivID: "popupMessage"
                ,messageDivClass: "popupInfo"
                ,color: "#999999"
                ,"font-size": 24
                ,width: 600
                ,height: 120
                ,padding: "90px 0 0 0"
                ,position: "absolute"
                ,zIndex: 101
                ,destroyMsg: true
                ,fadeDelayTime: 2500
                ,destroyDelayTime: 3000
            };
            $extend(opt, options);

            var messageDiv = new Element("div", {
                "class" : opt["messageDivClass"] + " displayNone", id : opt["messageDivID"]
				,styles: opt
			}).set("html", message);

            Popups.dropShadow(messageDiv);
			messageDiv.inject(document.body);

            if (opt["location"]) {
                messageDiv.setStyles({ left: opt["location"]["left"], top: opt["location"]["top"] });
            } else {
                Popups.centerPopup(messageDiv);
    			messageDiv.setStyles(Popups.getPopupLocation(opt["width"], opt["height"]));
            }
            messageDiv.removeClass("displayNone");

            if (opt["destroyMsg"]) {
    			(function() {
    				messageDiv.fade("out");
    				(function() { messageDiv.destroy(); }).delay(opt["destroyDelayTime"]);
    			}).delay(opt["fadeDelayTime"]);
            }

        },

        /* Hides popup message */
        hidePopupMessage : function () {
        	$("popupMessage").fade(0).destroy();
        },

 
        sendEmail : function (emailContainer, objectName, objectID) {
        	
        	if ($("emailSubject") && $("emailSubject").value == "") {
        		alert("Email Subject cannot be empty.");
        		return false;
        	}
        	
    		var htmlEmailVars = EmailPopupsAPI.getHtmlEmailVars();
    		var emailTemplateBodyValue = (htmlEmailVars.isHtmlEmail) ? $("emailTemplateBody" + htmlEmailVars.emailTemplateSuffix).contentWindow.document.body.innerHTML : $("emailTemplateBody").value;

    		var saData = EmailPopupsAPI.getSpamAssassinDataObj("emailTemplateBody");

    	    var saOptions = {
    		    onComplete: function(result) {

    		    	EFX.hideOverlay($$('div.SendSelectedSection')[0]);
    				if (result != null && result['isSpam']) {
    					EmailPopupsAPI.runSpamAssassinErrorElements(result);
    					Popups.resizeShadow(emailContainer);
    					return;
    				}

    			    var emailBulkNum = 1, exclude = false, recipients = [];
    				$("emailIndividualsHolder").getElements("input[name=personID]").each(function (obj, index) {
    					recipients[index] = obj.value;
    				});

    			    var data = {
    					  TempID: EmailPopupsAPI.getTempID()
    					, modifiedTemplates: EmailPopupsAPI.getModifiedTemplates()
    					, recipients: recipients
    					, exclude: exclude
    					, emailBulkNum: emailBulkNum
    					, recipientsKey: "GenericEmail"
    					, component: objectName
    					, instanceId: objectID
    					, isHtmlEmail: ($("htmlEmailRadio").checked) ? true : false
    			    };

    			    var PBOptions = {
    			    	updateFunction : function () {
    						
    					},
    					url: "/emails/sendGenericEmail/"
    			    };

    			    $("sendEmailBtn").disabled = "disabled";
    			    var options = {
    			        onComplete: function(res){
    			            if (!res) {
    			                $("progressBar").empty();
    			                $("progressBar").set("text", "No recipients assigned");
    			                $("sendEmailBtn").disabled = "";
    			            }
    			            else {
    			                $("progressBar").empty();
    			                pb = PB.createPB($("progressBar"), 0, {
    			                    "width": 300,
    			                    "height": 25
    			                });
    			                EmailPopupsAPI.getProgress(pb, 0, "Sending...", res["count"], data, PBOptions);
    			            }
    			        }
    			    };
    			    
    			    API.request("/emails/prepareSendEmail/0", data, options);
    			}
    		};

    		EmailPopupsAPI.runSpamAssassinErrorElements();
    		Popups.resizeShadow(emailContainer);

    		if ($('chk_spamassassin_send_anyway').checked) {
    			saOptions.onComplete(null);
    		} else {

    			EFX.showOverlay($$('div.SendSelectedSection')[0]);
    			API.request('/emails/spamAssassinCheck/0', saData, saOptions);
    		}

    	},
        
        /** Creates an modal alert box.
         *
         * @author Michael Simmons <msimmons@guidepointglobal.com>
         * @param {String} alertMsg - (required) message to show in alert popup
         * @param {Object} options - {
         *                     ,background: Alert Box background.  Defaults to "#ffffff"
         *                     ,color: Alert Box font color.  Defaults to "#000000"
         *                     ,alertBoxWidth: Alert Box width.  Defaults to 342px
         *                     ,alertBoxHeight: Alert Box height.  Defaults to 50px
         *                     ,padding: Alert Box padding.  Defaults to "20px 10px"
         *                     ,border: Alert Box border.  Defaults to "1px solid #ce0101"
         *                     ,buttonValue: Value of alert button
         *                     ,okFunction: function that shoule be called when alert button is clicked
         *                 }
         */
        alertPopup: function(alertMsg, options) {
            Popups.createModal();
            var o = $extend({ background: "#ffffff", color: "#000000", alertBoxWidth: 342, alertBoxHeight: 50, padding: "20px 10px", border: "1px solid #ce0101", buttonValue: "Ok", buttonBg: "#ce0101", buttonFontColor: "#ffffff"  }, options)
               ,alertBox = new Element("div", { id: "AlertMsgBox", "class": "AlertMsgBox",
                    styles: {
                        background: o["background"], color: o["color"], width: o["alertBoxWidth"], height: o["alertBoxHeight"], padding: o["padding"], position: "absolute", border: o["border"], zIndex: 70000
                    } })
                    .setStyles(Popups.getPopupLocation( o["alertBoxWidth"], o["alertBoxHeight"] ))
                    .adopt(new Element("p", {}).set("text", alertMsg))
                    .adopt(new Element("input", {
                        id: "okBtn", "class": "submitAlert AlertBoxInput", type: "button", value: o["buttonValue"]
                        ,styles: { background: o["buttonBg"], "color": o["buttonFontColor"]}
                        ,events: {
                            "click": function(){
                                alertBox.fade("out");
                                Popups.hideModal();
                                if (options) eval(options['okFunction']);
                            }
                        }
                    }))
                    .inject(document.body)
                    .fade("in");
    		Popups.centerPopup(alertBox);
        },

        /**
         * Built from an snippet from listSelectorAPI, this function will allow you build a selector menu that is not
         * associated with checkboxes.
         *
         * @author Michael Simmons <msimmons@guidepointglobal.com>
         * @param {Object} el - (required) element hotspot
         * @param {Integer} advisorID - id of advisor
         * @param {Object} options {
         *                     {String} wrapperID: id of popup wrapper
         *                     {Object} selectors: Array of selector Object (see below)
         *                         {
         *                             {String} label: Label of the added selector
         *                             {Integer} count:  Count of the added selector
         *                             {Function} fn: Function executed when the selector is selected
         *                         }
         *                 }
         */
        buildSelectorMenu: function( el, ID, options ) {
            var elCoords = el.getCoordinates(), popupSelectorWrapper = $(options["wrapperID"] + "_selectorPopup_Wrapper");

            // If no popup, creates it
    		if (!popupSelectorWrapper) {
                popupSelectorWrapper = new Element("div", { "id" : options["wrapperID"] + "_selectorPopup_Wrapper"
                    ,styles: { position: "absolute", left: parseInt(elCoords["left"]) - 7, top: parseInt(elCoords["top"]) + parseInt(elCoords["height"]) + 2, zIndex: 10 }
                    ,events: { "mousedown": function(e){
                        var evt = new Event(e);
                    	evt.stop();
                    }}
    			});
                var popupSelector = new Element("div", { "id" : options["wrapperID"] + "_selectorPopup", "class" : "selectorPopup PopupInfo" }).inject(popupSelectorWrapper);

                // Builds the selectors
    			options["selectors"].each( function (item, idx) {
    			    new Element("div", {
                        "class": "clickable selectorItem " + ((idx == 0) ? "last " : "") + ((idx % 2 == 0) ? "even" : "odd")
                        ,events: {
                            "click": function(){
                                popupSelectorHide();
                                eval(item.fn);
                            }
                        }
                    }).appendText(item.label + ((item.count !== null) ? " (" + item.count.numberFormat() + ")" : "")).inject(popupSelector);
    			});

                popupSelectorWrapper.inject(document.body);

        		// Builds the dropShadow
                Popups.dropShadow(popupSelector);
            } else {
                popupSelectorWrapper.removeClass("hidden").setStyles({ left: parseInt(elCoords["left"]) - 7, top: parseInt(elCoords["top"]) + parseInt(elCoords["height"]) + 2 });
                Popups.resizeShadow(popupSelectorWrapper.firstChild);
            }

       		var popupSelectorHide = function() {
    			if (popupSelectorWrapper) {
    				popupSelectorWrapper.addClass("hidden");
    				document.removeEvent("mousedown", function(){ popupSelectorHide(); });
    			}
		    };

            document.addEvent("mousedown", function(){ popupSelectorHide(); });
        },

        /**
         * Maximizes popup size to screen viewpoint
         *
         * @author Michael Simmons <msimmons@guidepointglobal.com>
         * @param {Object} btn - button to invoke this function
         * @param {Object} popup - popup that is being maximized
         *
         */
        maximizePopup: function(btn, popup) {
            var parent = popup.parentNode
                ,winSize = window.getSize()
                ,winPos = window.getScroll()
                ,popupIDSplit = popup.id.split("_");

            btn.addClass("displayNone").nextSibling.removeClass("displayNone");
            popup.setStyles({ width: parseInt(winSize.x) - 2 , height: parseInt(winSize.y) - 2 }).parentNode.setStyles({ top: winPos.y, left: winPos.x });

            if (popupIDSplit[0] == "emailpopup") {
                popup.getElements("div.emailBodyDiv").addClass("bodyMax");
                $(popup.retrieve("InfoID")).setStyles({ height: "95%", overflow: "auto" });
            }
            $(popup.id + "_dropShadow").addClass("displayNone");
        },

        /**
         * Minimizes the height of a popup
         *
         * @author Michael Simmons <msimmons@guidepointglobal.com>
         * @param {Object} btn - button that invokes this function
         * @param {Object} popup - popup that is being maximized
         *
         */
        minimizePopup: function(btn, popup) {
            var originalWidth = popup.retrieve("widthValue")
                ,originalHeight = popup.retrieve("heightValue")
                ,location = Popups.getPopupLocation(originalWidth, originalHeight)
                ,popupIDSplit = popup.id.split("_");

            btn.addClass("displayNone").previousSibling.removeClass("displayNone");
            popup.setStyles({ "width": originalWidth, "height": originalHeight }).parentNode.setStyles(location);

            if (popupIDSplit[0] == "emailpopup") {
                popup.getElements("div.emailBodyDiv").removeClass("bodyMax");
                $(popup.retrieve("InfoID")).setStyles({ height: "", overflow: "" });
            }

            Popups.resizeShadow(popup);
            $(popup.id + "_dropShadow").removeClass("displayNone");
        },

        /**
         * Creates option menu for advisors link
         *
         * @author Michael Simmons <msimmons@guidepointglobal.com>
         * @param {Object} el - Element that has the event that invokes this function
         * @param {Integer} advisorID - ID of advisor
         * @param {String} advisorName - Name of advisor
         *
         */
        showAdvisorOptionMenu: function(el, advisorID, advisorName) {
            var advMenu = $("AdvisorOptionMenuWrapper_" + advisorID), optionImg = $("OptionMenuImg_" + advisorID);

            if (advMenu) {
                if (advMenu.timeoutInt) {
                    clearTimeout(advMenu.timeoutInt);
                    advMenu.timeoutInt = "";
                }
                advMenu.removeClass("displayNone");
            } else {
                var coords = el.parentNode.getCoordinates(), listOptions = []
                    ,list = new Element("ul", {
                        id: "AdvisorOptionMenu_" + advisorID, "class": "advisorOptionMenu"
                        ,styles: { height: 150 }
                        ,events: {
                            click: function(){
                                this.parentNode.addClass("displayNone");
                                el.addClass("displayNone");
                            }
                            ,mouseenter: function() {
                                if (el.timeoutInt) {
                                    clearTimeout(el.timeoutInt);
                                    el.timeoutInt = "";
                                }
                                this.parentNode.removeClass("displayNone");
                                el.removeClass("displayNone");
                            }
                            ,mouseleave: function() {
                                this.parentNode.timeoutInt = setTimeout("Popups.hideAllAdvisorOptionMenuItems(" + advisorID + ")", 200);
                            }
                        }
                    })
                    ,menuOptions = new Hash({
                        advCardMenuOption: {
                            linkName: "vCard"
                            ,action: "VCardAPI.showAdvisorCard('', " + advisorID + ", \'" + advisorName + "\')"
                        },
                        advProfileNewPageMenuOption: {
                            linkName: "Profile (New Page)"
                            ,action: "window.open('/advisors/" + advisorID + "', '_blank')"
                        },
                        advProfileSamePageMenuOption: {
                            linkName: "Profile (Same Page)"
                            ,action: "window.location.assign('/advisors/" + advisorID + "')"
                            ,extraClass: "linkSectionEnd"
                        },
                        advEmailsMenuOption: {
                            linkName: "Email History"
                            ,action: "EmailPopupsAPI.showEmailMessagePopup('', {ID: 'emailpopupspan_" + advisorID + "', url: '/emails/buildPMAdvisorEmailPopup/', to_id: " + advisorID + ", to_role: 'Advisor', filter_set: 'PMtoAdvisor', title: '" + advisorName + " Emails' })"
                        },
                        advComposeEmailAdvisorsMenuOption: {
                            linkName: "Compose Email"
                            ,action: ""
                            ,extraClass: "linkSectionEnd"
                        },
                        advSubmitInvoiceMenuOption: {
                            linkName: "Submit Invoice"
                            ,action: "window.open('/invoices/create?advisor_id=" + advisorID + "', '_blank')"
                        }
                    });

                menuOptions.each( function(value, key) {
                    listOptions.include(
                        new Element("li", {
                            id: key + "_" + advisorID, "class": "advisorOptionLink clickable"
                            ,events: { click: function(){ eval(menuOptions[key]["action"]); } }
                        }).addClass(menuOptions[key]["extraClass"]).set("html", menuOptions[key]["linkName"])
                    );
                });

                var menuWrapper = new Element("div", {
                    id: "AdvisorOptionMenuWrapper_" + advisorID, "class": "advisorOptionMenuWrapper"
                    ,styles: { position: "absolute", top: parseInt(coords.top) + 1, left: parseInt(coords.right) - 11 }
                }).adopt(list.adopt(listOptions)).inject(document.body);
                Popups.dropShadow(list);
            }
        },

        /**
         *  Hides option menu for advisors link
         *
         * @author Michael Simmons <msimmons@guidepointglobal.com>
         * @param {Object} el - Element that has the event that invokes this function
         * @param {Integer} advisorID - ID of advisor
         */
        hideAdvisorOptionMenu: function(el, advisorID) {
            el.timeoutInt = setTimeout("$('AdvisorOptionMenuWrapper_" + advisorID + "').addClass('displayNone')", 200);
        },

        /**
         * Hides all item associated with Advisor Option Menu
         *
         * @author Michael Simmons <msimmons@guidepointglobal.com>
         * @param {Integer} advisorID - ID of advisor
         */
        hideAllAdvisorOptionMenuItems: function(advisorID) {
            var optionMenuImg = $("OptionMenuImg_" + advisorID);
            if (optionMenuImg.getProperty("rowHovered") != "Y") optionMenuImg.addClass("displayNone");
            $("AdvisorOptionMenuWrapper_" + advisorID).addClass("displayNone");
        },


        /**
         * shows Login Popup when user is not logged in and tries to make an ajax call
         *
         * @author Michael Simmons <msimmons@guidepointglobal.com>
         * @param {String} siteName - name of site. ex("PM", "Advisor", "Client").
         */
        showAjaxLoginPopup: function(siteName, cb_function) {
			var ajaxLoginWrapperWidth = 350, ajaxLoginWrapperHeight = 172;

        	//Login Top
        	var ajaxLoginTopLeftImg = new Element("img", { "class": "floatLeft", src: "/core/images/ajaxLoginTopLeft.gif" });
        	var ajaxLoginTopRightImg = new Element("img", { "class": "floatRight", src: "/core/images/ajaxLoginTopRight.gif" });

			switch (siteName) {
				case "PM":
					var loginTitle = "Login";
					break;
				case "Advisor":
					var loginTitle = "Advisor Login";
					break;
				case "Client":
					var loginTitle = "Client Login";
					break;
			}

			var primCallback = function (data) {
				if ("LOGIN_ERROR" == data) {
					$("LoginMsg").set("html", "Login Attempt Failed. Please enter your login credentials.");
				} else {
					if (cb_function) cb_function(data);
					Popups.hideAjaxLoginPopup();
				}
			};

			var ajaxLoginTitle = new Element("div", { "class": "ajaxLoginTitle left paddingMini" }).set("text", loginTitle);
        	var ajaxLoginTop = new Element("div", { "class": "ajaxLoginTop", styles: { background: "#33739A", "width": ajaxLoginWrapperWidth, "height": 32 }}).adopt(ajaxLoginTopLeftImg).adopt(ajaxLoginTopRightImg).adopt(ajaxLoginTitle);

          	//Login Middle
        	var ajaxLoginIDFieldsLabel = new Element("label", { "htmlFor": "loginId" }).set("text", "Email");
        	var ajaxLoginIDFieldsLabelCell = new Element("td", { "class": "label" }).adopt(ajaxLoginIDFieldsLabel);
        	var ajaxLoginIDFieldsInput = new Element("input", { id: "loginId", "class": "text", type: "text", name: "loginid", value: "" });
        	var ajaxLoginIDFieldsInpurCell = new Element("td", {}).adopt(ajaxLoginIDFieldsInput);
			var ajaxLoginIDFieldsRow = new Element("tr", {}).adopt(ajaxLoginIDFieldsLabelCell).adopt(ajaxLoginIDFieldsInpurCell);

        	var ajaxLoginPasswordFieldsLabel = new Element("label", { "htmlFor": "loginPassword" }).set("text", "Password");
       		var ajaxLoginPasswordFieldsLabelCell = new Element("td", { "class": "label" }).adopt(ajaxLoginPasswordFieldsLabel);
        	var ajaxLoginPasswordFieldsInput = new Element("input", { id:"loginPassword", "class": "text", type: "password", name: "loginpass", value: "" });
        	var ajaxLoginPasswordFieldsInputCell = new Element("td", {}).adopt(ajaxLoginPasswordFieldsInput);
			var ajaxLoginPasswordFieldsRow = new Element("tr", {}).adopt(ajaxLoginPasswordFieldsLabelCell).adopt(ajaxLoginPasswordFieldsInputCell);

        	var ajaxLoginSubmitBtnEmptyCell = new Element("td", {});
			var ajaxLoginSubmitBtn = new Element("input", { id:"loginBtn", "class": "floatLeft", type: "image", name: "loginpass", value: "", src: "/core/images/b_login_page.gif", alt: "Log In" });
        	var ajaxLoginSubmitBtnCell = new Element("td", {}).adopt(ajaxLoginSubmitBtn);
        	var ajaxLoginSubmitBtnRow = new Element("tr", {}).adopt(ajaxLoginSubmitBtnEmptyCell).adopt(ajaxLoginSubmitBtnCell);

        	var ajaxLoginTable = new Element("table", { id: "AjaxLoginTable", "class": "ajaxLoginTable" }).adopt(ajaxLoginIDFieldsRow).adopt(ajaxLoginPasswordFieldsRow).adopt(ajaxLoginSubmitBtnRow);
        	var ajaxLoginActionInput = new Element("input", { type: "hidden", name: "loginAction", value: "loginJS" });
        	var ajaxLoginMsg = new Element("div", { id:"LoginMsg", "class": "msg center", styles: { height: 20, "margin-top": 5 }}).set("text", "Your session has timed out.  Please enter your login credentials.");
        	var ajaxLoginForm = new Element("form", { id: "AjaxLoginForm", "class": "loginForm ajaxLoginForm", action: "/",  method: "post", target: "AjaxLoginFormTarget" }).adopt(ajaxLoginActionInput).adopt(ajaxLoginTable).adopt(ajaxLoginMsg);
        	var ajaxLoginFormTargetIframe = new Element("iframe", { id: "AjaxLoginFormTarget", "class": "ajaxLoginFormTarget", name: "AjaxLoginFormTarget", src: "#" });

        	ajaxLoginFormTargetIframe.addEvent("load", function (e) { primCallback($("AjaxLoginFormTarget").contentDocument.body.innerHTML); });

        	var ajaxLoginBottomLeftImg = new Element("img", { "class": "floatLeft", src: "/core/images/ajaxLoginBottomLeft.gif" });
        	var ajaxLoginBottomRightImg = new Element("img", {  "class": "floatRight", src: "/core/images/ajaxLoginBottomRight.gif" });
          	var ajaxLoginMiddle = new Element("div", { id: "AjaxLoginMiddle" }).adopt(ajaxLoginForm).adopt(ajaxLoginBottomLeftImg).adopt(ajaxLoginBottomRightImg);

			var location = Popups.getPopupLocation(ajaxLoginWrapperWidth, ajaxLoginWrapperHeight);
        	var ajaxLoginWrapper = new Element("div", { id: "AjaxLoginWrapper", "class": "ajaxLoginWrapper"
        		,styles: { background: "#f0efe6", width: ajaxLoginWrapperWidth, height: ajaxLoginWrapperHeight, position: "absolute", top: location.top, left: location.left, zIndex: 70000 }
        	}).adopt(ajaxLoginTop).adopt(ajaxLoginMiddle);

    		Popups.createModal();

    		( function() {
    			document.body.adopt(ajaxLoginFormTargetIframe).adopt(ajaxLoginWrapper);
        		Popups.centerPopup(ajaxLoginWrapper);
        	}).delay(1000);
        },

		hideAjaxLoginPopup: function() {
            $("AjaxLoginWrapper").destroy();
			Popups.hideModal();
		}
    };
} ) ();

/*****************************************************************************
* listSelectorAPI:
* Builds customized list selectors for massUpdate selection
*
*****************************************************************************/
var listSelectorAPI = (function () {
	// Variable storing the list selectors loaded on the page
	var listSelectors = {};

	/*************************************************************************
	* This method is public and accessible using listSelectorAPI.checkOff()
	* Checks off passed in checkboxes
	*
	* param: Object, array, collection or nodelist of checkboxes elements
	* param: Boolean, checked or unchecked
	* param: Boolean, if there is any disabled checkboxes within the collection, it indicates whether or not include them
	* return: int, count of checked off checkboxes
	*************************************************************************/
	var checkOff = function (checkboxes, checked, includeDisabled) {
		if (!$defined(includeDisabled)) {
			includeDisabled = true;
		}
		var count = 0;
		if (checkboxes) {
			if (!$defined(checkboxes.length)) { // checkboxes is not an array nor a nodelist, so we make it an array
				checkboxes = [checkboxes];
			}

			if (checkboxes.length > 0) {
				for (var i = 0; i < checkboxes.length; i++) {
					if (includeDisabled || !checkboxes[i].get("disabled")) {
						if (checked) {
							checkboxes[i].set("checked", "checked");
							count++;
						} else {
							checkboxes[i].erase("checked");
						}
					}
				}
			}
		}
		return count;
	};

	/*************************************************************************
	* This method is public and accessible using listSelectorAPI.disable()
	* Disables passed in checkboxes
	*
	* param: Object, array, collection or nodelist of checkboxes elements
	* param: Boolean, disabled if true, enabled otherwise
	* return: int, count of disabled checkboxes
	*************************************************************************/
	var disable = function (checkboxes, disabled) {
		if (!$defined(checkboxes.length)) { // checkboxes is not an array nor a nodelist, so we make it an array
			checkboxes = [checkboxes] ;
		}
		var count = 0;
		if (checkboxes) {
			if (checkboxes.length > 0) {
				for (var i = 0; i < checkboxes.length; i++) {
					if (disabled) {
						checkboxes[i].set("disabled", "disabled");
						count++;
					} else {
						checkboxes[i].erase("disabled");
					}
				}
			}
		}
		return count;
	};

	/*************************************************************************
	* This Class is public and accessible using listSelectorAPI.ListSelector
	*
	*************************************************************************/
	var ListSelector = new Class ({
		hotspot: false 							// Hotspot element (required)
		,mesBox: false 							// Message box element (optional)
		,processForm: false 					// Process Form, mass update (required)
		,searchForm: false 						// Search form (optional)
		,checkboxName: "" 						// Checkbox name attribute
		,popup: false 							// Popup element
		,selectors: [] 							// Array of selector Object (see below)
		,globalCount: 0 						// Global count of the checkbox collection
		,selectedCount: 0 						// Selected checkbox count
		,processAllFlag: 0 						// Use all the checkboxes (of all the pages) with the process form
		,searchAllFlag: 0 						// Use all the checkboxes (of all the pages) with the search form
        ,options: {								// Option object
        	"includeDisabled" : true,
        	"dropShadow" : true,
        	"selectAll" : 0
        }

        /*************************************************************************
		* ListSelector Constructor
		*
		* param: Element, processForm: form used for maass update
		* param: String, checkboxName: Name attribute of the checkbox
		* param: Element, hotspot: triggers the listSelector when clicked
		* param: Array, selectors: Array of selector Object.
		*        Ex: {"label" : "myLabel", "count" : 50, "fn" : function (){ doMyOwnSelection(); }}
		*************************************************************************/
        ,initialize: function (processForm, checkboxName, hotspot, selectors, options) {
			selectors = selectors || null;
			this.hotspot = hotspot;
			this.messageBox = $(checkboxName + "_mb") || false;

			this.processForm = processForm || false;
			this.searchForm = (processForm) ? $(processForm.get("id").split("_")[0] + "_searchForm") : false;

			this.globalCount = $(this.processForm.get("id") + "_gc").value;
			this.checkboxName = checkboxName;
			this.options = $merge(this.options, options);
			this.options["wrapperStyles"] = this.options["wrapperStyles"] || {};

			if (this.processForm && !this.processForm[this.checkboxName + "_process_all"]) {
				this.processForm.adopt(new Element("input", {
					"type" : "hidden",
					"id" : this.checkboxName + "_process_all",
					"name" : this.checkboxName + "_process_all",
					"value" : this.options["selectAll"]
				}));
			}

			if (this.searchForm && !this.searchForm[this.checkboxName + "_search_all"]) {
				this.searchForm.adopt(new Element("input", {
					"type" : "hidden",
					"id" : this.checkboxName + "_search_all",
					"name" : this.checkboxName + "_search_all",
					"value" : this.options["selectAll"]
				}));
				// Setup event so the form is reset when a new search is done
				this.searchForm.addEvent("submit", (function () {
					this.searchForm[this.checkboxName + "_search_all"].set('value', 0);
					this.processForm[this.checkboxName + "_process_all"].set('value', 0);
				}).bind(this));
			}

			// Try to get the process flag and search flag form if there is any (these are not required)
			this.processAllFlag = (this.processForm) ? ((this.processForm[this.checkboxName + "_process_all"]) ? parseInt(this.processForm[this.checkboxName + "_process_all"].value) : 0) : 0;
			this.searchAllFlag = (this.searchForm) ? ((this.searchForm[this.checkboxName + "_search_all"]) ? parseInt(this.searchForm[this.checkboxName + "_search_all"].value) : 0) : 0;

			// Initialize the selected count if the process flag = 1
			if (this.processAllFlag == 1) {
				this.selectedCount = this.globalCount;
			}

			// Set selectors to default if no selectors is provided
			if (selectors == null) {
				this.addSelector("This Page", this.processForm[checkboxName + "[]"].length || 1, (function () {
					this.selectPage();
					this.hide();
				}).bind(this));
				this.addSelector("All Records", this.globalCount, (function () {
					this.selectAll();
					this.hide();
				}).bind(this));
				this.addSelector("None", null, (function () {
					this.selectNone();
					this.hide();
				}).bind(this));
			} else {
				selectors.each(
					(function (item) {
						item.fn.bind(this);
						this.addSelector(item);
					}).bind(this)
				);
			}

			// Assigns onClick Event to the hotspot (arrow img)
			this.hotspot.addEvent("click", (function () {
				this.display();
			}).bind(this));

			// Assigns onClick Event to check all checkbox
			/*this.processForm[this.checkboxName + "All"].addEvent("click", (function () {
				this.toggleAll();
			}).bind(this));*/


			// Assigns onClick Event to all the checkboxes to change the count of selected records on the fly
			// Hack to avoid scope issues using the addEvent function
			var that = this;

			// Use for loop because .each does not work on a nodeList
			var checkboxes = this.processForm[this.checkboxName + "[]"] || false;
			if (checkboxes) {
				if (!$defined(checkboxes.length)) {
					checkboxes = [checkboxes];
				}

				for (var i = 0; i < checkboxes.length; i++) {
					checkboxes[i].addEvent("click", function () {
						if (this.checked) {
							that.selectedCount++;
						} else {
							that.selectedCount--;
						}
						that.showMessage();
					});

				}
			}

			if (this.options["extraInit"]) { this.options["extraInit"].bind(this)(); }
		},

		/*************************************************************************
		* Add a selector to the ListSelector Object
		*
		* param: String, label: label of the added selector
		* param: int, count: Count of the added selector
		* param: Function, fn: function executed when the selector is selected
		*************************************************************************/
		"addSelector" : function (label, count, fn) {
			if ($type(label) == "object") {
				this.selectors.push(label);
			} else {
				this.selectors.push({
					"label" : label,
					"count" : count,
					"fn" : fn
				});
			}
		},

		/*************************************************************************
		* Checks off the passed in checkboxes.
		* Uses the includeDisabled option of the Object
		*
		* param: Object, checkboxes: array, collection or nodelist of checkboxes
		* param: boolean, checked: checked or unchecked
		* return: int, count of checked off checkboxes
		*************************************************************************/
		"checkOff" : function (checkboxes, checked) {
			return checkOff(checkboxes, checked, this.options["includeDisabled"]);
		},

		/*************************************************************************
		* Disables passed in checkboxes
		* See listSelectorAPI.disable()
		*************************************************************************/
		"disable" : disable,

		/*************************************************************************
		* Sets the processAllFlag and searchAllFlag property
		*
		* param: int, val: 0 or 1
		* return: void
		*************************************************************************/
		"setAllFlag" : function (val) {
			if (this.processForm && this.processForm[this.checkboxName + "_process_all"]) {
				this.processForm[this.checkboxName + "_process_all"].set("value", val);
				this.processAllFlag = parseInt(val);
			} else {
				this.processAllFlag = 0;
			}

			if (this.searchForm && this.searchForm[this.checkboxName + "_search_all"]) {
				this.searchForm[this.checkboxName + "_search_all"].set("value", val);
				this.searchAllFlag = parseInt(val);
			} else {
				this.searchAllFlag = 0;
			}

			/*
			if (this.processAllFlag) { this.processAllFlag.set("value", val); }
			if (this.searchAllFlag) { this.searchAllFlag.set("value", val); }*/
		},

		/*************************************************************************
		* Set the content of the message container, if there is any
		* /!\ TO UPDATE
		*
		* param: int, count: Count of selected checkbox
		* return: void
		*************************************************************************/
		"showMessage" : function (cnt) {
			cnt = cnt || this.selectedCount;
			var mes = ((cnt == 0) ? "No" : cnt.numberFormat() ) + " record" + ((cnt > 1) ? "s" : "") + " selected";

			if (this.messageBox) {
				this.messageBox.set('html', mes);
			}
		},

		/*************************************************************************
		* Builds the listSelector popup with the dropshadow
		*
		* return: void
		*************************************************************************/
		"build" : function () {
			// If no popup, creates it
			if (!this.popup) {
				this.popup = new Element("div", {
		            "id" : "selectorPopup_Wrapper",
					"events" : {
		                "mousedown" : function (e) {
		                    try {
		                    	var evt = new Event(e);
		                    	evt.stop();
		                    } catch (ex) { }
						}
		            },
		            "styles" : this.options.wrapperStyles
				}).adopt( new Element("div", {
                    "id" : "selectorPopup",
                    "class" : "selectorPopup PopupInfo"
                }));
				elCoordinates = this.hotspot.getCoordinates();

		    	this.popup.setStyles( {
                    position: "absolute"
                    ,left: parseInt(elCoordinates["left"]) - 7
					,top: parseInt(elCoordinates["top"]) + parseInt(elCoordinates["height"]) + 2
				}).inject(document.body);
			}

			// Builds the selectors
			if (this.popup.getFirst().get("html") == "") {
				this.selectors.each((function (item, idx) {
					this.popup.getFirst().adopt(
						new Element("div", {
							"class" : "clickable selectorItem " + ((idx == 0) ? "last " : "") + ((idx % 2 == 0) ? "even" : "odd"),
							"events" : {
								"click" : item.fn.bind(this)
							}
						}).appendText(item.label + ((item.count !== null) ? " (" + item.count.numberFormat() + ")" : ""))
					);
				}).bind(this));
			}

			// Builds the dropShadow
			if (this.options["dropShadow"]) {
				Popups.dropShadow(this.popup.getFirst());
			}
		},

		/*************************************************************************
		* Displays the listSelector popup
		*
		* return: void
		*************************************************************************/
		"display" : function () {
			if (!this.popup) this.build();
			this.popup.removeClass("hidden");
			this.boundHide = this.hide.bind(this);
			document.addEvent("mousedown", this.boundHide);
    	},

    	/*************************************************************************
		* Hides the listSelector popup
		*
		* return: void
		*************************************************************************/
		"hide" : function (destroy) {
			if (this.popup) {
				if (destroy) {
                    this.popup.destroy();
                    this.popup = false;
                } else {
                    this.popup.addClass("hidden");
                }
				document.removeEvent("mousedown", this.boundHide);
			}
		},

		/*************************************************************************
		* Reset all the checkboxes:
		*  - unchecks all the checkboxes
		*  - enables all the checkboxes
		*  - resets the counts
		*  - Shows the message
		*
		* return: void
		*************************************************************************/
		"reset" : function() {
			var checkboxes = this.processForm[this.checkboxName + "[]"];
			//var checkAll = this.processForm[this.checkboxName + "All"];

			if (this.options["includeDisabled"]) {
				//this.disable(checkAll, false);
				this.disable(checkboxes, false);
			}

			//this.checkOff(checkAll, false, this.options["includeDisabled"]);
			this.checkOff(checkboxes, false, this.options["includeDisabled"]);

			this.selectedCount = 0;
			this.showMessage();

			this.setAllFlag(0);
		},

		/*************************************************************************
		* Gets all the selected checkboxes:
		*  param: boolean includeDisabled: include disabled checkboxes in the selection
		*
		* return: obj: selection
		*************************************************************************/
		"getSelected" : function(includeDisabled) {
			if (!$defined(includeDisabled)) {
				includeDisabled = this.options["includeDisabled"];
			}

			var selection = {
				"currentPage" : [],
				"all" : this.processAllFlag
			};
			var checkboxes = this.processForm[this.checkboxName + "[]"];

			if (!$defined(checkboxes.length)) { // checkboxes is not an array nor a nodelist, so we make it an array
				checkboxes = [checkboxes];
			}

			if (checkboxes.length > 0) {
				for (var i = 0; i < checkboxes.length; i++) {
					if (includeDisabled || !checkboxes[i].get("disabled")) {
						if (checkboxes[i].checked) {
							selection["currentPage"].push(checkboxes[i].value);
						}
					}
				}
			}
			return selection;
		},

		/*************************************************************************
		* Gets the processAllFlag value
		*
		* return: int: 0 or 1
		*************************************************************************/
		"getProcessAll" : function() {
			return this.processAllFlag;
		},

		/*************************************************************************
		* Gets the searchAllFlag value
		*
		* return: int: 0 or 1
		*************************************************************************/
		"getSearchAll" : function() {
			return this.searchAllFlag;
		},

		/*************************************************************************
		* Select all the checkboxes including the ones on other pages (using the processAllFlag)
		*  - checks all the checkboxes
		*  - disables all the checkboxes
		*  - sets the counts
		*  - Shows the message
		*
		* return: void
		*************************************************************************/
		"selectAll" : function () {
			var checkboxes = this.processForm[this.checkboxName + "[]"];
			//var checkAll = this.processForm[this.checkboxName + "All"];

			if (this.options["includeDisabled"]) {
				//this.disable(checkAll, true);
				this.disable(checkboxes, true);
			}

			//this.checkOff(checkAll, true, this.options["includeDisabled"]);
			this.checkOff(checkboxes, true, this.options["includeDisabled"]);

			this.selectedCount = this.globalCount;
			this.showMessage();

			this.setAllFlag(1);
		},

		/*************************************************************************
		* Select none of the checkboxes
		* Alias of reset()
		*
		* return: void
		*************************************************************************/
		"selectNone" : function () {
			this.reset();
		},

		/*************************************************************************
		* Select all the checkboxes within the current page
		*  - checks all the checkboxes
		*  - disables all the checkboxes
		*  - sets the counts
		*  - Shows the message
		*
		* return: void
		*************************************************************************/
		"selectPage" : function () {
			var checkboxes = this.processForm[this.checkboxName + "[]"];
			//var checkAll = this.processForm[this.checkboxName + "All"];

			if (this.options["includeDisabled"]) {
				//this.disable(checkAll, false);
				this.disable(checkboxes, false);
			}

			//this.checkOff(checkAll, true, this.options["includeDisabled"]);
			this.selectedCount = this.checkOff(checkboxes, true, this.options["includeDisabled"]);

			this.showMessage();

			this.setAllFlag(0);
		},

		/*************************************************************************
		* Toggle all the checkboxes within the current page
		*  - checks all the checkboxes
		*  - disables all the checkboxes
		*  - sets the counts
		*  - Shows the message
		*
		* return: void
		*************************************************************************/
		"toggleAll" : function () {
			if (this.processForm[this.checkboxName + "All"].checked) {
				this.selectPage();
			} else {
				this.selectNone();
			}
		}
	}); // End of ListSelector Class

    /*************************************************************************
	* Setup a listSelector for the current document
	*
	* param: Element, processForm: form of the mass update
	* param: String, checkboxName: Name attribute of the checkbox
	* param: Element, hotspot: Triggers the listSelector popup when clicked
	* param: Object, selectors: Array of selectors (can be null, so selecctor will be set to default)
	* param: Object, options: Options of the listSelector {"includeDisabled" : true or false}
	* return: void
	*************************************************************************/
	var setup = function (processForm, checkboxName, hotspot, selectors, options) {
		// Register the selector in the static variable of the API
		if (!listSelectors[processForm.id]) {
			listSelectors[processForm.id]= {};
		}
		listSelectors[processForm.id][checkboxName] = new ListSelector(processForm, checkboxName, hotspot, selectors, options);
	};

	/*************************************************************************
	* Return a listSelector
	*
	* param: String, processFormID: form of the mass update
	* param: String, checkboxName: Name attribute of the checkbox
	* return: ListSelector
	*************************************************************************/
	var getListSelector = function (processFormID, checkboxName) {
		return listSelectors[processFormID] ? listSelectors[processFormID][checkboxName] : false;
	};

	return {
		setup : setup,
		ListSelector : ListSelector,
		listSelectors : listSelectors,
		getListSelector : getListSelector,
		checkOff : checkOff,
		disable : disable
	};
})();


/*****************************************************************************
* listSelectorAPI:
* Builds customized list selectors for massUpdate selection
*
*****************************************************************************/
var listSelectorAPI_new = (function () {
	// Variable storing the list selectors loaded on the page
	var listSelectors = {};

	/*************************************************************************
	* This method is public and accessible using listSelectorAPI.checkOff()
	* Checks off passed in checkboxes
	*
	* param: Object, array, collection or nodelist of checkboxes elements
	* param: Boolean, checked or unchecked
	* param: Boolean, if there is any disabled checkboxes within the collection, it indicates whether or not include them
	* return: int, count of checked off checkboxes
	*************************************************************************/
	var checkOff = function (checkboxes, checked, includeDisabled) {
		if (!$defined(includeDisabled)) {
			includeDisabled = true;
		}
		var count = 0;
		if (checkboxes) {
			if (!$defined(checkboxes.length)) { // checkboxes is not an array nor a nodelist, so we make it an array
				checkboxes = [checkboxes];
			}

			if (checkboxes.length > 0) {
				for (var i = 0; i < checkboxes.length; i++) {
					if (includeDisabled || !checkboxes[i].get("disabled")) {
						if (checked) {
							checkboxes[i].set("checked", "checked");
							count++;
						} else {
							checkboxes[i].erase("checked");
						}
					}
				}
			}
		}
		return count;
	};

	/*************************************************************************
	* This method is public and accessible using listSelectorAPI.disable()
	* Disables passed in checkboxes
	*
	* param: Object, array, collection or nodelist of checkboxes elements
	* param: Boolean, disabled if true, enabled otherwise
	* return: int, count of disabled checkboxes
	*************************************************************************/
	var disable = function (checkboxes, disabled) {
		if (!$defined(checkboxes.length)) { // checkboxes is not an array nor a nodelist, so we make it an array
			checkboxes = [checkboxes] ;
		}
		var count = 0;
		if (checkboxes) {
			if (checkboxes.length > 0) {
				for (var i = 0; i < checkboxes.length; i++) {
					if (disabled) {
						checkboxes[i].set("disabled", "disabled");
						count++;
					} else {
						checkboxes[i].erase("disabled");
					}
				}
			}
		}
		return count;
	};

	/*************************************************************************
	* This Class is public and accessible using listSelectorAPI.Selector
	*
	*************************************************************************/
	var Selector = new Class({

		/*************************************************************************
		* Selector Constructor
		*
		* param: String, label: label of the Selector
		* param: int, count: count for this Selector when selected
		* param: Function, fn: function triggered when selecting this Selector
		* param: String, flagName: name of the flag if there is any associated flag for this Selector (optional)
		* param: boolean, flagValue: value of the flag if there is any associated flag for this Selector. 0 or 1 (optional)
		* param: boolean, addHiddenInputs: indicates whether or not we want to add hidden input on the page to process with POST form
		*************************************************************************/
		initialize : function (label, count, fn, flagName, flagValue, addHiddenInputs, onComplete) {
			this.label = label;
			this.count = count;
			this.fn = fn;
			this.inputs = ($defined(addHiddenInputs)) ? addHiddenInputs : false;
			this.onComplete = ($defined(onComplete)) ? onComplete : false;
			this.listSelector = null;

			flagName = ($defined(flagName)) ? flagName : false;
			flagValue = ($defined(flagValue)) ? flagValue : 0;

			if (flagName) {
				this.flag = {
					"name" : flagName,
					"value" : flagValue
				};
			} else {
				this.flag = false;
			}
		},

		/*************************************************************************
		* Assigns a ListSelector Object to this Selector
		*
		* param: ListSelector, listSelector: ListSelector you want to assign to this Selector
		* return: void
		*************************************************************************/
		setListSelector : function (listSelector) {
			this.listSelector = listSelector;
		},

		/*************************************************************************
		* Set the flag value of this Selector if there is a flag
		*
		* param: boolean, flagValue: 0 or 1
		* return: int, flagValue: 0 or 1
		*************************************************************************/
		setFlag : function (flagValue) {
			if (this.flag) {
				this.flag.value = flagValue;
				if (this.inputs && this.listSelector) {
					this.listSelector.setInputFlags(this.flag.name, flagValue);
				}
				return flagValue;
			}
		},

		/*************************************************************************
		* Return a boolean value indicating whether or not this Selector is selected
		*
		* return: int, flagValue: 0 or 1
		*************************************************************************/
		isSelected : function () {
			return this.flag ? (this.flag.value == 1) : false;
		},

		/*************************************************************************
		* Resets the flag value to 0
		*
		* return: void
		*************************************************************************/
		resetFlag : function () {
			this.setFlag(0);
		},

		/*************************************************************************
		* Selects this Selector: set flag value to 1, triggers the associated
		* function and show the message if there any message container for the
		* associated ListSelector Object
		*
		* return: void
		*************************************************************************/
		select : function (noOnComplete) {
			if (this.listSelector) {
				if (!$defined(noOnComplete)) {
					//print_r("noOnComplete is not defined");
					noOnComplete = false;
				} else {
					//print_r("noOnComplete is defined");
					if ($type(noOnComplete) != "boolean") {
						//print_r("noOnComplete is not a boolean");
						noOnComplete = false;
					}

					//print_r(noOnComplete);
				}

				this.fn.bind(this.listSelector)();
				this.listSelector.selectedCount = (this.count !== null) ? this.count : 0;
				this.setFlag(1);
				this.listSelector.showMessage();

				if (!noOnComplete) {
					if (this.onComplete && ($type(this.onComplete) == "function")) {
						//print_r("executing onComplete ...");
						this.onComplete();
					} else {
						//print_r("not set or not a function");
					}
				} else {
					//print_r("NO ONCOMPLETE");
				}
			} else {
				throw "No listSelector assigned: cannot proceed";
			}
		}
	});

	/*************************************************************************
	* This Class is public and accessible using listSelectorAPI.ListSelector
	*
	*************************************************************************/
	var ListSelector = new Class ({
		hotspot : false 						// Hotspot element (required)
		,mesBox : false 						// Message box element (optional)
		,processForm : false 					// Process Form, mass update (required)
		,searchForm : false 					// Search form (optional)
		,checkboxName : "" 						// Checkbox name attribute
		,popup : false 							// Popup element
		,selectors : [] 						// Array of selector Object (see below)
		,globalCount : 0 						// Global count of the checkbox collection
		,selectedCount : 0 						// Selected checkbox count
		,processAllFlag : 0 					// Use all the checkboxes (of all the pages) with the process form
		,searchAllFlag : 0 						// Use all the checkboxes (of all the pages) with the search form
        ,options : {							// Option object
        	"includeDisabled" : true,
        	"dropShadow" : true,
        	"selectAll" : 0
        }

        /*************************************************************************
		* ListSelector Constructor
		*
		* param: Element, processForm: form used for mass update
		* param: String, checkboxName: Name attribute of the checkbox
		* param: Element, hotspot: triggers the listSelector when clicked
		* param: Array, selectors: Array of Selector object (see Selector class above).
		* param: Object, option: associative Array of options. Valid entries are
		*			"includeDisabled" : boolean, whether or not include disabled checkboxes,
        *			"dropShadow" : boolean, whether or not create the dropshadow effect on the popup,
        *			"selectAll" : boolean, value the "all" selected flag, used only for default selector (i.e selectors == null)
		*************************************************************************/
        ,initialize: function (processForm, checkboxName, hotspot, selectors, options) {
			this.processForm = processForm || false;
			if (!processForm) {
				throw "ListSelector constructor: processForm doesn't exist.";
			}

        	this.hotspot = hotspot;
			this.messageBox = $(checkboxName + "_mb") || false;
			this.searchForm = (processForm) ? $(processForm.get("id").split("_")[0] + "_searchForm") : false;
			this.globalCount = $(this.processForm.get("id") + "_gc").value;
			this.checkboxName = checkboxName;
			this.options = $merge(this.options, options);
			this.options["wrapperStyles"] = this.options["wrapperStyles"] || {};

			// Assigns onClick Event to the hotspot (arrow img)
			this.hotspot.addEvent("click", (function () {
				this.display();
			}).bind(this));

			// Assigns onClick Event to all the checkboxes to change the count of selected records on the fly
			// Hack to avoid scope issues ("this" variable conflicts) using the addEvent function
			var that = this;

			// Use for loop because .each does not work on a nodeList
			var checkboxes = this.processForm[this.checkboxName + "[]"] || false;

			if (checkboxes) {
				if (!$defined(checkboxes.length)) {
					checkboxes = [checkboxes];
				}
				var pageCount = checkboxes.length;

				for (var i = 0; i < pageCount; i++) {
					checkboxes[i].addEvent("click", function () {
						if (this.checked) {
							that.selectedCount++;
						} else {
							that.selectedCount--;
						}
						that.showMessage();
					});
				}
			} else {
				var pageCount = 0;
			}

			// Set selectors to default if no selectors is provided
			if (!$defined(selectors)) {
				selectors = [
					new Selector("All Records", this.globalCount, function () { this.reset(); this.selectAll(); this.hide(); }, "all", this.options["selectAll"], true),
					new Selector("This Page", pageCount , function () { this.reset(); this.selectPage(); this.hide(); }),
					new Selector("None", null, function () { this.reset(); this.hide(); })
				];
			}

			selectors.each(
				(function (item) {
					item.fn.bind(this);
					this.addSelector(item);
				}).bind(this)
			);

			if (this.options["extraInit"]) { this.options["extraInit"].bind(this)(); }
		},

		/*************************************************************************
		* Add a hidden input flag to the process form
		*
		* param: String, flagName: name of the flag
		* param: String, flagValue: value of the flag
		*************************************************************************/
		"addProcessFlagInput" : function (flagName, flagValue) {
			if (this.processForm && !this.processForm[this.checkboxName + "_process_" + flagName]) {
				this.processForm.adopt(new Element("input", {
					"type" : "hidden",
					"id" : this.checkboxName + "_process_" + flagName,
					"name" : this.checkboxName + "_process_" + flagName,
					"value" : flagValue
				}));
			}
		},

		/*************************************************************************
		* Add a hidden input flag to the search form and setup onSubmit events to reset flag values
		*
		* param: String, flagName: name of the flag
		* param: String, flagValue: value of the flag
		*************************************************************************/
		"addSearchFlagInput" : function (flagName, flagValue) {
			if (this.searchForm && !this.searchForm[this.checkboxName + "_search_" + flagName]) {
				this.searchForm.adopt(new Element("input", {
					"type" : "hidden",
					"id" : this.checkboxName + "_search_" + flagName,
					"name" : this.checkboxName + "_search_" + flagName,
					"value" : flagValue
				}));
				// Setup event so the form is reset when a new search is done
				this.searchForm.addEvent("submit", (function () {
					this.setInputFlags(flagName, 0);
				}).bind(this));
			}
		},

		/*************************************************************************
		* Set hidden input flags value in both process and search form if those exist
		*
		* param: String, flagName: name of the flag
		* param: String, flagValue: value of the flag
		*************************************************************************/
		"setInputFlags" : function (flagName, flagValue) {
			if (this.processForm && this.processForm[this.checkboxName + "_process_" + flagName]) {
				this.processForm[this.checkboxName + "_process_" + flagName].set("value", flagValue);
			}
			if (this.searchForm && this.searchForm[this.checkboxName + "_search_" + flagName]) {
				this.searchForm[this.checkboxName + "_search_" + flagName].set("value", flagValue);
			}
		},

		/*************************************************************************
		* Add a selector to the ListSelector Object
		*
		* param: String, label: label of the added selector
		* param: int, count: Count of the added selector
		* param: Function, fn: function executed when the selector is selected
		* param: String, flagName: name of the flag for the added selector (optional)
		* param: int, fn: value of the flag for the added selector (optional)
		*************************************************************************/
		"addSelector" : function (selector) {
			// Link the selector to the list selector
			selector.setListSelector(this);
			this.selectors.push(selector);

			// Create hidden inputs if needed
			if (selector.flag && selector.inputs) {
				this.addProcessFlagInput(selector.flag.name, selector.flag.value);
				this.addSearchFlagInput(selector.flag.name, selector.flag.value);
			}

			// Initialize the selector if it is selected
			if (selector.isSelected()) {
				selector.select(true);
			}
		},

		/*************************************************************************
		* Checks off the passed in checkboxes.
		* Uses the includeDisabled option of the Object
		*
		* param: Object, checkboxes: array, collection or nodelist of checkboxes
		* param: boolean, checked: checked or unchecked
		* return: int, count of checked off checkboxes
		*************************************************************************/
		"checkOff" : function (checkboxes, checked) {
			return checkOff(checkboxes, checked, this.options["includeDisabled"]);
		},

		/*************************************************************************
		* Disables passed in checkboxes
		* See listSelectorAPI.disable()
		*************************************************************************/
		"disable" : disable,

		/*************************************************************************
		* Checks Off and disables checkboxes according to the className passed in parameter
		*
		* param: String, className: class name of the checkboxes you want to select
		* return: void
		*************************************************************************/
		"checkOffAndDisable" : function (className, status) {
			this.checkOff(this.processForm.getElements("input[name^=" + this.checkboxName + "]." + className), status);
			this.disable(this.processForm[this.checkboxName + "[]"], status);
		},
		/*************************************************************************
		* Set the content of the message container, if there is any
		*
		* param: int, count: Count of selected checkbox
		* return: void
		*************************************************************************/
		"showMessage" : function (cnt) {
			cnt = cnt || this.selectedCount;

			if (this.messageBox && cnt != null) {
				this.messageBox.set("html", ((cnt == 0) ? "No" : cnt.numberFormat() ) + " record" + ((cnt > 1) ? "s" : "") + " selected");
			}
		},

		/*************************************************************************
		* Builds the listSelector popup with the dropshadow
		*
		* return: void
		*************************************************************************/
		"build" : function () {
			// If no popup, creates it
			if (!this.popup) {
				this.popup = new Element("div", {
					"id" : "selectorPopup_Wrapper",
		            "events" : {
						"mousedown" : function (e) {
							try {
								var evt = new Event(e);
								evt.stop();
							} catch (ex) { }
						}
					},
					"styles" : this.options["wrapperStyles"]
				}).adopt( new Element("div", {
                    "id" : "selectorPopup",
                    "class" : "selectorPopup PopupInfo"
                }));
				elCoordinates = this.hotspot.getCoordinates();

		    	this.popup.setStyles( {
                    position: "absolute"
                    ,left: parseInt(elCoordinates["left"]) - 7
					,top: parseInt(elCoordinates["top"]) + parseInt(elCoordinates["height"]) + 2
				}).inject(document.body);
			}

			// Builds the selectors
			if (this.popup.getFirst().get("html") == "") {
				this.selectors.each((function (item, idx) {
					this.popup.getFirst().adopt(
						new Element("div", {
							"class" : "clickable selectorItem " + ((idx == 0) ? "last " : "") + ((idx % 2 == 0) ? "even" : "odd"),
							"events" : {
								"click" : item.select.bind(item)
							}
						}).appendText(item.label + ((item.count !== null) ? " (" + item.count.numberFormat() + ")" : ""))
					);
				}), this);
			}

			// Builds the dropShadow
			if (this.options["dropShadow"]) {
				Popups.dropShadow(this.popup.getFirst());
			}
		},

		/*************************************************************************
		* Displays the listSelector popup
		*
		* return: void
		*************************************************************************/
		"display" : function () {
			if (!this.popup) this.build();
			this.popup.removeClass("hidden");
			this.boundHide = this.hide.bind(this);
			document.addEvent("mousedown", this.boundHide);
    	},

    	/*************************************************************************
		* Hides the listSelector popup
		*
		* return: void
		*************************************************************************/
		"hide" : function () {
			if (this.popup) {
				this.popup.addClass("hidden");
				document.removeEvent("mousedown", this.boundHide);
			}
		},

		/*************************************************************************
		* Reset all the checkboxes:
		*  - unchecks all the checkboxes
		*  - enables all the checkboxes
		*  - resets the counts
		*  - Shows the message
		*
		* return: void
		*************************************************************************/
		"reset" : function() {
			var checkboxes = this.processForm[this.checkboxName + "[]"];

			if (checkboxes) {
				if (this.options["includeDisabled"]) {
					this.disable(checkboxes, false);
				}

				this.checkOff(checkboxes, false, this.options["includeDisabled"]);
			}
			this.selectedCount = 0;
			this.showMessage();

			this.selectors.each(function (item, index) {
				item.resetFlag();
			});
		},

		/*************************************************************************
		* Gets all the selected checkboxes
		*
		* param: boolean includeDisabled: include disabled checkboxes in the selection
		* return: obj: selection
		*************************************************************************/
		"getSelected" : function(includeDisabled) {
			if (!$defined(includeDisabled)) {
				includeDisabled = this.options["includeDisabled"];
			}

			var selection = {
				"currentPage" : [],
				"flags" : {}
			};

			this.selectors.each(function(item) {
				if (item.flag) {
					selection["flags"][item.flag.name] = item.flag.value;
				}
			});

			var checkboxes = this.processForm[this.checkboxName + "[]"];

			if (checkboxes) {
				if (!$defined(checkboxes.length)) { // checkboxes is not an array nor a nodelist, so we make it an array
					checkboxes = [checkboxes];
				}

				if (checkboxes.length > 0) {
					for (var i = 0; i < checkboxes.length; i++) {
						if ((includeDisabled || !checkboxes[i].get("disabled")) && checkboxes[i].checked) {
							selection["currentPage"].push(checkboxes[i].value);
						}
					}
				}
			}

			return selection;
		},

		/*************************************************************************
		* Gets the selected flags
		*
		* return: obj: selected flags
		*************************************************************************/
		"getFlags" : function() {
			return this.getSelected().flags;
		},

		/*************************************************************************
		* Gets the selected flag
		*
		* return: obj: selected flag
		*************************************************************************/
		"getSelectedFlag" : function() {
			var flags = this.getFlags();

			for (var key in flags) {
				if (flags[key]) {
					var selectedFlag = {};
					selectedFlag[key] = flags[key];
					return selectedFlag;
				}
			}
			return false;
		},

		/*************************************************************************
		* Select all the checkboxes including the ones on other pages (using the processAllFlag)
		*  - checks all the checkboxes
		*  - disables all the checkboxes
		*  - sets the counts
		*  - Shows the message
		*
		* return: void
		*************************************************************************/
		"selectAll" : function () {
			var checkboxes = this.processForm[this.checkboxName + "[]"];

			if (checkboxes) {
				if (this.options["includeDisabled"]) {
					this.disable(checkboxes, true);
				}

				this.checkOff(checkboxes, true);
			}
		},

		/*************************************************************************
		* Select none of the checkboxes
		* Alias of reset()
		*
		* return: void
		*************************************************************************/
		"selectNone" : function () {
			this.reset();
		},

		/*************************************************************************
		* Select all the checkboxes within the current page
		*  - checks all the checkboxes
		*  - disables all the checkboxes
		*  - sets the counts
		*  - Shows the message
		*
		* return: void
		*************************************************************************/
		"selectPage" : function () {
			var checkboxes = this.processForm[this.checkboxName + "[]"];

			if (checkboxes) {
				if (this.options["includeDisabled"]) {
					this.disable(checkboxes, false);
				}

				this.checkOff(checkboxes, true, this.options["includeDisabled"]);
			}
		},

		/*************************************************************************
		* Toggle all the checkboxes within the current page
		*  - checks all the checkboxes
		*  - disables all the checkboxes
		*  - sets the counts
		*  - Shows the message
		*
		* return: void
		*************************************************************************/
		"toggleAll" : function () {
			if (this.processForm[this.checkboxName + "All"].checked) {
				this.selectPage();
			} else {
				this.selectNone();
			}
		}
	}); // End of ListSelector Class

    /*************************************************************************
	* Setup a listSelector for the current document
	*
	* param: Element, processForm: form of the mass update
	* param: String, checkboxName: Name attribute of the checkbox
	* param: Element, hotspot: Triggers the listSelector popup when clicked
	* param: Object, selectors: Array of selectors (can be null, so selecctor will be set to default)
	* param: Object, options: Options of the ListSelector.
        	"includeDisabled": default is true
        	"dropShadow" : default is true,
        	"selectAll" : default is 0
	* return: void
	*************************************************************************/
	var setup = function (processForm, checkboxName, hotspot, selectors, options) {
		// Register the selector in the static variable of the API
		if (!listSelectors[processForm.id]) {
			listSelectors[processForm.id]= {};
		}
		listSelectors[processForm.id][checkboxName] = new ListSelector(processForm, checkboxName, hotspot, selectors, options);

		return listSelectors[processForm.id][checkboxName];
	};

	/*************************************************************************
	* Return a listSelector
	*
	* param: String, processFormID: form of the mass update
	* param: String, checkboxName: Name attribute of the checkbox
	* return: ListSelector
	*************************************************************************/
	var getListSelector = function (processFormID, checkboxName) {
		return listSelectors[processFormID] ? listSelectors[processFormID][checkboxName] : false;
	};

	return {

		// API Classes
		ListSelector : ListSelector,
		Selector : Selector,

		// API Methods
		setup : setup,
		getListSelector : getListSelector,
		checkOff : checkOff,
		disable : disable,

		// API variables
		listSelectors : listSelectors
	};
})();

ProfilePopupAPI = ( function() {
	return {
		/**
         * shows advisor profile popup
         *
         * @param {Element} el - element with the event that invokes this function
         * @param {Integer} objectID - ID of Object (Advisor and Client implemented
         * @param {String} roleAction - if present determines the popup type to use (if missing defaults to advisor popup)
         */
        showProfilePopup: function(el, objectID, generatedID, roleAction) {
    		var objectLink = $(el.id)
				,objectType = el.getProperty("linkType").toString().ucWords()
	        	,colorCodeName = objectLink.getProperty("colorCodeName")
                ,profilePopup = $("Profile_" + objectID + "_" + generatedID)
	        	,coords = objectLink.getCoordinates()
                ,profileWidth = (objectType == "Advisors") ? 565 : 410
                ,profileHeight = (objectType == "Advisors") ? 315 : 258
                ,winSize = window.getSize()
            	,popupOffScreenWidth = parseInt(coords.right + profileWidth + 5)
            	,requestIDInput = $("requestID");

			if (popupOffScreenWidth < winSize.x) {
				var popupPositionLeft = parseInt(coords.right + 5), popupDirection = "Right";
			} else {
				var popupPositionLeft = parseInt((coords.left - profileWidth) - ((objectType == "Advisors") ? 25 : 15)), popupDirection = "Left";
			}

			if (objectType == "Advisors") {
				var popupDirectionClass = "profilePopup" + objectType + popupDirection;
			} else {
				var popupDirectionClass = "profilePopup" + popupDirection;
			}

			
			objectLink.setProperty("isOverLink", "Y");

        	if (profilePopup) {
	            ( function() {
                    if (objectLink.getProperty("isOverLink") == "Y") profilePopup.setStyle("left", popupPositionLeft).removeClass("hidden");
                }).delay(150);
        	} else {
        		var data = {
					objectID: objectID
					,generatedID: generatedID
					,popupDirection: popupDirection
					,requestID: (requestIDInput) ? parseInt(requestIDInput.value) : ""
        		};

        		var options = {
					override_cache: true
					,onComplete: function(obj) {
		                var profilePopup = new Element("div", { id: "Profile_" + objectID + "_" + generatedID, "class": "profilePopup " + popupDirectionClass + " hidden", isOverProfile: "N"
			                ,styles: { width: profileWidth, height: profileHeight, top: parseInt(coords.top - 20), left: popupPositionLeft }
			                ,events: {
				                mouseenter: function() {
				                	objectLink.setProperty("isOverLink", "N");
				                	this.setProperty("isOverProfile", "Y");
				                }
				                ,mouseleave: function() {
				                	this.setProperty("isOverProfile", "N");
									ProfilePopupAPI.hideProfilePopup(el, objectID, generatedID);
				                }
			               }
			            }).set("html", obj["html"]).inject(document.body);

	            		( function() {
                            if (objectLink.getProperty("isOverLink") == "Y") {
                            	profilePopup.removeClass("hidden");
								if (objectType != "Advisors") {
									$("ProfileName_" + objectID + "_" + generatedID).setStyle("width", 360);
									profilePopup.getElements(".left").setStyle("width", 388);
								}
                            }
                         }).delay(150);
					}
				};

				if (roleAction != null && roleAction == 'showClientCard') {
					API.request("/clients/profilePopup/" + $random(1, 100), data, options);
				} else {
					API.request("/advisors/profilePopup/" + $random(1, 100), data, options);
				}
        	}
        },

        /**
         * delays call to hide function to allow time to hover over profile popup
         *
         * @param {Element} el - element with the event that invokes this function
         * @param {Integer} advisorID - ID of Advisor
         * @param {Integer} generatedID - random generated ID
         */
        delayHidingProfilePopup: function(el, advisorID, generatedID) {
        	el.setProperty("isOverLink", "N");
			( function() { ProfilePopupAPI.hideProfilePopup(el, advisorID, generatedID); }).delay(100);
        },

        /**
         * shows Advisor VCard from profile popup
         *
         * @param {Element} el - element with the event that invokes this function
         * @param {Integer} advisorID - ID of Advisor
         * @param {String} fullNameJS
         * @param {Integer} generatedID - random generated ID
         */
        showAdvCard: function(el, advisorID, fullNameJS, generatedID) {
	        $("Profile_" + advisorID + "_" + generatedID).setProperty("isOverProfile", "N");
            ProfilePopupAPI.hideProfilePopup(el, advisorID, generatedID);
        	VCardAPI.showAdvisorCard(el, advisorID, fullNameJS);
        },

        /**
         * shows Emails Popup from profile popup
         *
         * @param {Element} el - element with the event that invokes this function
         * @param {Integer} advisorID - ID of Advisor
         * @param {String} fullNameJS
         * @param {Integer} generatedID - random generated ID
         */
        showAdvEmails: function (el, advisorID, fullNameJS, generatedID) {
	        $("Profile_" + advisorID + "_" + generatedID).setProperty("isOverProfile", "N");
	        ProfilePopupAPI.hideProfilePopup($('advisor_' + advisorID + '_' + generatedID), advisorID, generatedID);
			EmailPopupsAPI.showEmailMessagePopup(el, {url : '/emails/buildPMAdvisorEmailPopup/', to_id : advisorID, to_role: 'Advisor', 'filter_set': 'PMtoAdvisor', 'title': fullNameJS + ' Emails' });
        },

        /**
         * close profile popup from profile popup
         *
         * @param {Integer} advisorID - ID of Advisor
         * @param {Integer} generatedID - random generated ID
         */
        closeProfilePopup: function(advisorID, generatedID) {
        	$$("div[id=Profile_" + advisorID + "_" + generatedID + "]").destroy();
        },

        /**
         * hides profile popup
         *
         * @param {Element} el - element with the event that invokes this function
         * @param {Integer} advisorID - ID of Advisor
         * @param {Integer} generatedID - random generated ID
         */
        hideProfilePopup: function(el, advisorID, generatedID) {
        	var profilePopup = $("Profile_" + advisorID + "_" + generatedID)
                ,isOverLink = $(el.id).getProperty("isOverLink");

        	if (profilePopup && profilePopup.getProperty("isOverProfile") == "N" && isOverLink == "N") {
        		profilePopup.addClass("hidden");
        	}
        },

		showAdvisorColorLegend: function(el) {
			var colorLegendPopupWidth = 400
				,colorLegendPopupHeight = 185
				,elIDSplit = el.id.split("_")
				,location = el.getCoordinates();

			var colorLegendPopupWrapper = new Element("div", { id: "ColorLegendPopupWrapper_" + elIDSplit[1] + "_" + elIDSplit[2]
				,styles: { background: "#ffffff", position: "absolute", left: parseInt(location.right + 3), top: parseInt(location.top - (colorLegendPopupHeight / 2)) }
			});

			var colorLegendPopupTitle = new Element("div", { "class": "paddingTopMini paddingBottomMini paddingLeftMini"
				,styles: { background: "#33739A", color: "#ffffff", "font-size": 14, "font-weight": "bold" }
			 }).set("text", "Advisor Link Color Legend").adopt(closeBtn);

			var closeBtn = new Element("span", { "class": "popupClose", title: "Close"
				,styles: { "top": 3 }
				,events: { click: function() { colorLegendPopupWrapper.destroy(); } }
			});

			var advisorRedLegend = new Element("span", { "class": "advisorLinkColorLegend advisorLinkColorLegendRed" }).set("html", "&nbsp;");
			var advisorRedSpan = new Element("span", { "class": "advisorLinkColorLegendText" }).set("text", "On DNC List or Compliance or Invalid Email or Deleted or Opted-Out or Terms & Conditions or Doesn't Participate in Cosultations");
			var advisorRedDiv = new Element("div", { "class": "marginTopMini" }).adopt(advisorRedLegend, advisorRedSpan);

			var advisorPurpleLegend = new Element("span", { "class": "advisorLinkColorLegend advisorLinkColorLegendPurple" }).set("html", "&nbsp;");
			var advisorPurpleSpan = new Element("span", { "class": "advisorLinkColorLegendText" }).set("text", "Special Notes or Requires Translator");
			var advisorPurpleDiv = new Element("div", { "class": "marginTopMini" }).adopt(advisorPurpleLegend, advisorPurpleSpan);

			var advisorBlackLegend = new Element("span", { "class": "advisorLinkColorLegend advisorLinkColorLegendBlack" }).set("html", "&nbsp;");
			var advisorBlackSpan = new Element("span", { "class": "advisorLinkColorLegendText" }).set("text", "Pending");
			var advisorBlackDiv = new Element("div", { "class": "marginTopMini" }).adopt(advisorBlackLegend, advisorBlackSpan);

			var advisorPinkLegend = new Element("span", { "class": "advisorLinkColorLegend advisorLinkColorLegendPink" }).set("html", "&nbsp;");
			var advisorPinkSpan = new Element("span", { "class": "advisorLinkColorLegendText" }).set("text", "Point Person");
			var advisorPinkDiv = new Element("div", { "class": "marginTopMini" }).adopt(advisorPinkLegend, advisorPinkSpan);

			var advisorGreenLegend = new Element("span", { "class": "advisorLinkColorLegend advisorLinkColorLegendGreen" }).set("html", "&nbsp;");
			var advisorGreenSpan = new Element("span", { "class": "advisorLinkColorLegendText" }).set("text", "First Consult or Custom Recruit");
			var advisorGreenDiv = new Element("div", { "class": "marginTopMini" }).adopt(advisorGreenLegend, advisorGreenSpan);

			var advisorOrangeLegend = new Element("span", { "class": "advisorLinkColorLegend advisorLinkColorLegendOrange" }).set("html", "&nbsp;");
			var advisorOrangeSpan = new Element("span", { "class": "advisorLinkColorLegendText" }).set("text", "Advisor needs to update their profile");
			var advisorOrangeDiv = new Element("div", { "class": "marginTopMini" }).adopt(advisorOrangeLegend, advisorOrangeSpan);

			var advisorBlueLegend = new Element("span", { "class": "advisorLinkColorLegend advisorLinkColorLegendBlue" }).set("html", "&nbsp;");
			var advisorBlueSpan = new Element("span", { "class": "advisorLinkColorLegendText" }).set("text", "Default");
			var advisorBlueDiv = new Element("div", { "class": "marginTopMini" }).adopt(advisorBlueLegend, advisorBlueSpan);

			var colorLegendPopup = new Element("div", { id: "ColorLegendPopup", "class": "popupInfo left"
    			,styles: { width: colorLegendPopupWidth, height: colorLegendPopupHeight, position: "relative", zIndex: 20000 }
    		}).adopt(colorLegendPopupTitle, advisorRedDiv, advisorPurpleDiv, advisorBlackDiv, advisorGreenDiv, advisorPinkDiv, advisorOrangeDiv, advisorBlueDiv);

    		colorLegendPopupWrapper.adopt(colorLegendPopup).inject(document.body);

			Popups.dropShadow(colorLegendPopup);
		},

		hideAdvisorColorLegend: function(el) {
			var elIDSplit = el.id.split("_");
			$("ColorLegendPopupWrapper_" + elIDSplit[1] + "_" + elIDSplit[2]).destroy();
		}
	};
})();

CommentPopupAPI = ( function() {
	return {
		/**
         * shows comment popup
         *
         * @param {Element} el - element with the event that invokes this function
         * @param {Integer} advisorID - ID of Advisor
         */
        showCommentPopup: function(el, advisorID, generatedID, reviewID) {
	        var link = $(el.id)
	        	,linkGeneratedID = ((generatedID) ? "_" + generatedID : "")
                ,commentPopup = $("Comment_" + advisorID + linkGeneratedID)
	        	,coords = link.getCoordinates()
                ,commentWidth = 410
                ,commentHeight = 240
                ,winSize = window.getSize()
            	,commentOffScreenWidth = parseInt(coords.right + commentWidth + 5);

			if (commentOffScreenWidth < winSize.x) {
				var commentPositionLeft = parseInt(coords.right + 5), commentDirection = "Right";
			} else {
				var commentPositionLeft = parseInt((coords.left - commentWidth) - 10), commentDirection = "Left";
			}

			link.setProperty("isOverLink", "Y");

        	if (commentPopup) {
	            ( function() {
                    if (link.getProperty("isOverLink") == "Y") commentPopup.setStyle("left", commentPositionLeft).removeClass("hidden");
                }).delay(150);
        	} else {
        		var data = {
					advisorID: advisorID
					,generatedID: linkGeneratedID
					,commentDirection: commentDirection
					,reviewID: reviewID
        		};

        		var options = {
					override_cache: true
					,onComplete: function(obj) {
		                var closeBtn = new Element("span", {
		                	"class": "popupClose popupProfileClose" + commentDirection
		                	,events: { click: function() {
		                		CommentPopupAPI.closeCommentPopup(advisorID, generatedID);
							} }
						});

						var comment = new Element("div", { "class": "popupComment" }).set("html", obj);

						var commentPopup = new Element("div", { id: "Comment_" + advisorID + linkGeneratedID, "class": "profilePopup profilePopup" + commentDirection + " hidden", isOverComment: "N"
			                ,styles: { width: commentWidth, height: commentHeight, position: "absolute", top: parseInt(coords.top - 20), left: commentPositionLeft }
			                ,events: {
				                mouseenter: function() {
				                	link.setProperty("isOverLink", "N");
				                	this.setProperty("isOverComment", "Y");
				                }
				                ,mouseleave: function() {
				                	this.setProperty("isOverComment", "N");
									CommentPopupAPI.hideCommentPopup(el, advisorID, generatedID);
				                }
			               }
			            }).adopt(closeBtn, comment).inject(document.body);

	            		( function() {
                            if (link.getProperty("isOverLink") == "Y") commentPopup.removeClass("hidden");
                        }).delay(150);
					}
				};

	            API.request("/advisors/getReviewComment/" + $random(1, 100), data, options);
        	}
        },

        /**
         * delays call to hide function to allow time to hover over comment popup
         *
         * @param {Integer} advisorID - ID of Advisor
         */
        delayHidingCommentPopup: function(el, advisorID, generatedID) {
        	el.setProperty("isOverLink", "N");
			( function() { CommentPopupAPI.hideCommentPopup(el, advisorID, generatedID); }).delay(100);
        },

        /**
         * close comment popup
         *
         * @param {Integer} advisorID
         */
        closeCommentPopup: function(advisorID, generatedID) {
        	var linkGeneratedID = ((generatedID) ? "_" + generatedID : "");
        	$$("div[id=Comment_" + advisorID + linkGeneratedID + "]").destroy();
        	//$("Comment_" + advisorID + linkGeneratedID).setProperty("isOverComment", "N").addClass("hidden");
        },


        /**
         * hides comment popup
         *
         * @param {Integer} advisorID - ID of Advisor
         */
        hideCommentPopup: function(el, advisorID, generatedID) {
        	var linkGeneratedID = ((generatedID) ? "_" + generatedID : "")
        		,commentPopup = $("Comment_" + advisorID + linkGeneratedID)
                ,isOverLink = $(el.id).getProperty("isOverLink");

        	if (commentPopup && commentPopup.getProperty("isOverComment") == "N" && isOverLink == "N") {
        		commentPopup.addClass("hidden");
        	}
        }
	};
})();


NotesPopupAPI = ( function() {
	return {
		/**
         * shows comment popup
         *
         * @param {Element} el - element with the event that invokes this function
         * @param {Integer} advisorID - ID of Advisor
         */
        showNotePopup: function(el, advisorID, generatedID, noteID) {
	        var link = $(el.id)
	        	,linkGeneratedID = ((generatedID) ? "_" + generatedID : "")
                ,commentPopup = $("Comment_" + advisorID + linkGeneratedID)
	        	,coords = link.getCoordinates()
                ,commentWidth = 410
                ,commentHeight = 240
                ,winSize = window.getSize()
            	,commentOffScreenWidth = parseInt(coords.right + commentWidth + 5);

			if (commentOffScreenWidth < winSize.x) {
				var commentPositionLeft = parseInt(coords.right + 5), commentDirection = "Right";
			} else {
				var commentPositionLeft = parseInt((coords.left - commentWidth) - 10), commentDirection = "Left";
			}

			link.setProperty("isOverLink", "Y");

        	if (commentPopup) {
	            ( function() {
                    if (link.getProperty("isOverLink") == "Y") commentPopup.setStyle("left", commentPositionLeft).removeClass("hidden");
                }).delay(150);
        	} else {
        		var data = {
					advisorID: advisorID
					,generatedID: linkGeneratedID
					,commentDirection: commentDirection
					,noteID: noteID
        		};

        		var options = {
					override_cache: true
					,onComplete: function(obj) {
		                var closeBtn = new Element("span", {
		                	"class": "popupClose popupProfileClose" + commentDirection
		                	,events: { click: function() {
		                		CommentPopupAPI.closeCommentPopup(advisorID, generatedID);
							} }
						});

						var comment = new Element("div", { "class": "popupComment" }).set("html", obj);

						var commentPopup = new Element("div", { id: "Comment_" + advisorID + linkGeneratedID, "class": "profilePopup profilePopup" + commentDirection + " hidden", isOverComment: "N"
			                ,styles: { width: commentWidth, height: commentHeight, position: "absolute", top: parseInt(coords.top - 20), left: commentPositionLeft }
			                ,events: {
				                mouseenter: function() {
				                	link.setProperty("isOverLink", "N");
				                	this.setProperty("isOverComment", "Y");
				                }
				                ,mouseleave: function() {
				                	this.setProperty("isOverComment", "N");
									CommentPopupAPI.hideCommentPopup(el, advisorID, generatedID);
				                }
			               }
			            }).adopt(closeBtn, comment).inject(document.body);

	            		( function() {
                            if (link.getProperty("isOverLink") == "Y") commentPopup.removeClass("hidden");
                        }).delay(150);
					}
				};

	            API.request("/home/getNoteComment/0", data, options);
        	}
        },

        /**
         * delays call to hide function to allow time to hover over comment popup
         *
         * @param {Integer} advisorID - ID of Advisor
         */
        delayHidingCommentPopup: function(el, advisorID, generatedID) {
        	el.setProperty("isOverLink", "N");
			( function() { CommentPopupAPI.hideCommentPopup(el, advisorID, generatedID); }).delay(100);
        },

        /**
         * close comment popup
         *
         * @param {Integer} advisorID
         */
        closeCommentPopup: function(advisorID, generatedID) {
        	var linkGeneratedID = ((generatedID) ? "_" + generatedID : "");
        	$$("div[id=Comment_" + advisorID + linkGeneratedID + "]").destroy();
        	//$("Comment_" + advisorID + linkGeneratedID).setProperty("isOverComment", "N").addClass("hidden");
        },


        /**
         * hides comment popup
         *
         * @param {Integer} advisorID - ID of Advisor
         */
        hideCommentPopup: function(el, advisorID, generatedID) {
        	var linkGeneratedID = ((generatedID) ? "_" + generatedID : "")
        		,commentPopup = $("Comment_" + advisorID + linkGeneratedID)
                ,isOverLink = $(el.id).getProperty("isOverLink");

        	if (commentPopup && commentPopup.getProperty("isOverComment") == "N" && isOverLink == "N") {
        		commentPopup.addClass("hidden");
        	}
        }
	};
})();


