// namespace
$.RGA = {
	global: {}
};

//IE does not support the trim() function. Here's a fix
if (typeof String.prototype.trim !== 'function') {
    String.prototype.trim = function() {
        return this.replace(/^\s+|\s+$/g, '');
    }
}

$(document).ready(function(){
    //change to window.load at a later point
    // FADE IN, IE uses a page transition via a meta tag in the conditional comments
	if(!$.browser.msie) {
		var $container = $("#rga-container");
			//$container.fadeOut(0);
			$container.fadeIn(400);
		
		$(".fadeLink").live('click', function(e) {
			e.preventDefault();
			var link = this;
			$container.fadeOut(200, function() {
				document.location = link.href;							 
			});
		});
	}
});

$(document).ready(function() {
    $.RGA.global.isIPad = ($('html').hasClass('ipad'));    
    if ($.browser.safari) {
        $("body").addClass("webkit");
    };

    // initialize header
    if ($("body").hasClass("home")) {
        $.RGA.global.Header = new $.RGA.Header({ mode: "static" });
    } else {
        $.RGA.global.Header = new $.RGA.Header();
    }
    // initialize contact section
    new $.RGA.ContactSection();

    $.RGA.global.RfiManager = new $.RGA.RfiManager();

    $.RGA.global.Tracking = new $.RGA.Tracking();
    var $body = $("body");
    if ($body.hasClass("home")) {
        //check for presence of hash is present and that the item exists on page
        var hash = encodeURIComponent(document.location.hash); if (!hash) {	        //track if this isn't true
            $.RGA.global.Tracking.trackPageView();
        }
    } else if ($body.hasClass("newsIndex") || $body.hasClass("workIndex") || $body.hasClass("awards")) {
        var qs = document.location.search;
        if (!qs)
            $.RGA.global.Tracking.trackPageView();
    }
    else {
        //do the default page view track	
        $.RGA.global.Tracking.trackPageView();
    }

    if (document.getElementById('share')) {
        $.RGA.global.ShareUtilities = new $.RGA.ShareUtilities();
    }

    $(window).resize(doResize);

    //wire up all the event links for tracking
    $('#content .extEventLink').click(function(e) {
        $.RGA.global.Tracking.trackPageView('/news/event/' + encodeURIComponent($(this).text()));
    });

    //wire up related link tracking
    $('#related a').click(function(e) {
        $.RGA.global.Tracking.trackRelatedLinkEvent(this);
    });

    var 
	    resizeTimer = null,
	    resizeCookie = {
	        key: "pageSize",
	        val: null,
	        opts: {
	            path: "/"
	        },

	        init: function() {
	            this.val = this.get();
	        },

	        //returns null if cookie does not exist
	        get: function() {
	            return $.cookie(this.key);
	        },

	        set: function(val) {
	            this.val = val;
	            $.cookie(this.key, this.val, this.opts);
	        }
	    };
    resizeCookie.init();

    function doResize() {
        clearTimeout(resizeTimer);
        resizeTimer = setTimeout(resizeComplete, 200);
    }
    function resizeComplete() {

        var cont = $("#rga-container");
        var $html = $("html");
        var $body = $("body");
        var winWidth = $(window).width();
        var scrollbarWidth = ($(window).height() < $("#rga-container").height() + 148) ? $.ScrollBar.getWidth() : 0;
        var maxWidth = 1528;
        var medWidth = ($.browser.msie ? 1270 : 1280) - scrollbarWidth; //IE adds in extra padding
        var minWidth = 995;
        var cookieval = "";

        $body.css("overflowX", "hidden");

        if (winWidth > maxWidth) {
            cont.removeClass("small").removeClass("medium").addClass("large");
            $html.removeClass("small").removeClass("medium").addClass("large");
            cookieval = "large";
        } else if (winWidth >= medWidth) {
            cont.removeClass("small").removeClass("large").addClass("medium");
            $html.removeClass("small").removeClass("large").addClass("medium");
            cookieval = "medium";
        } else {
            cont.removeClass("large").removeClass("medium").addClass("small");
            $html.removeClass("large").removeClass("medium").addClass("small");
            cookieval = "small";
            $body.css("overflowX", "visible");
        }

        $(document).trigger("resizeComplete");
        resizeCookie.set(cookieval);
    }

    resizeComplete();

    $('input.checkbox').each(function() {
        new $.Checkbox({ container: $(this).parent(), manager: '$.CheckboxManagerObj' });
    });

    // CLOSE BTN
    $.CloseButton.init();


    $('#share #email').live("click", function(e) {
        e.preventDefault();
        var o = new $.Overlay({ blockerOpacity: 0.2, closeButton: '' });
        o.setContent($('#' + this.id + 'Overlay'));
        o.show();
        var responseMsg = '';
        var oc = $("#overlayContainer");
        $.RGA.global.Tracking.trackPageView("/share/email");

        new $.AjaxForm(oc.find("#sendAFriendOverlayForm"), {
            onSuccess: function(response) {
                responseMsg = oc.find(".sentSuccessMesssage");
                oc.find(".sendButton").val("Send Again");
                $.RGA.global.Tracking.trackPageView("/share/email_sent");
            },
            onError: function(response) {
                responseMsg = oc.find(".sentErrorMesssage");
            },
            onComplete: function(response) {
                responseMsg.fadeIn('fast');
                setTimeout(function() { responseMsg.fadeOut('slow'); }, 5000);
            }
        });

    });

    $('#share #embed').live("click", function(e) {
        e.preventDefault();
        var o = new $.Overlay({ blockerOpacity: 0.2, closeButton: '' });
        o.setContent($('#' + this.id + 'Overlay'));
        o.show();
        $.RGA.global.Tracking.trackPageView("/share/embed");
    });

    $('#embedCode').live("click", function(e) {
        this.focus();
        this.select();
    });

    $('#controlBar #sharePresentation').live("click", function(e) {
        e.preventDefault();
        var o = new $.Overlay({ blockerOpacity: 0.2, closeButton: '' });
        o.setContent($('#' + this.id + 'Overlay'));
        o.show();
        var responseMsg = '';
        var oc = $("#overlayContainer");

        new $.AjaxForm(oc.find("#sharePresentationOverlayForm"), {
            onSuccess: function(response) {
                responseMsg = oc.find(".sentSuccessMesssage");
                oc.find(".sendButton").val("Send Again");
                $.RGA.global.Tracking.trackPageView("/collection/share_your_collection");
            },
            onError: function(response) {
                responseMsg = oc.find(".sentErrorMesssage");
            },
            onComplete: function(response) {
                responseMsg.fadeIn('fast');
                setTimeout(function() { responseMsg.fadeOut('slow'); }, 5000);
            }
        });

    });

    $('#prevButton a, #nextButton a').live('mousedown', function(e) {
        $(this).addClass('down');
    }).live('mouseup', function(e) {
        $(this).removeClass('down');
    });

});


$.RGA.HideContent = function(){
    //hide as soon as possible for better transition   
    if (!$.browser.msie) $("#rga-container").hide();
}; 

$.RGA.ContactSection = function() {
	_adjust()
	
	$(window).resize(function(){
		_adjust();
	});
	
	function _adjust() {
		var $sectionContainer = $("#footer .sectionContainer");
		var $adjustedHeight = $(window).height() - $("#header").height() + 20;
		
		if($sectionContainer.height() < $adjustedHeight) {
			$sectionContainer.height($adjustedHeight);	
		}
	}	
	
	var sendAMessage = $("#sendAMessageForm");
	var responseMsg = "";
	if (sendAMessage.get(0)) new $.AjaxForm(sendAMessage, {
		onSuccess : function(response){
			responseMsg = $("#sentSuccessMesssage");
			$("#submit > input").val("Send Again");
			$.RGA.global.Tracking.trackPageView("/send_us_a_message");
		},
		onError : function(response){
			responseMsg = $("#sentErrorMesssage");
		},
		onComplete : function(response){
			responseMsg.fadeIn('fast');
			setTimeout(function(){responseMsg.fadeOut('slow');}, 5000);
		}
	});
	
}

$.RGA.Tracking = function() {
	var pageTracker = 0,
	self = this,
	settings = {
	    prefix: "/rga_2010"
	};
	//dev - UA-11419981-1 | live - UA-796906-1
	try{ pageTracker = _gat._getTracker("UA-796906-1");} catch(e){};
	
    this.trackFlashEvent = function(category,action,optlabel){
        this.trackEvent(category,action,optlabel);
    };
    this.trackPageViewWithRedirect = function(name,url){
		//slow down the request so that it has time to register
		setTimeout(function(){
		    $.RGA.global.Tracking.trackPageView(name);
		    window.location = url;
		},200);
	};
	this.trackRelatedLinkEvent = function(link){
	    $link = $(link);
	    $.RGA.global.Tracking.trackEvent('related_link','/go_to_url'+$link.attr('href'));
	};
	this.trackPageView = function(name){
	    //check if in collection mode
	    var inPresentationMode = (document.getElementById && document.getElementById("controlBar"));

		if (pageTracker){
			if(name!=undefined)
			    pageTracker._trackPageview(settings.prefix+name+(inPresentationMode?"/presentationMode":""));
			else
			    pageTracker._trackPageview(settings.prefix+document.location.pathname+(inPresentationMode?"/presentationMode":""));
		}
		
		//check for search term and add tracking event if present
		var qs = new $.QueryString();
		if(qs.get('searchTerm'))
		    $.RGA.global.Tracking.trackEvent('search',qs.get('searchTerm'));
		
	};
	this.trackHomepageTout = function(toutIndex,url){
	    if(url!=undefined)
	        $.RGA.global.Tracking.trackEventWithRedirect('tout',toutIndex,url);
	    else
	        $.RGA.global.Tracking.trackEvent('tout',toutIndex);
	};
	this.trackEventWithRedirect = function(category,action,url,optlabel){
		//slow down the request so that it has time to register
		setTimeout(function(){
		    $.RGA.global.Tracking.trackEvent(category,action,optlabel);
		    window.location = url;
		},200);
	};
	this.trackContactSectionLink = function(name){	    
	    var path = document.location.pathname;	    
	    if(path=="/" || path==""){
	        path = "/home";
	    }
	    $.RGA.global.Tracking.trackPageView(path+'/contact/'+name);
	};
	this.trackEvent = function(category,action,optlabel){
     	//check if in collection mode
	    var inPresentationMode = (document.getElementById && document.getElementById("controlBar"));

		if (pageTracker)
        {
          if(optlabel!=undefined)
    	        pageTracker._trackEvent(category,action,optlabel);
	      else
	            pageTracker._trackEvent(category,action,settings.prefix+document.location.pathname+(inPresentationMode?"/presentationMode":""));
		}
	};	
}

$.RGA.ShareUtilities = function() {    
    var settings = $.extend({
		container: $("#share"),
		shareUrl: window.document.location,
		shareTitle: window.document.title,
		shareBody: ""
	});
    
    //init
    settings.container.find("#printLink").click(function(e){
		$.RGA.global.Tracking.trackPageView("/share/print");
        window.print();
    });
	
	//bind all share links
	var $shareListLIs = settings.container.find("ul.shareLinks a");		
	
	$shareListLIs.each(function(index, itm) {
		var href = $(itm).attr("href");
		href = href.replace("@@@PAGEHREF@@@", encodeURIComponent(settings.shareUrl));
		href = href.replace("@@@PAGETITLE@@@", encodeURIComponent(settings.shareTitle));
		href = href.replace("@@@BODYTEXT@@@", encodeURIComponent(settings.shareBody));
		$(itm).attr("href", href);
	});	
}

$.RGA.Search = function() {
	// INIT
	var $searchWrap = $("#searchWrap");
	var $searchForm = $("#search");	
	var	$input = $searchForm.find("input");
	var $searchResults = $("#searchResults");
	var cta = "Search";
	var noResultsMsg = "No results matching your search terms were found.";
	var resultsOpen = 0;
	$input.val(cta);
	
	// BIND EVENTS
	$searchForm.submit(doSearch);
	$input.focus(doFocus);
	$input.blur(doBlur);
	
	var timeout = null;
	$input.keyup(function(e) {
		clearTimeout(timeout);
		timeout = setTimeout(function() {
			doSearch();
		}, 300);
	});
	
	//prevent form submission 
	$searchForm.submit(function(e){
	    e.preventDefault();
	});
	
	$searchWrap.live("keydown",function(e){
		if (resultsOpen){
			if (e.keyCode == 13){
				e.preventDefault();
				var a = $("#searchPageLink").get(0);
				if (a) window.location = a.href;
			}
			else if (e.keyCode == 27){
				e.preventDefault();
				_close();
				$input.blur();
			}
		}
	});
	
	function doSearch() {
		
		var val = $input.val();
		
		if (val.length > 0){
			$.ajax({
				url : "/service/search/" + val,
				method : "POST",
				success : function(response){
					var html = response.length ? response : noResultsMsg;
					$searchResults.html(html);
				},
				error : function(){
					$searchResults.html(noResultsMsg);
				},
				complete : function(){
					_showResults();
				}
			});
		}
		else {
			$searchResults.hide();
		}
	}
	
	function doFocus() {
		$searchWrap.addClass("alert");
		
		if($input.val() == cta) {
			$input.val("");	
		}
	}
	
	function doBlur() {
        //delay the blur function for 500ms to avoid it unfocus too soon and make the link unclickable
        setTimeout(function(){
		$searchWrap.removeClass("alert");
		
		//if($input.val() == "") {
			$input.val(cta);	
			_hideResults();
		//}
		},500);
	}
	
	function _close() {
		$searchWrap.removeClass("alert");
	}
	
	function _showResults(){
		$searchResults.show();
		if ( $.browser.msie )
			{
			$("div#searchResults ul li a.vid-link").css("background","none");
			$("div#searchResults ul li a.vid-link").append('<img src="/_assets/img/Icon_Video_Default_14px.gif" />'); 
			$("div#searchResults ul li a.vid-link img").css({'display':'inline','position':'relative','top':'2px','left':'5px'});
			var img_on="/_assets/img/Icon_Video_Hover_14px.gif", img_off="/_assets/img/Icon_Video_Default_14px.gif";
			$("div#searchResults ul li a.vid-link").hover(
	    		function(){
				$(this).find('img').attr("src",img_on);
				}, 
	  			function()
	    		{
	    		$(this).find('img').attr("src",img_off);
	    	});
	}
		resultsOpen = 1;
	}
	
	function _hideResults(){
		$searchResults.hide();
		resultsOpen = 0;
	}
}

$.RGA.Header = function(options) {
    var settings = $.extend({
        mode: ""
    }, options);

    // INITIALIATION
    var $menu = $("#menu");
    var $menuLinks = $("#menu a");
    var $content = $("#content");
    var $contentContainer = $("#contentContainer");

    new $.RGA.Search();

    if ($('body').hasClass("inner")) {
        $menu.css({ opacity: 0, height: 29 });

        //set link href		
        $('#menu li a').each(function() {
            this.href = '/' + $(this).attr('href');
        });
    }

    $menuLinks.click(scrollPage);

    //if we enter a URL containing a hash, make it active and scroll to it
    var $active = $("#menu a[href='" + window.location.hash + "']");
    $active.addClass("active");
    $(window).load(function() {
        $active.click();
    });

    // BIND EVENTS

    //bind function to focus (menu)
    if (settings.mode != "static") {
        $menuLinks.bind("focus", expandMenu);
        $menuLinks.bind("blur", collapseMenu);
    }

    var hash = window.location.hash;
    setInterval(function() {
        if (window.location.hash != hash) {
            hash = window.location.hash;
            $menuLinks.removeClass("active");
            $("#menu a[href='" + window.location.hash + "']").addClass("active");
            if (!$.browser.msie) {
                $("#menu a[href='" + window.location.hash + "']").click();
            }
        }
    }, 100);

    // private functions
    function scrollPage(e) {
        e.preventDefault(e);

        $menuLinks.removeClass("active");
        e.target.className += " active";
        //SCROLL HANDLING
        //get the href value
        var whereTo = $(this).attr("href");
        var targetLink = whereTo.substring(1); //remove hash
        var offset = parseInt($("#header").css("height"));

        //if there is a div on this page where id = whereTo, then scroll to it
        if ($("#" + targetLink).text() != '') {
            $("#" + targetLink).css("padding-top", 14);
            $.scrollTo($("#" + targetLink), 1000, { axis: 'y', easing: '',

                onAfter: function(whereTo) {
                    setTimeout(function() {
                        window.location.hash = targetLink;
                        hash = window.location.hash;
                        $.RGA.global.Tracking.trackPageView('/home/' + targetLink);
                    }, 100);
                }
            });
        } else {
            window.location = rootPath + whereTo;
        }
    }

    var menuTimeout;
    //show all menu options onmouseover
    //only if it is an inner page
    if ($('body').hasClass("inner")) {
        $('#header').hover(function() {
            clearTimeout(menuTimeout);
            menuTimeout = setTimeout(expandMenu, 300);
        }, collapseMenu);
        $menuLinks.css("display", "none");
    }

    var contentContainerCap = parseInt($contentContainer.position().top) + 46;
    //alert(expandCap);

    //function for rollover
    function expandMenu() {
        $menu.stop();
        $menu.animate({ height: "75px" }, 400, function() {
            $menuLinks.css("display", "block");
            $menu.css('visibility', 'visible');
            $menu.animate({ opacity: 1 }, 200);
        });
        $contentContainer.stop();
        $contentContainer.animate({ paddingTop: contentContainerCap + "px" }, 400);
    }

    //function for rollout
    function collapseMenu() {
        clearTimeout(menuTimeout);
        $menu.stop();
        $contentContainer.stop();
        $menu.animate({ opacity: 0 }, 200, function() {
            $menuLinks.css("display", "none");
            $menu.animate({ height: "29px" }, 400);
            $contentContainer.animate({ paddingTop: (contentContainerCap - 46) + "px" }, 400);
        });
    }
};

(function($) {

    $.ScrollBar = {

        width: null,

        getWidth: function() {
            if (this.width == null) this.width = this.calculateWidth();

            return this.width;
        },

        calculateWidth: function() {

            var inner = document.createElement('p');
            inner.style.width = "100%";
            inner.style.height = "200px";

            var outer = document.createElement('div');
            outer.style.position = "absolute";
            outer.style.top = "0px";
            outer.style.left = "0px";
            outer.style.visibility = "hidden";
            outer.style.width = "200px";
            outer.style.height = "150px";
            outer.style.overflow = "hidden";
            outer.appendChild(inner);

            document.body.appendChild(outer);
            var w1 = inner.offsetWidth;
            outer.style.overflow = "scroll";
            var w2 = inner.offsetWidth;
            if (w1 == w2) w2 = outer.clientWidth;

            document.body.removeChild(outer);

            return (w1 - w2);
        }
    };

    $.CloseButton = {
        href: "/",
        anchor: "",
        id: "#pageClose",
        indexClasses: ["workIndex", "newsIndex"],
        cookieName: "lastIndex",
        cookieOpts: {
            path: "/"
        },
        init: function() {
            this.button = $(this.id);
            if (this.button.get(0)) {
                this.bindEvents();
            }

            if (this.href == "/") {
                //save the href
                this.href = this.button.attr('href');
            }
            this.setCookie();
        },

        bindEvents: function() {
            this.button.mousedown(function() {
                $(this).addClass("down");
            }).mouseup(function() {
                $(this).removeClass("down");
            }).mouseleave(function() {
                $(this).removeClass("down");
            });
        },

        setCookie: function() {
            var 
                $body = $("body"),
                isIndex = false;

            for (var i = 0; i < this.indexClasses.length; i++) {
                if ($body.hasClass(this.indexClasses[i])) {
                    $.cookie(this.cookieName, window.location.toString(), this.cookieOpts);
                    isIndex = true;
                    break;
                }
            }

            if (!isIndex) this.setHref();
        },

        setHref: function() {
            var 
	            lastIndex = $.cookie(this.cookieName);

            if (lastIndex != null) {
                this.button.attr("href", lastIndex);
                $.cookie(this.cookieName, null);
            }
        }
    };

    $.AjaxForm = function($form, params) {
        this.settings = $.extend({}, this.defaults, params);
        this.fields = $form.find("input:text, input:hidden, select, textarea");
        this.checkboxes = $form.find("input:checkbox");

        var self = this,
			method = this.settings.method || $form.attr("method"),
			url = this.settings.url || $form.attr("action"),
			stripTags = function() {
			    self.fields.each(function() {
			        var val = this.value;
			        this.value = val.replace(/</g, "&lt;").replace(/>/g, "&gt;");
			    });
			}

        $form.submit(function(e) {
            e.preventDefault();
            if (self.validate()) {
                stripTags();
                var datafields = $.param(self.fields);
                if (self.checkboxes.length)
                    datafields += "&" + self.stringifyCheckboxes();

                $.ajax({
                    url: url,
                    type: method,
                    data: datafields,
                    success: function(response) {
                        self.settings.onSuccess(response);
                    },
                    error: function(response) {
                        self.settings.onError(response);
                    },
                    complete: function(response) {
                        self.settings.onComplete(response);
                    }
                });
            }

        });

    };
    $.AjaxForm.prototype = {

        defaults: {
            requiredClass: "required",
            containerSelectors: ".textBox, .dropdown",
            errorSelector: ".error_state",
            errorClass: "error_state_active",
            onSuccess: function() { },
            onError: function() { },
            onComplete: function() { }
        },

        validate: function() {
            var self = this, errs = 0;

            this.fields.each(function() {
                var $this = $(this), err = 1;
                if (!$this.hasClass(self.settings.requiredClass) || self.checkSpecific($this)) {
                    $this.parents(self.settings.containerSelectors).find(self.settings.errorSelector).removeClass(self.settings.errorClass);
                    err = 0;
                }

                if (err) {
                    $this.parents(self.settings.containerSelectors).find(self.settings.errorSelector).addClass(self.settings.errorClass);
                    errs++;
                }
            });

            return errs ? false : true;
        },

        checkDefault: function($field) {
            return !(/[<>]+/.test($field.val()));
        },

        checkSpecific: function($field) {
            var valid = true;

            //split up multiple emails
            if ($field.hasClass('email')) {
                var emails = $field.val().trim().split(",");
                var i = 0;
                for (i = 0; i < emails.length; i++) {
                    var email = emails[i].trim();
                    valid = this.getCheckRegExp($field).test(email);
                }
            } else {
                valid = (this.getCheckRegExp($field).test($field.val()));
            }

            return valid;
        },

        getCheckRegExp: function($field) {
            var regExp = /.+/;
            if ($field.hasClass('email')) regExp = /^([a-zA-Z0-9])+([\.a-zA-Z0-9_-])*@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-]+)+$/;
            else if ($field.hasClass('alpha')) regExp = /^[a-zA-Z\s-'.]+$/;

            return regExp;
        },

        stringifyCheckboxes: function() {
            var str = "";
            this.checkboxes.each(function() {
                str += this.name + "=" + this.checked + "&";
            });

            return str.replace(/&$/, '');
        }
    };

    $.CheckboxManager = function(params) {
        var self = this, _checkboxes = {}, _count = 0, _liveClass = 'jq-cb';

        this.defaults = {
            checkedClass: 'cb-checked',
            focusedClass: 'cb-focused',
            container: 0,
            changeCallback: false
        }

        var settings = $.extend({}, self.defaults, params),
			liveInput = '.' + _liveClass + ' input';

        //start:events
        $('.' + _liveClass).live('click', function(e) {
            e.preventDefault();

            while (e.target.className.indexOf(_liveClass) == -1) {
                e.target = e.target.parentNode;
            }

            _toggle(_checkboxes[$(e.target).data('Id')]);

        });


        $(liveInput).live('keyup', function(e) {
            e.preventDefault();
            var $this = $(e.target);
            while (!$this.hasClass(_liveClass)) {
                $this = $this.parent();
            }

            if (e.keyCode == 32) {
                _toggle(_checkboxes[$this.data('Id')]);
            } else if (e.keyCode == 13) {
                var $form = $this.parents('form').eq(0);
                if ($form) {
                    $form.submit();
                }
            }
        });
        //end:events

        //start:public
        this.addCheckbox = function(checkbox) {
            checkbox.Id = _count;
            checkbox.settings.container.data("Id", _count);
            checkbox.settings.container.addClass(_liveClass);
            _checkboxes[_count] = checkbox;
            _count++;
        }
        //end:public

        //start:private
        function _toggle(checkbox) {
            if (checkbox.input.checked == true) {
                checkbox.input.checked = false;
                checkbox.settings.container.removeClass(checkbox.settings.checkedClass);
            } else {
                checkbox.input.checked = true;
                checkbox.settings.container.addClass(checkbox.settings.checkedClass);
            }

            checkbox.input.focus();

            if (typeof checkbox.settings.callBack == 'function') {
                checkbox.callBack();
            }
        }
        //end:private
    }

    /*
    params requirements {container:jQueryObj, manager:string}
    settings public to allow use in CheckboxManager
    */
    $.Checkbox = function(params) {

        if (!window[params.manager]) {
            window[params.manager] = new $.CheckboxManager();
        }

        this.settings = $.extend({}, window[params.manager].defaults, params);
        if (!this.settings.container || !this.settings.container.get(0)) return;

        var self = this, input = this.settings.container.find('input');

        this.input = input.get(0);

        if (this.input.checked == true) {
            this.settings.container.addClass(this.settings.checkedClass);
        }

        //Excluded from the manager since live does not currently support focus/blur
        input.focus(function() {
            self.settings.container.addClass(self.settings.focusedClass);
        }).blur(function() {
            self.settings.container.removeClass(self.settings.focusedClass);
        });

        window[params.manager].addCheckbox(this);
    };

    $.Overlay = function(params) {

        var 
			self = this,
			scrollTimeout,
			resizeTimeout;

        this.settings = $.extend({}, this.defaults, params);
        this.window = $(window);
        this.body = $(document.body);
        this.container = $("<div id='overlayContainer' class='overlay'></div>");
        this.open = 0;

        if (this.settings.content) {
            this.content = this.settings.content;
            this.appendContent();
        }

        //Events!
        this.window.resize(function() {
            if (self.open) {
                clearTimeout(resizeTimeout);
                resizeTimeout = setTimeout(function() {

                    if (self.blocker) {
                        self.adjustBlocker();
                    }

                    self.center(self.settings.animate);
                }, 350);
            }
        });

        if (this.settings.followScroll) {
            this.window.scroll(function() {
                if (self.open) {
                    clearTimeout(scrollTimeout);
                    scrollTimeout = setTimeout(function() {
                        self.center(self.settings.animate);
                    }, 350);
                }
            });
        }

        this.settings.initCallback();
    };
    $.Overlay.prototype = {

        defaults: {
            content: 0,
            zIndex: 10000,
            followScroll: 1,
            animate: 1,
            animateDuration: 500,
            animateEasing: "easeout",
            fade: 0,
            fadeDuration: 500,
            blocker: 1,
            blockerColor: "#000000",
            blockerOpacity: 0.35,
            blockerAdjust: {
                width: 0,
                height: 0
            },
            initCallback: function() { },
            showCallback: function() { },
            hideCallback: function() { },
            closeButton: "<a href='javascript:void(0)' class='close_button'>close</a>"
        },

        show: function() {

            if (this.settings.blocker) {
                this.createBlocker();
            }

            this.body.append(this.container);
            this.container.css({ zIndex: this.settings.zIndex, position: "absolute" });
            this.center();

            if (this.settings.fade) {
                this.fadeIn();
            }
            else {
                this.settings.showCallback();
            }

            this.bindCloseButton();
            this.open = 1;
            return this;

        },

        hide: function() {

            if (this.settings.fade) {
                this.fadeOut();

            }
            else {
                this.container.remove();

                if (this.blocker) {

                    this.blocker.remove();

                }

                this.settings.hideCallback();
            }

            this.open = 0;
            return this;

        },

        //accepts html string or $ extended element
        setContent: function(content) {
            this.content = content;
            this.appendContent();

            return this;
        },

        //should be called when overlay is already showing
        //will transition to the new content without dropping the blocker
        updateContent: function(content) {
            var self = this;
            this.content = content;

            if (this.settings.fade) {
                this.fadeOutContainer(function() {
                    self.appendContent();
                    self.bindCloseButton();
                    self.fadeInContainer();
                });
            }
            else {
                this.appendContent();
                this.bindCloseButton();
            }

            return this;
        },

        appendContent: function() {
            var html = "";

            if (typeof (this.content) == "string") {
                html = this.content;
            }
            else {
                html = this.content.html();
            }

            this.container.html(html + this.settings.closeButton);
        },

        center: function(animate) {
            var 
				cWidth = this.container.outerWidth(),
				cHeight = this.container.outerHeight(),
				scrollTop = this.settings.followScroll ? this.window.scrollTop() : 0,
				scrollLeft = this.settings.followScroll ? this.window.scrollLeft() : 0,
				top = (this.window.height() / 2) - (cHeight / 2) + scrollTop,
				left = (this.window.width() / 2) - (cWidth / 2) + scrollLeft,
				cTop = scrollTop, cLeft = scrollLeft;

            if (top > 0) {
                cTop = top;
            }

            if (left > 0) {
                cLeft = left;
            }

            if (animate) {
                this.container.stop();
                this.container.animate({
                    left: cLeft,
                    top: cTop
                }, {
                    duration: this.settings.animateDuration,
                    easing: this.settings.animateEasing
                });
            }
            else {
                this.container.css({
                    left: cLeft,
                    top: cTop
                });
            }
        },

        createBlocker: function() {
            this.body.append("<div id=\"overlayBlocker\"></div>");
            this.blocker = $("#overlayBlocker");
            this.blocker.css({
                backgroundColor: this.settings.blockerColor,
                opacity: this.settings.blockerOpacity,
                position: 'absolute',
                top: 0,
                left: 0,
                zIndex: this.settings.zIndex - 1
            });

            this.adjustBlocker();
        },

        adjustBlocker: function() {
            var 
				bWidth = this.body.outerWidth() + this.settings.blockerAdjust.width,
				bHeight = this.body.outerHeight() + this.settings.blockerAdjust.height,
				width = (bWidth > this.window.width()) ? bWidth : "100%",
				height = (bHeight > this.window.height()) ? bHeight : "100%";

            this.blocker.width(width).height(height);
        },

        fadeIn: function() {
            var self = this;
            this.fadeInContainer(function() {
                self.settings.showCallback();
            });

            if (this.blocker) {
                this.blocker.css({ opacity: 0 }); //using fadeTo, so instead of display:none set opacity to 0
                this.blocker.fadeTo(this.settings.fadeDuration, this.settings.blockerOpacity);
            }
        },

        fadeOut: function() {
            var self = this;
            this.fadeOutContainer(function() {
                self.container.remove();
                self.settings.hideCallback();
            });

            if (this.blocker) {
                this.blocker.fadeOut(this.settings.fadeDurtaion, function() {
                    self.blocker.remove();
                });
            }
        },

        fadeInContainer: function(callback) {
            this.container.css({ display: 'none' }); //hide initially so it can fade in
            this.container.fadeIn(this.settings.fadeDuration, callback);
        },

        fadeOutContainer: function(callback) {
            this.container.fadeOut(this.settings.fadeDuration, callback);
        },

        bindCloseButton: function() {
            var self = this;
            this.container.find('.close_button').click(function(e) {
                e.preventDefault();
                self.hide();
            });
        }

    };


    //instantiate on DOMReady
    $.RGA.RfiManager = function(params) {

        var self = this;
        this.settings = $.extend({}, this.defaults, params);
        this.pageCount = this.getPageArray().length;
        this.indexPlusState = 0;
        this.cookieOpts = {
            path: "/"
        };

        //live events
        $("a." + this.settings.addPageClass).live("click", function(e) {
            e.preventDefault();

            var isIndexPage = $("#rfiAction").hasClass("indexPage");

            if (!isIndexPage) { //for sub pages
                self.addPage($("#contentID").val());
                $(this).addClass('rfiPageAdded');
                $.RGA.global.Tracking.trackEvent("collection", "add");
            }
            else { //for index pages
                if (this.parentNode.id == "rfi-collector") { //case for main addpage to toggle other pluses
                    self.toggleIndexPluses();
                }
                else {
                    self.addPage(this.href.split("#")[1]);
                    $(this).addClass('rfiPageAdded');
                    $.RGA.global.Tracking.trackEvent("collection", "add");
                }
            }
        });

        $("#collectionList a.deleteButton").live("click", function(e) {
            e.preventDefault();

            var $parent = $(this).parent("div.handle");
            self.removePageByIndex($parent.prev().length);
            $parent.remove();
        });

        //for the rfiCollection page
        var $c = $("#collectionList");
        if ($c.get(0)) {

            $c.sortable({
                stop: function() {
                    self.reorderCollection();
                }
            });
        }

        //next button event
        $("a.slideShowNext").click(function(e) {
            e.preventDefault();
            var newPosition = parseInt(self.getPosition()) + 1;
            self.setPosition(newPosition);
            self.doAction(this.href);
        });

        //prev button event
        $("a.slideShowPrev").click(function(e) {
            e.preventDefault();
            var newPosition = parseInt(self.getPosition()) - 1;
            self.setPosition(newPosition);
            self.doAction(this.href);
        });

        $("#exitPresentation").click(function(e) {
            if (this.className != "over")
                return;
            var confirmed = confirm("You have a collection saved, do you want to overwrite it with this collection?");
            if (confirmed) {
                var hash = $("#presentationHash").val();
                window.location = "/Collection/CopyPresentation/" + hash;
            } else {
                e.preventDefault();
            }
        });

    };
    $.RGA.RfiManager.prototype = {

        doAction: function(url) {
            var parts = url.split('?');
            var url = parts[0];
            var pres = parts[1].split('=')[1];
            var form = $('#slideShowActionForm');
            var hashValue = form.find('#pres');
            form.attr('action', url);
            hashValue.val(pres);
            form.submit();
        },

        addPage: function(id) {
            var 
				ids = this.getPageArray(),
				length = ids.length,
				i = 0;
            /* Allowing mutliple adds
            for (i;i<length;i++){
            if (id == ids[i]){
            exists = 1;
            break;
            }
            }
            */
            //if (!exists){
            ids.push(id);

            this.setCookie(ids.join(","));
            this.pageCount = ids.length;
            //}

            this.updatePageCount();
        },

        removePageById: function(id) {
            var 
				ids = this.getPageArray(),
				length = ids.length,
				i = 0;

            for (; i < length; i++) {
                if (id == ids[i]) {
                    ids.splice(i, 1);
                    this.setCookie(ids.join(","));
                    this.pageCount = ids.length;
                    break;
                }
            }

            this.updatePageCount();
        },

        removePageByIndex: function(index) {

            var ids = this.getPageArray();

            ids.splice(index, 1);
            this.setCookie(ids.join(","));
            this.pageCount = ids.length;
            this.updatePageCount();
        },

        setCookie: function(str) {
            $.cookie(this.settings.cookieName, str, this.cookieOpts);
        },

        setPosition: function(newPosition) {
            $.cookie(this.settings.collectionPositionCookieName, newPosition, this.cookieOpts);
        },

        getPosition: function() {
            var position = $.cookie(this.settings.collectionPositionCookieName) || 0;
            return position;
        },

        reorderCollection: function() {
            var 
				list = $("#" + this.settings.collectionListId),
				items = list.find("div.handle"),
				ids = [];

            items.each(function() {
                var id = this.id.split("_")[1];
                ids.push(id);
            });

            if (ids.length)
                this.setCookie(ids.join(","));

        },

        updatePageCount: function() {
            var 
				counter = document.getElementById(this.settings.pageCountId),
				rfiPageCounter = document.getElementById("collectionNumber");

            counter.innerHTML = " " + this.pageCount;
            if (rfiPageCounter) {
                rfiPageCounter.innerHTML = this.pageCount;
            }

            //no more items, return to home page
            if (this.pageCount == 0) {
                this.hideCollectionForm();
                this.showNoItems();
            }

        },

        showNoItems: function() {
            $noitems = $("#noitems");
            $noitems.show();
        },

        hideNoItems: function() {
            $noitems = $("#noitems");
            $noitems.hide();
        },

        hideCollectionForm: function() {
            var collectionForm = $('#collectionForm');
            var viewPresButton = $('#viewPres');
            var collectionInstructions = $('#dragInstructions');
            if (collectionForm[0] != null)
                collectionForm.hide();
            if (viewPresButton[0] != null)
                viewPresButton.hide();
            if (collectionInstructions[0] != null)
                collectionInstructions.hide();
        },

        getPageArray: function() {
            var 
				array = [],
				idStr = $.cookie(this.settings.cookieName) || "";

            if (idStr.length) {
                array = idStr.split(",");
            }

            return array;
        },

        toggleIndexPluses: function() {
            var body = $(document.body);
            if (this.indexPlusState) {
                body.removeClass("show_pluses");
                this.indexPlusState = 0;
            }
            else {
                body.addClass("show_pluses");
                this.indexPlusState = 1;
            }
        },

        defaults: {
            addPageClass: "rfiAddPage",
            pageCountId: "rfiPageCount",
            cookieName: "RGASavedCollectionIDs",
            collectionListId: "collectionList",
            collectionPositionCookieName: "SlideShowPos"
        }
    };

    $.DropShadow = function(params) {
        this.settings = $.extend({}, this.defaults, params);
        this.width = (this.settings.width || this.settings.element.outerWidth()) + this.settings.adjustWidth;
        this.height = (this.settings.height || this.settings.element.outerHeight()) - this.settings.topHeight - this.settings.bottomHeight + this.settings.adjustHeight;

        var 
			offset = this.settings.element.position(),
			top = offset.top + this.settings.adjustY,
			left = offset.left + this.settings.adjustX;

        this.cont = this.generateHtml();

        this.settings.element.after(this.cont);
        this.cont.css({
            top: top,
            left: left,
            position: "absolute",
            zIndex: this.getZindex()
        });

        this.adjustCenter();

        this.settings.callback();
    };
    $.DropShadow.prototype = {
        defaults: {
            element: null,
            width: null,
            height: null,
            zIndex: -1,
            addedClass: "",
            adjustX: 0,
            adjustY: 0,
            adjustWidth: 0,
            adjustHeight: 0,
            topHeight: 0,
            bottomHeight: 0,
            callback: function() { }
        },

        generateHtml: function() {

            var arr = [];
            arr.push('<div class="ds_container ', this.settings.addedClass, '">');
            arr.push('<div class="ds_top"><div class="ds_outer"><div class="ds_inner"></div></div></div>');
            arr.push('<div class="ds_middle" style="width:', this.width, 'px;height:', this.height, 'px"><div class="ds_left" style="height:', this.height, 'px;"></div><div class="ds_center" style="height:', this.height, 'px;"></div><div class="ds_right" style="height:', this.height, 'px;"></div></div>');
            arr.push('<div class="ds_bottom"><div class="ds_outer"><div class="ds_inner"></div></div>');
            arr.push('</div>');

            return $(arr.join(''));
        },

        destroy: function() {
            if (this.cont.get(0)) this.cont.remove();
        },

        getZindex: function() {

            var z = parseInt(this.settings.element.css("zIndex"));

            return isNaN(z) ? -1 : z;
        },

        adjustCenter: function() {
            var left = this.cont.find(".ds_left"),
				center = this.cont.find(".ds_center"),
				right = this.cont.find(".ds_right");

            center.width(this.width - left.width() - right.width());
        }
    };

    $.cookie = function(name, value, options) {
        if (typeof value != 'undefined') { // name and value given, set cookie
            options = options || {};
            if (value === null) {
                value = '';
                options = $.extend({}, options); // clone object since it's unexpected behavior if the expired property were changed
                options.expires = -1;
            }
            var expires = '';
            if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
                var date;
                if (typeof options.expires == 'number') {
                    date = new Date();
                    date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
                } else {
                    date = options.expires;
                }
                expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
            }
            // NOTE Needed to parenthesize options.path and options.domain
            // in the following expressions, otherwise they evaluate to undefined
            // in the packed version for some reason...
            var path = options.path ? '; path=' + (options.path) : '';
            var domain = options.domain ? '; domain=' + (options.domain) : '';
            var secure = options.secure ? '; secure' : '';
            document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
        } else { // only name given, get cookie
            var cookieValue = null;
            if (document.cookie && document.cookie != '') {
                var cookies = document.cookie.split(';');
                for (var i = 0; i < cookies.length; i++) {
                    var cookie = $.trim(cookies[i]);
                    // Does this cookie string begin with the name we want?
                    if (cookie.substring(0, name.length + 1) == (name + '=')) {
                        cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                        break;
                    }
                }
            }
            return cookieValue;
        }
    };

    $.QueryString = function() {
        this._getQs();
    };
    $.QueryString.prototype = {
        _getQs: function() {
            this.qs = {};
            if (window.location.search.length > 0) {
                var qs = window.location.search.substr(1), pairs = qs.split('&'), kvp = {};
                for (var i = 0; i < pairs.length; i++) {
                    var pair = pairs[i].split('='), key = decodeURIComponent(pair[0]), val = decodeURIComponent(pair[1]);
                    kvp[key] = val;
                }
                this.qs = kvp;
            }
        },
        get: function(key) {
            if (typeof key == "undefined") return this.qs;
            return (typeof this.qs[key] != "undefined") ? this.qs[key] : "";
        },
        set: function(key, val) {
            this.qs[key] = val;
            return this;
        },
        remove: function(key) {
            if (typeof this.qs[key] != "undefined") {
                this.qs[key] = null;
                delete this.qs[key];
            }
            return this;
        },
        stringify: function() {
            var str = "";
            for (var key in this.qs) {
                str += encodeURIComponent(key) + "=" + encodeURIComponent(this.qs[key]) + "&";
            }
            return str.length ? "?" + str.replace(/&$/, '') : "";
        },
        reset: function() {
            this._getQs();
            return this;
        },
        clear: function() {
            this.qs = {};
            return this;
        }
    };

})(jQuery);

