
(function(){
	
	var currentHash = location.hash;
	hashParam = {};
	if(currentHash.length){
		currentHash = currentHash.substr(1).split('&');
		for(var i=0; i<currentHash.length; i++){
			var keyValuePair = currentHash[i].split('=');
			hashParam[keyValuePair[0]] = keyValuePair[1]; //numbers are still strings at this point.
		}
	}
	function setHashParam(k, v){
		//update hashParam
		hashParam[k] = v;
		
		//serialize hashParam
		var s = [];
		for(var key in hashParam){
			s.push( key + '=' + hashParam[key] );
		}
		
		//set the hash to the serialization of hashParam.
		location.hash = '#' + s.join('&');
	}
	

	function setCookie(name,value,days) {
		if (days) {
			var date = new Date();
			date.setTime(date.getTime()+(days*24*60*60*1000));
			var expires = "; expires="+date.toGMTString();
		}
		else var expires = "";
		document.cookie = name+"="+value+expires+"; path=/";
	}

	function getCookie(name) {
		var nameEQ = name + "=";
		var ca = document.cookie.split(';');
		for(var i=0;i < ca.length;i++) {
			var c = ca[i];
			while (c.charAt(0)==' ') c = c.substring(1,c.length);
			if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
		}
		return null;
	}

	function eraseCookie(name) {
		createCookie(name,"",-1);
	}

	
	var temp;
	var templateBase = '/assets/templates/hqa';
	
	// "fix" sidebar images.
	$('.one-third img').each(function(){
		var el = $(this);
		$('<img src="'+this.src+'" alt="'+this.alt+'"/>').insertAfter(el);
		el.remove();
	});
	
	// add dropshadow to button text.
	$('button span').each(function(){
		var el = $(this);
		$('<b>'+el.html()+'</b>').prependTo(el);
	});
	
	//[plugin] treat spacebar 'keypress' event the same as the mouse 'click' event.
	$.fn.klik = function(f){
		return this.bind('click keypress', function(e){
			if(!e.keyCode || e.keyCode == 32){ //32 == space
				return f.call(this, e);
			}
		});
	};
	
	// add easeOutQuad to the easing options and make it the default option.
	jQuery.extend(jQuery.easing, {
		def: 'easeOutQuart',
		easeInOutQuart: function (x, t, b, c, d) {
			if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
			return -c/2 * ((t-=2)*t*t*t - 2) + b;
		},
		easeOutExpo: function (x, t, b, c, d) {
			return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
		},
		easeOutCirc: function (x, t, b, c, d) {
			return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
		},
		easeOutQuad: function (x, t, b, c, d) {
			return -c *(t/=d)*(t-2) + b;
		}
	});
	
	// wire up secondary nav li:hover
	//~ $('#glb-hdr-secondary-nav>ul>li').hover(
		//~ function(){
			//~ if( $('.tertiary-nav',this).size() ){
				//~ $(this).addClass('over');
			//~ }
		//~ },
		//~ function(){
			//~ $(this).removeClass('over');
		//~ }
	//~ );
	
	// wire up printing on "print-page" class
	$('.print-page').click(function(){window.print();});

	// Prevent text selection (of language selector text) in IE
	//~ if(temp.size() && temp[0].attachEvent){
		//~ temp.attachEvent('onselectstart', function(){ return false; });
	//~ }
	

	/**
	 * carousel - jQuery plugin to navigate images/any content in a carousel style widget.
	 * @requires jQuery v1.2 or above
	 *
	 * Copyright (c) 2009 Dennis Hall <http://www.google.com/profiles/103490491683374491591>
	 * - heavily modified from the 2007 original version
	 * Copyright (c) 2007 Ganeshji Marwaha (gmarwaha.com)
	 * http://gmarwaha.com/jquery/jcarousellite/
	 * Dual licensed under the MIT and GPL licenses:
	 * http://www.opensource.org/licenses/mit-license.php
	 * http://www.gnu.org/licenses/gpl.html
	 *
	 * Version: 1.0.1a
	 */


	(function($) {                                                  // Compliant with jQuery.noConflict()
		
		$.fn.carousel = function(o) {
			o = $.extend({
				btnPrev: null,
				btnNext: null,
				btnGo: null,
				mouseWheel: false,
				auto: null,
				speed: 500,
				easing: null,
				vertical: false,
				circular: false,
				visible: 5,
				autoSize: false,
				start: 0,
				scroll: 5,
				listContainerSelector: 'ul',
				listItemSelector: 'li',
				beforeStart: null,
				afterEnd: null
			}, o || {});
			
			return this.each(function() {                           // Returns the element collection. Chainable.

				var running = false,
					animCss = o.vertical ? "top" : "left",
					sizeCss = o.vertical ? "height" : "width",
					div = $(this),
					ul = $(o.listContainerSelector, div),
					tLi = $(o.listItemSelector, ul),
					tl = tLi.size(),
					v = o.visible,
					disabledClass = 'disabled';
				///

				if(o.circular) {
					ul.prepend(tLi.slice(tl-v-1+1).clone()).append(tLi.slice(0,v).clone());
					o.start += v;
				}
				
				var li = $(o.listItemSelector, ul),
					numItems = li.size(),
					curr = o.start;
				///
				
				// if we are trying to start with an item that is too close to the end of the list,
				// we don't want it to be the first item.
				if(curr > numItems - v){
					curr = numItems - v;
				}

				//~ li.css({overflow: "hidden", 'float': (o.vertical ? "none" : "left")});
				//~ ul.css({margin: "0", padding: "0", position: "relative", "list-style-type": "none", "z-index": "1"});
				//~ div.css({overflow: "hidden", position: "relative", "z-index": "2", left: "0px"});

				var liSize = o.vertical ? height(li) : width(li),   // Full li size(incl margin)-Used for animation
					ulSize = liSize * numItems,                     // size of full ul(total length, not just for the visible items)
					divSize = liSize * v;                           // size of entire div(total length for just the visible items)
				///
				
				//li.css({width: li.width(), height: li.height()});
				li.css({sizeCss:liSize});
				ul.css(sizeCss, ulSize+"px").css(animCss, -(curr*liSize));

				o.autoSize && div.css(sizeCss, divSize+"px");       // Width of the DIV. length of visible images
				
				function prev(){
					return go(curr - o.scroll);
				}
				
				function next(){
					return go(curr + o.scroll);
				}
				
				// make scrolling prev/next publicly accessible, for example:
				//   <code>$('.my-particular-carousel').trigger('scroll_prev');</code>
				div.bind('scroll_prev', prev);
				div.bind('scroll_next', next);
				div.bind('slide_go', function(){
					var to = div.data('carousel_start');
					go( to || to === 0 ? to : curr );
				});
				//~ div.bind('scroll_update', function(){
					//~ tLi = $(o.listItemSelector,ul);
					//~ numItems = tLi.size() - 1;
					//~ // if the number of items remaining is equal to the number of items to display at a time,
					//~ // then make sure to scroll to the first item
					//~ // else if we removed an item that is in the last 'page' of items,
					//~ // then make sure to scroll back one so we don't leave a blank space at the end.
					//~ return go(numItems == v ? 0 : tLi.index(arguments[1]) == numItems ? numItems : curr);
				//~ });
				
				if(o.btnPrev){
					o.btnPrev = $(o.btnPrev, div.parent()).klik(prev);//.css('display','block');
				}
				
				if(o.btnNext){
					o.btnNext = $(o.btnNext, div.parent()).klik(next);//.css('display','block');
				}

				if(!o.circular && o.start == 0 && o.btnPrev){
					o.btnPrev.addClass(disabledClass);
				}

				if(o.btnGo)
					$.each(o.btnGo, function(i, val) {
						$(val).click(function() {
							return go(o.circular ? o.visible+i : i);
						});
					});

				if(o.mouseWheel && div.mousewheel)
					div.mousewheel(function(e, d) {
						return d>0 ? go(curr-o.scroll) : go(curr+o.scroll);
					});

				if(o.auto)
					setInterval(function() {
						go(curr+o.scroll);
					}, o.auto+o.speed);

				function vis() {
					return li.slice(curr).slice(0,v);
				};
				

				function go(to) {
					if(!running) { //<strike>if to==curr, then we have nowhere to go, let's not waste time animating to where we already are.</strike>

						(o.beforeStart && o.beforeStart.call(this, vis()));
						
						//added because PGE requires dynamic items - you can click "no thanks" and the item will remove itself
						//numItems = ul.find('li').size();

						if(o.circular) {                    // If circular we are in first or last, then goto the other end
							if(to<=o.start-v-1) {           // If first, then goto last
								ul.css(animCss, -((numItems-(v*2))*liSize)+"px");
								// If "scroll" > 1, then the "to" might not be equal to the condition; it can be lesser depending on the number of elements.
								curr = to==o.start-v-1 ? numItems-(v*2)-1 : numItems-(v*2)-o.scroll;
							} else if(to>=numItems-v+1) { // If last, then goto first
								ul.css(animCss, -( (v) * liSize ) + "px" );
								// If "scroll" > 1, then the "to" might not be equal to the condition; it can be greater depending on the number of elements.
								curr = to==numItems-v+1 ? v+1 : v+o.scroll;
							} else curr = to;
						} else {                            // If non-circular and to points to first or last, we just return.
							/** NEXT LINE CHANGED **/
							curr = to < 0 ? 0 : to > numItems-v ? numItems-v : to;
						}                                   // If neither overrides it, the curr will still be "to" and we can proceed.
						
						
						running = true;
						
						ul.animate(
							animCss == "left" ? { left: -(curr*liSize) } : { top: -(curr*liSize) } , o.speed, o.easing,
							function() {
								if(o.afterEnd){
									o.afterEnd.call(this, vis());
								}
								running = false;
							}
						);
						
						// Disable buttons when the carousel reaches the last/first, and enable when not
						if(!o.circular) {
							// remove disabledClass
							var both = o.btnPrev.add(o.btnNext).removeClass(disabledClass);
							// add disabledClass if appropriate
							var disableMe = (curr==0 && o.btnPrev) || (curr+o.scroll>=numItems && o.btnNext);
							(disableMe && disableMe.addClass(disabledClass));
							// if we have removed enough elements so that there is no need to scroll,
							// then hide the scroll buttons
							if(numItems == o.visible){
								both.css('display','none');
							}
						}

					}
					return false;
				};
				
				div.go = go;

			});
		};

		function css(el, prop) {
			return parseInt($.css(el[0], prop)) || 0;
		};
		function width(el) {
			return  el[0].offsetWidth + css(el, 'marginLeft') + css(el, 'marginRight');
		};
		function height(el) {
			return el[0].offsetHeight + css(el, 'marginTop') + css(el, 'marginBottom') + css(el, 'paddingTop') + css(el, 'paddingBottom');
		};
		
	})(jQuery);


	/* END MIT AND GPL LICENSING */


	// course listing page enhancements
	var courseListingContainer = $('#course-listing');
	(function(){
		// are we on the course listing page?
		if(courseListingContainer.size()){
			$('<div class="view-styles"><span>View:</span> <a href="#" class="blurb-style" title="View as blurbs">.</a> <a href="#" class="list-style" title="View as a list">.</a></div>').insertBefore('h1');
			
			var viewStyleKey = 'viewStyle';
			var defaultViewStyleClassName = 'default-view-style';
			var viewStyle = hashParam[viewStyleKey] || getCookie(viewStyleKey) || 'default';
			if(viewStyle != 'list'){
				$('body').addClass(defaultViewStyleClassName);
			}
			if(!hashParam[viewStyleKey]){
				setHashParam(viewStyleKey, viewStyle);
			}
			$('.blurb-style,.list-style').klik(function(){
				$('body').toggleClass(defaultViewStyleClassName);
				setCookie(viewStyleKey, $('body').is('.'+defaultViewStyleClassName)?'default':'list', 60);
				return false;
			});
			
			//add the previous/next buttons
			courseListingContainer.append('<a href="#" class="prev"><span>previous</span></a> <a href="#" class="next"><span>next</span></a>');
			var pages = $('<ul class="pages"><li><a href="#">1</a></li></ul>').appendTo(courseListingContainer);
			// create 'pages'
			var blurbs = courseListingContainer.find('.course-blurb');
			var rootNode = blurbs.parent();
			var numBlurbs = blurbs.size();
			var itemsPerPage = 6;
			for(var i=1;i<numBlurbs/itemsPerPage;i++){
				var clone = rootNode.clone(true).appendTo(rootNode.parent());
				//~ console.log(i, i*itemsPerPage, clone.children().slice(0,i*itemsPerPage).map(function(){return $('h2 a',this).html();}));
				clone.children().slice(0,i*itemsPerPage).remove();
				//~ console.log('second range: ', clone.children().slice(itemsPerPage).map(function(){return $('h2 a',this).html();}));
				clone.children().slice(itemsPerPage).remove();
				
				// append page-number LIs to the 'pages' UL.
				pages.append('<li><a href="#">'+(i+1)+'</a></li>');
			}
			rootNode.children().slice(itemsPerPage).remove();
			
			var start = 1 * hashParam.carousel_start || 0;
			
			pages = pages.find('li');
			function setPageBookmark(d){
				pages.removeClass('on');
				pages.eq(d).addClass('on');
				setHashParam('carousel_start', d);
			}
			
			$('.course-listing-chunk').carousel({
				listContainerSelector: ".inner",
				listItemSelector: "ul",
				btnNext: ".next span",
				btnPrev: ".prev span",
				speed: 800,
				visible: 1,
				start: start,
				scroll: 1
			});
			
			var page = start;
			pages.removeClass('on');
			pages.eq(start).addClass('on');
			var pageLimit = rootNode.siblings().size();
			$(".next span").klik(function(){
				if(page < pageLimit){
					setPageBookmark(++page);
				}
			});
			$(".prev span").klik(function(){
				if(page){ // >0
					setPageBookmark(--page);
				}
			});
			pages.find('a').klik(function(){
				page = $(this).text()*1-1;
				setPageBookmark(page);
				$('.course-listing-chunk')
					.data('carousel_start', page)
					.trigger('slide_go');
				return false;
			});
		}
	})();



	/******************/

	// we are using this for the global search box, makes sense to include it in hqa.global.js:
	/**
	 * inputHint $ plugin
	 * @description: simulates default-text existing inside of <input>s by overlaying them with their <label>s
	 *               (<label class="hint" for="input-id"> may be substituted by <div title="for:input-id">)
	 *               http://remysharp.com/2007/03/19/a-few-more-$-plugins-crop-labelover-and-pluck/#labelOver
	 * @param overClass: the className to apply to the input hint (label or div)
	 */
	$.fn.inputHint = function(overClass) {
		return this.each(function(){
			var hint = $(this);
			// in this scope, "var f" means the element attribute "for"
			// .. "for" is a reserved word in the ECMA grammar
			var f = hint.attr('for') || hint.attr('title').split('for:').pop();
			if (f) {
				var input = $('#' + f).data('input-hint', hint[0]);
				
				this.hide = function() {
					hint.css({ left: -9999 });
				};
				
				this.show = function() {
					if (input.val() == ''){
						hint.css({ left: 0 });
					}
				};
				
				// handlers
				input.focus(this.hide);
				input.blur(this.show);
				hint.addClass(overClass).click(function(){ input.focus(); });
				
				if (input.val() != ''){
					this.hide();
				}
			}
		});
	};
	/// end plugin
	
	//apply plugin
	$('.input-hint').inputHint('hint-over');

	//we might have race condition, deal with it.
	(function(){
		if(window.Cufon){
			Cufon.replace('h1,h2');
			//for ie.
			Cufon.now();
		} else {
			setTimeout(arguments.callee, 20);
		}
	})();
	

})();

