var groomstars = {
	global: {
		initialize: function () {
			groomstars.global.initializeDropdownMenu();
			groomstars.global.setCurrentCategoryInMenu();
			groomstars.global.initializeBrowseMenu();
			groomstars.global.initializePopupStack();
			groomstars.global.calloutCycle();

			$('#footer input.text').focus(function() {
				$(this).prev('label').hide();
			}).blur(function() {
				if ($(this).val() == '') {
					$(this).prev('label').show();					
				}
			});			
		},

		initializeDropdownMenu: function () {
			$('ul#navigation').superfish();
		},

		initializeBrowseMenu: function () {
			$('ul.browse_by').browseMenu();
			
			// if not already browsing, show the Shop by Item Menu
			if ($('body').find('.select').html() === null) {
				$('.browse_by li:first').find('a:first').click();	
			}
		},
		
		setCurrentCategoryInMenu: function() {
			var location = document.location.href;
			var start = location.indexOf(location.split('/')[3]);
			
			var currentCategoryUrl = '/' + location.substr(start);
			
			$('.browse_by a[href='+currentCategoryUrl+']').addClass('select');
		},
		
		calloutCycle: function() {
			$('.callout_cycle').cycle();
		},
		
		addProductToBag: function(button) {
			button.html('Adding item...');
						
			$.ajax({
				url: '/cart.jsp?' + $.param(button.metadata().param),
				type: 'post',
				success: function(data) {
					button.html('Item Added').qtip({
						content: {
							text: '<div class="add_message"><p>This item has been added to your shopping cart.</p> <p><a href="#" class="continue">Continue Shopping</a> | <a href="'+cartURL+'">View Shopping Bag</a></p></div>'
						},
						container: $(this).parent(),
						show: {
							ready: true
						},
						hide: false,
						position: {
							corner: {
								tip: true,
								target: 'leftMiddle',
								tooltip: 'rightMiddle'
							},
							adjust: {
								x: - 2
							}
						},
						style: {
							border: {
								width: 2,
								radius: 2,
								color: '#717480'
							},
							width: {
								max: 400
							},
							tip: {
								corner: 'rightMiddle',
								size: {
									x: 6,
									y: 10
								}
							}
						},
						api: {
							onRender: function () {
								var self = this;

								$(self.elements.tooltip).find('a.continue').click(function() {
									$(self.elements.target).html('Add to shopping bag');
									self.destroy();
									
									return false;
								});
							}
						}
					});
				},
				error: function(req, textStatus, errorThrown) {
					alert('error');
				}
			});
		},
		
		initializePopupStack: function() {			
			window.productStack = new Array();
		}
	},
	
	homePage: {
	
		initialize: function() {
			this.cycle();
		},
		more_info_popup:function(){
			$('#more_info_header h3, #more_info_header span,#more_info_close').click(function(){
				$('#more_info_body').slideToggle();
			});
		},
		cycle : function() {
			$('#feature').delay(8000).fadeIn('slow', function() { 
				$('#feature #items').cycle({
					fx : 'fade',
					prev: 'div#feature .prev',					
					next: 'div#feature .next',
					timeout: 8000,//here to enable home timer
					delay: 8000,
					pager: '#items_pager',
					pagerAnchorBuilder: function(idx, slide) { 
						return '<li><a class="pager_item">.</a></li>'; 
					} 
				});
			});
			
		}
		
	},


	catalogPage:function(){
		/*var el= $('.right_col > h1 + p'),*/
/*
		var el= $('.right_col .complete'),
				_str =el.text();
		if (_str.length > 353) {
		  var part1= _str.substring(0,_str.indexOf(' ', 353)); 
			var more= '<a href="#" class="read_more">read more</a>';
			var extra_text = '<span class="more_text" style="display:inline;">' + _str.substring(_str.indexOf(' ', 353)) +'<a href="#" class="read_less">..less text</a></span>';	
			
			el.html(part1 + more + extra_text);
			$('span.more_text').hide();
		};

		$('a.read_more').live('click',function(){
			$(this).hide();
			$(this).next('span').show();
			return false;
		});
		
		$('a.read_less').live('click',function(){
			$('span.more_text').hide();
			$('a.read_more').show();
			return false;
		});*/


		truncate('#parContent');
		$('span.paragraphBreak, #parContent p:empty').remove();

		$('.readMore').live('click', function() {
		    var $hidden = $('.hiddenText');
		    if($hidden.is(':hidden')) {
		        $hidden.show();
		        $(this).insertAfter($('#parContent span.hiddenText p:last')).children('.readMoreText').text(' close ').siblings().hide();
		    } else {
		        $(this).appendTo($('.revealText')).children('.readMoreText').text(' read more ').siblings().show().css('display','inline');
		        $hidden.hide();
		    }
		});

		$('.readMore').click();

		function truncate(element) {
		    $(element + ' p').css({display: 'inline'});

		    var theText = $(element).html();        // Original Text
		    var item;                               // Current tag or text area being iterated
		    var convertedText = '<span class="revealText">';    // String that will represent the finished result
		    var limit = 250;                        // Max characters (though last word is retained in full)
		    var counter = 0;                        // Track how far we've come (compared to limit)
		    var lastTag;                            // Hold a reference to the last opening tag
		    var lastOpenTags = [];                  // Stores an array of all opening tags (they get removed as tags are closed)
		    var nowHiding = false;                  // Flag to set to show that we're now in the hiding phase

		    theText = theText.replace(/[\s\n\r]{2,}/g, ' ');            // Consolidate multiple white-space characters down to one. (Otherwise the counter will count each of them.)
		    theText = theText.replace(/(<[^<>]+>)/g,'|*|SPLITTER|*|$1|*|SPLITTER|*|');                      // Find all tags, and add a splitter to either side of them.
		    theText = theText.replace(/(\|\*\|SPLITTER\|\*\|)(\s*)\|\*\|SPLITTER\|\*\|/g,'$1$2');           // Find consecutive splitters, and replace with one only.
		    theText = theText.replace(/^[\s\t\r]*\|\*\|SPLITTER\|\*\||\|\*\|SPLITTER\|\*\|[\s\t\r]*$/g,''); // Get rid of unnecessary splitter (if any) at beginning and end.
		    theText = theText.split(/\|\*\|SPLITTER\|\*\|/);            // Split theText where there's a splitter. Now we have an array of tags and words.

		    for(var i in theText) {                                     // Iterate over the array of tags and words.
		        item = theText[i];                                      // Store current iteration in a variable (for convenience)
		        lastTag = lastOpenTags[lastOpenTags.length - 1];        // Store last opening tag in a variable (for convenience)
		        if( !item.match(/<[^<>]+>/) ) {                         // If 'item' is not a tag, we have text
		            if(lastTag && item.charAt(0) == ' ' && !lastTag[1].match(/span|SPAN/)) item = item.substr(1);   // Remove space from beginning of block elements (like IE does) to make results match cross browser
		            if(!nowHiding) {                                        // If we haven't started hiding yet...
		                counter += item.length;                             // Add length of text to counter.
		                if(counter >= limit) {                              // If we're past the limit...
		                    var length = item.length - 1;                   // Store the current item's length (minus one).
		                    var position = (length) - (counter - limit);    // Get the position in the text where the limit landed.
		                    while(position != length) {                     // As long as we haven't reached the end of the text...
		                        if( !!item.charAt(position).match(/[\s\t\n]/) || position == length )   // Check if we have a space, or are at the end.
		                            break;                                  // If so, break out of loop.
		                        else position++;                            // Otherwise, increment position.
		                    }
		                    if(position != length) position--;
		                    var closeTag = '', openTag = '';                // Initialize open and close tag for last tag.
		                    if(lastTag) {                                   // If there was a last tag,
		                        closeTag = '</' + lastTag[1] + '>';         // set the close tag to whatever the last tag was,
		                        openTag = '<' + lastTag[1] + lastTag[2] + '>';  // and the open tag too.
		                    }
		                    // Create transition from revealed to hidden with the appropriate tags, and add it to our result string
		                    var transition = '<span class="readMore"><span class="ellipsis">...</span><span class="readMoreText"> [Read More] </span></span>' + closeTag + '</span><span class="hiddenText">' + openTag;
		                    convertedText += (position == length)   ? (item).substr(0) + transition
		                                                                : (item).substr(0,position + 1) + transition + (item).substr(position + 1).replace(/^\s/, '&nbsp;');
		                    nowHiding = true;       // Now we're hiding.
		                    continue;               // Break out of this iteration.
		                }
		            }
		        } else {                                                // Item wasn't text. It was a tag.
		            if(!item.match(/<br>|<BR>/)) {                      // If it is a <br /> tag, ignore it.
		                if(!item.match(/\//)) {                         // If it is not a closing tag...
		                    lastOpenTags.push(item.match(/<(\w+)(\s*[^>]*)>/));     // Store it as the most recent open tag we've found.
		                } else {                                                    // If it is a closing tag.
		                    if(item.match(/<\/(\w+)>/)[1] == lastOpenTags[lastOpenTags.length - 1][1]) {    // If the closing tag is a paired match with the last opening tag...
		                        lastOpenTags.pop();                                                         // ...remove the last opening tag.
		                    }
		                    if(item.match(/<\/[pP]>/)) {            // Check if it is a closing </p> tag
		                        convertedText += ('<div class="par_spacer" style="height:8px;width:100%;"></div>');    // If so, add two line breaks to form paragraph
		                    }
		                }
		            }
		        }   
		        convertedText += (item);            // Add the item to the result string.
		    }
		    convertedText += ('</span>');           // After iterating over all tags and text, close the hiddenText tag.
		    $(element).html(convertedText);         // Update the container with the result.
		}
		
		
		
	},
	
	productPage: {
		initialize: function () {
			var $page = $('div.product_page');
			var $image = $page.find('a.magnify');

			groomstars.productPage.initializeAlternateViewTooltip($page, 'productPage');
			groomstars.productPage.initializePersonalizationTooltip();
			groomstars.productPage.initializeImageZoom($image, 'productPage');
			groomstars.productPage.relatedProductsQtip();
			groomstars.landingPage.setSidebarHeight();
		},

		relatedProductsQtip: function() {
			$('div.other_products a.image').qtip({
				position: {
					corner: {
						tip: true,
						target: 'topMiddle',
						tooltip: 'bottomMiddle'
					},
					adjust: {
						y: - 2
					}
				},
				style: {
					'font-size': '10px',
					'font-weight': 'bold',
					'text-align': 'center',
					border: {
						width: 2,
						radius: 2
					},
					tip: {
						corner: 'bottomMiddle',
						size: {
							x: 10,
							y: 6
						}
					}
				}
			});
		},

		initializeImageZoom: function (image, context) {
			var width = 328;
			var height = 216;
			var offset = 30;

			if (context == 'productPopup' || context == 'productPage') {
				offset = 45;
				width = 355;
			}

			image.click(function() {
				image.jqzoom({
					title: false,
					zoomWidth: width,
					zoomHeight: height,
					xOffset: offset,
					lensReset: true
				}).mouseenter();
				
				return false;
			});
		},

		initializeAlternateViewTooltip: function (container, context) {
			var $target = $(container).find('a.alternate');
			var tooltipContent = '' + $(container).find('div.alternate_views').html();
			var $cont;
			var adjust = {};

			if (context == 'productPopup') {
				adjust = {
					x: (-1) * $(container).offset().left + $(container).width() / 2,
					y: (-1) * $(container).offset().top + $(container).height() / 2,
					scroll: false,
					resize: false
				};
				
				$cont = $('#popup_container div.product_page');
			}
			else if (context == 'productPage') {
				adjust = {
					x: (-1) * $(container).offset().left,
					y: (-1) * $(container).offset().top,
					scroll: false,
					resize: false
				};

				$cont = $('div.product_page');
			}
			else {
				adjust = {
					x: 0,
					y: 0,
					scroll: false,
					resize: false
				};

				$cont = $('div.current');
			}

			$target.qtip({
				content: {
					text: tooltipContent,
					prerender: true
				},
				position: {
					corner: {
						target: 'topMiddle',
						tooltip: 'bottomMiddle'
					}
				},
				show: {
					solo: true,
					effect: {
						type: 'fade',
						length: 200
					}
				},
				hide: {
					fixed: true,
					effect: {
						type: 'fade',
						length: 300
					}
				},
				style: {
					border: {
						width: 2,
						radius: 2
					},
					width: {
						max: 400
					},
					tip: {
						corner: 'bottomMiddle',
						size: {
							x: 10,
							y: 6
						}
					}
				},
				api: {
					onRender: function () {
						var self = this;

						$(this.elements.tooltip).find('img').each(function(i) {
							$(this).click(function (i) {
								var $image = $(this);
								
								var $magnifyLink = $cont.find('a.magnify');
								var $enlargeLink = $cont.find('a.enlarge_link');
								var $productImage = $cont.find('.product_image');

								$productImage.animate({
									opacity: 0
								}, 200, function () {
									$(this).attr('src', $image.attr('src')).animate({
										opacity: 1
									}, 300);
								});

								$magnifyLink.attr('href', $image.attr('fullsize'));
								
								$enlargeLink.attr('href', jQuery.param.querystring($enlargeLink.attr('href'), 'imageName='+$image.attr('fullsize').substr($image.attr('fullsize').lastIndexOf('/') + 1)));
								$enlargeLink.optPopup($enlargeLink.attr('href'));

								groomstars.productPage.initializeImageZoom($('#popup_container a.magnify'), context);
								self.hide();

								return false;
							});
						});
					}
				}
			}).click(function () {
				return false;
			});
		},

		initializePersonalizationTooltip: function () {
			$('a.personalize').qtip({
				position: {
					corner: {
						tip: true,
						target: 'topMiddle',
						tooltip: 'bottomMiddle'
					},
					adjust: {
						y: - 2
					}
				},
				style: {
					'font-size': '10px',
					'font-weight': 'bold',
					'text-align': 'center',
					border: {
						width: 2,
						radius: 2
					},
					tip: {
						corner: 'bottomMiddle',
						size: {
							x: 10,
							y: 6
						}
					}
				}
			});
		}
	},

	productPopup: {
		initialize: function () {
			var $page = $('#popup_container');
			var $image = $('#popup_container a.magnify')
			var productId = $('#popup_container div.product_page').attr('id');

			var off = $image.offset();
			
			groomstars.productPage.initializeAlternateViewTooltip($page, 'productPopup');
			groomstars.productPage.initializeImageZoom($image, 'productPopup');
			groomstars.productPage.initializePersonalizationTooltip();
			groomstars.productPage.relatedProductsQtip();
			
			groomstars.productPopup.initializeGoBackLink();

			// Add the current product to the stack
			window.productStack.push(productId);
		},
		
		initializeGoBackLink: function() {
			// If there are no products on the product stack, hide the go back link
			if (window.productStack.length != 0) {
				$('a.go_back').show().click(function() {
					groomstars.productPopup.goBack();
					
					return false;
				});
			}			
		},
		
		goBack: function() {
			window.productStack.pop();
			
			var goBackURL = '/popup.jsp?content=prodPopup&product=' + window.productStack.pop();
			
			$.fn.optPopup.popup(goBackURL, $.fn.optPopup.defaults);
		}
	},

	newArrivals: {
		initialize: function () {
			groomstars.newArrivals.initializeCycle();
			groomstars.landingPage.setSidebarHeight();
		},

		initializeCycle: function () {
			var $buttons = $('.button_container');

			var $container = $('.slide_container').cycle({
				fx: 'scrollHorz',
				speed: 300,
				timeout: 0,
				prev: 'div.cycle_left a',
				next: 'div.cycle_right a',
				after: groomstars.newArrivals.cycleCallback
			});

			$container.children().each(function (i) {
				// create input
				$('<a href="#" id="goto-' + i + '"></a>')
				// append to button container
				.appendTo($buttons)
				// bind click handler
				.click(function () {
					// cycle to the corresponding slide
					$container.cycle(i);

					$(this).siblings().removeClass();

					$(this).addClass('current');
					return false;
				});
			});

			$buttons.find('a:first-child').addClass('current');
		},

		cycleCallback: function (curr, next, opts) {
			var image = $(next).find('a.magnify');
			$(curr).removeClass('current');
			$(next).addClass('current');

			groomstars.productPage.initializeImageZoom(image);
			groomstars.productPage.initializeAlternateViewTooltip(next);
			groomstars.productPage.initializePersonalizationTooltip();

			$('div[qtip]').hide();

			var index = opts.currSlide;

			$('.button_container a').removeClass();
			$('.button_container a[id="goto-' + index + '"]').addClass('current');
		}
	},
	
	landingPage: {
		
		initialize: function() {
			//groomstars.landingPage.initializeCycle();
			this.add_Scroll_Bars();
			this.setSidebarHeight();
		},
		
		// not sure of this is being used but need to figure out  
		initializeCycle: function() {
			var $container = $('.items').cycle({
				fx: 'scrollHorz',
				speed: 300,
				timeout: 0,
				prev: '.recommended_gifts a.prev',
				next: '.recommended_gifts a.next',
				after: groomstars.newArrivals.cycleCallback
			});
		},
		
			setSidebarHeight: function() {
			var sidebarHeight = $('div.right_col').height();
			$('div.left_col').css('height', sidebarHeight*1);
			},
			
			add_Scroll_Bars:function(){
				$(window).load(function() {
					$('#landing_header').children('blockquote').wrapAll('<div id="scroll" />');

					$('#scroll').jScrollPane({
						showArrows: true
					});

					$('#scroll').children('blockquote').mousewheel(function(event, delta) {
					});
				});	
		}
	},
	
	featuredBrand: {
		
		initialize: function() {
			this.cycleProducts();
			this.productQtip();
		},
		
		cycleProducts: function() {
			$(function() {
				$('.featured_brand_products .items').cycle({
					fx: 'scrollHorz',
					prev: '.prev',
					next: '.next',
					timeout: 0
				});
			});
		},
		
		productQtip: function() {
			$('.featured_brand_products a.image').qtip({
				position: {
					corner: {
						tip: true,
						target: 'topMiddle',
						tooltip: 'bottomMiddle'
					},
					adjust: {
						y: - 2
					}
				},
				style: {
					'font-size': '10px',
					'font-weight': 'bold',
					'text-align': 'center',
					border: {
						width: 2,
						radius: 2
					},
					tip: {
						corner: 'bottomMiddle',
						size: {
							x: 10,
							y: 6
						}
					}
				}
			});
		}
	},
	
	ga : {
		
		trackPage: function(page) {
			_gaq.push(['_trackPageview',page]);
		}
		
	}
	
};



$(function () {
	groomstars.global.initialize();

	$.fn.optPopup.initializeLinks = function() {
		if (typeof (Cufon) != "undefined" && Cufon !== null) {
			Cufon.refresh();
		}

		$('a[rel^=popup]').each(function() {
			$(this).optPopup($(this).attr('href'), $(this).metadata());
		});
		
		var productId;
		var popURL;
		
		$('a[rel^=product-popup]').each(function() {
			productId = $(this).attr('name');
			popURL = '/popup.jsp?content=prodPopup&product=' + productId;
			
			$(this).optPopup(popURL, $(this).metadata());
		});

		$('.email_link').each(function() {
			$(this).optPopup($(this).attr('href'), {
				onSuccess: function() {

					var boxForm = $('form[name=email2]');

					boxForm.validate({
						submitHandler: function(form) {
							var postUrl = boxForm.attr('action');

							if (postUrl.substr(0, 1) != "/") {
								postUrl = "/" + postUrl;
							}

							$.ajax({
								type: "POST",
								url: postUrl,
								data: boxForm.serialize(),
								beforeSend: function() {
									boxForm.find('input').attr('disabled', true).addClass('disabled');
									boxForm.find('textarea').attr('disabled', true).addClass('disabled');
								},
								success: function(data) {
									boxForm.find('h2').css('font-size', '12px').html(data);
									
									if (typeof (Cufon) != "undefined" && Cufon !== null) {
										Cufon.refresh();
									}
									
									setTimeout(function() {
										close();
									}, 3000);

									}
								});
							return false;
						}
					});
				}
			});
		});

		$('.contact_link').each(function() {
			$(this).optPopup($(this).attr('href'), {
				onSuccess: function() {

					var boxForm = $('form[name=contactUs]');

					boxForm.validate({
						submitHandler: function(form) {
							var postUrl = boxForm.attr('action');

							if (postUrl.substr(0, 1) != "/") {
								postUrl = "/" + postUrl;
							}

							$.ajax({
								type: "POST",
								url: postUrl,
								data: boxForm.serialize(),
								beforeSend: function() {
									boxForm.find('input').attr('disabled', true).addClass('disabled');
									boxForm.find('textarea').attr('disabled', true).addClass('disabled');
								},
								success: function(data) {
									boxForm.find('h2').css('font-size', '12px').html(data);
									
									if (typeof (Cufon) != "undefined" && Cufon !== null) {
										Cufon.refresh();
									}
									
									setTimeout(function() {
										close(); }, 3000);
									}
								});
							return false;
						}
					});
				}
			});
		});
	};
});

/* Minor Plugins */


(function ($) {
	/* Browse menu */

	$.fn.browseMenu = function () {
		$(this).find('ul:not(:first)').hide();
		$(this).find('a.select').parent('li').show().parent('ul').show().parent('li').show().parent('ul').show();

		this.find('a').click(function () {
			$(this).parent().siblings().children('ul').slideUp();

			var child = $(this).parent().children('ul');

			if (child.is(':hidden')) {
				child.slideDown('slow');
			}
			else {
				child.slideUp('slow');
			}

			if ($(this).attr('href') == "#") {
				return false;
			}
		});

		return this;
	};

	/* Plugin for the image iterators on the landing pages */

	$.fn.imageIterator = function () {
		var container = this;

		container.data("position", {
			position: 2
		});

		var count = 0;

		container.find('img').each(function () {
			if (count > 2) {
				$(this).hide();
			}
			count++;
		});

		container.find('a.prev').click(function () {
			if (container.data("position").position <= 2) {
				return;
			}

			container.find('img').eq(container.data("position").position - 3).show();
			container.data("position", {
				position: container.data("position").position - 1
			});
			container.find('img').eq(container.data("position").position + 1).hide();
		});

		container.find('a.next').click(function () {
			if (container.data("position").position >= container.find('img').length - 1) {
				return;
			}

			container.find('img').eq(container.data("position").position + 1).show();
			container.data("position", {
				position: container.data("position").position + 1
			});
			container.find('img').eq(container.data("position").position - 3).hide();
		});
	};

	/* Plugin for the drop-down page menus */

	$.fn.dropdownMenu = function () {
		var menu = this;

		menu.find('li').mouseover(function () {
			$(this).children('ul:hidden').show();
		}).mouseout(function () {
			$(this).children('ul:visible').hide();
		});

		return this;
	};

	$.fn.nmcDropDown = function (options) {

		// build main options before element iteration
		var opts = $.extend({}, $.fn.nmcDropDown.defaults, options);

		// iterate each matched element
		return this.each(function () {
			var menu = $(this);
			submenus = menu.children('li:has(' + opts.submenu_selector + ')');

			if (opts.fix_IE) {
				// Fix IE 6+7 z-index bug
				menu.css('z-index', 71).parents().each(function (i) {
					if ($(this).css('position') == 'relative') {
						$(this).css('z-index', (i + 72));
					}
				});
				submenus.children(opts.submenu_selector).css('z-index', 70);
			}

			if (opts.fix_IE_less) {
				// Fix IE 6+7 z-index bug
				menu.css('z-index', 31).parents().each(function (i) {
					if ($(this).css('position') == 'relative') {
						$(this).css('z-index', (i + 32));
					}
				});
				submenus.children(opts.submenu_selector).css('z-index', 30);
			}


			// Function that is called to show the submenu
			over = function () {
				$(this).addClass(opts.active_class).children(opts.submenu_selector).animate(opts.show, opts.show_speed);
				return false;
			};

			// Function that is called to hide the submenu
			out = function () {
				$(this).removeClass(opts.active_class).children(opts.submenu_selector).animate(opts.hide, opts.hide_speed);
				return false;
			};

			// Show and hide the sub-menus
			if (opts.trigger == 'click') {
				submenus.toggle(over, out).children(opts.submenu_selector).hide();
			} else if ($().hoverIntent) {
				submenus.hoverIntent({
					interval: opts.show_delay,
					over: over,
					timeout: opts.hide_delay,
					out: out
				}).children(opts.submenu_selector).hide();
			} else {
				submenus.hover(over, out).children(opts.submenu_selector).hide();
			}
		});
	};

	// Default options
	$.fn.nmcDropDown.defaults = {
		trigger: 'hover',
		// Event to show and hide sub-menu - hover or click
		active_class: 'open',
		// Class to give open menu items
		submenu_selector: 'ul',
		// The element immediately below the <li> containing the sub-menu
		show: {
			opacity: 'show'
		},
		// Effect(s) to use when showing the sub-menu
		show_speed: 300,
		// Speed of the show transition
		show_delay: 50,
		// Delay before the sub-menu is show (requires HoverIntent)
		hide: {
			opacity: 'hide'
		},
		// Effect(s) to use when hiding the sub-menu
		hide_speed: 200,
		// Speed of the hide transition
		hide_delay: 100,
		// Delay before the sub-menu is hidden (requires HoverIntent)
		fix_IE: true,
		// IE 6 and 7 have problems with z-indexes. This tries to fix them
		fix_IE_less: false // IE 6 and 7 have problems with z-indexes. This tries to fix them
	};

	/**
	 * hoverIntent is similar to jQuery's built-in "hover" function except that
	 * instead of firing the onMouseOver event immediately, hoverIntent checks
	 * to see if the user's mouse has slowed down (beneath the sensitivity
	 * threshold) before firing the onMouseOver event.
	 * 
	 * hoverIntent r5 // 2007.03.27 // jQuery 1.1.2+
	 * <http://cherne.net/brian/resources/jquery.hoverIntent.html>
	 * 
	 * hoverIntent is currently available for use in all personal or commercial 
	 * projects under both MIT and GPL licenses. This means that you can choose 
	 * the license that best suits your project, and use it accordingly.
	 * 
	 * // basic usage (just like .hover) receives onMouseOver and onMouseOut functions
	 * $("ul li").hoverIntent( showNav , hideNav );
	 * 
	 * // advanced usage receives configuration object only
	 * $("ul li").hoverIntent({
	 *	sensitivity: 7, // number = sensitivity threshold (must be 1 or higher)
	 *	interval: 100,	 // number = milliseconds of polling interval
	 *	over: showNav,	// function = onMouseOver callback (required)
	 *	timeout: 0,	  // number = milliseconds delay before onMouseOut function call
	 *	out: hideNav	// function = onMouseOut callback (required)
	 * });
	 * 
	 * @param  f  onMouseOver function || An object with configuration options
	 * @param  g  onMouseOut function  || Nothing (use configuration options object)
	 * @author	  Brian Cherne <brian@cherne.net>
	 */

	$.fn.hoverIntent = function (f, g) {
		// default configuration options
		var cfg = {
			sensitivity: 7,
			interval: 100,
			timeout: 0
		};
		// override configuration options with user supplied object
		cfg = $.extend(cfg, g ? {
			over: f,
			out: g
		} : f);

		// instantiate variables
		// cX, cY = current X and Y position of mouse, updated by mousemove event
		// pX, pY = previous X and Y position of mouse, set by mouseover and polling interval
		var cX, cY, pX, pY;

		// A private function for getting mouse position
		var track = function (ev) {
			cX = ev.pageX;
			cY = ev.pageY;
		};

		// A private function for comparing current and previous mouse position
		var compare = function (ev, ob) {
			ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
			// compare mouse positions to see if they've crossed the threshold
			if ((Math.abs(pX - cX) + Math.abs(pY - cY)) < cfg.sensitivity) {
				$(ob).unbind("mousemove", track);
				// set hoverIntent state to true (so mouseOut can be called)
				ob.hoverIntent_s = 1;
				return cfg.over.apply(ob, [ev]);
			} else {
				// set previous coordinates for next time
				pX = cX;
				pY = cY;
				// use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs)
				ob.hoverIntent_t = setTimeout(function () {
					compare(ev, ob);
				}, cfg.interval);
			}
		};

		// A private function for delaying the mouseOut function
		var delay = function (ev, ob) {
			ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
			ob.hoverIntent_s = 0;
			return cfg.out.apply(ob, [ev]);
		};

		// A private function for handling mouse 'hovering'
		var handleHover = function (e) {
			// next three lines copied from jQuery.hover, ignore children onMouseOver/onMouseOut
			var p = (e.type == "mouseover" ? e.fromElement : e.toElement) || e.relatedTarget;
			while (p && p != this) {
				try {
					p = p.parentNode;
				} catch (er) {
					p = this;
				}
			}
			if (p == this) {
				return false;
			}

			// copy objects to be passed into t (required for event object to be passed in IE)
			var ev = jQuery.extend({}, e);
			var ob = this;

			// cancel hoverIntent timer if it exists
			if (ob.hoverIntent_t) {
				ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
			}

			// else e.type == "onmouseover"
			if (e.type == "mouseover") {
				// set "previous" X and Y position based on initial entry point
				pX = ev.pageX;
				pY = ev.pageY;
				// update "current" X and Y position based on mousemove
				$(ob).bind("mousemove", track);
				// start polling interval (self-calling timeout) to compare mouse coordinates over time
				if (ob.hoverIntent_s != 1) {
					ob.hoverIntent_t = setTimeout(function () {
						compare(ev, ob);
					}, cfg.interval);
				}

				// else e.type == "onmouseout"
			} else {
				// unbind expensive mousemove event
				$(ob).unbind("mousemove", track);
				// if hoverIntent state is true, then call the mouseOut function after the specified delay
				if (ob.hoverIntent_s == 1) {
					ob.hoverIntent_t = setTimeout(function () {
						delay(ev, ob);
					}, cfg.timeout);
				}
			}
		};

		// bind the function to the two event listeners
		return this.mouseover(handleHover).mouseout(handleHover);
	};

})(jQuery);



// Special Events
(function () {

	var special = jQuery.event.special,
		uid1 = 'D' + (+new Date()),
		uid2 = 'D' + (+new Date() + 1);

	special.scrollstart = {
		setup: function () {

			var timer, handler = function (evt) {

				var _self = this,
					_args = arguments;

				if (timer) {
					clearTimeout(timer);
				} else {
					evt.type = 'scrollstart';
					jQuery.event.handle.apply(_self, _args);
				}

				timer = setTimeout(function () {
					timer = null;
				}, special.scrollstop.latency);

			};

			jQuery(this).bind('scroll', handler).data(uid1, handler);

		},
		teardown: function () {
			jQuery(this).unbind('scroll', jQuery(this).data(uid1));
		}
	};

	special.scrollstop = {
		latency: 300,
		setup: function () {

			var timer, handler = function (evt) {

				var _self = this,
					_args = arguments;

				if (timer) {
					clearTimeout(timer);
				}

				timer = setTimeout(function () {

					timer = null;
					evt.type = 'scrollstop';
					jQuery.event.handle.apply(_self, _args);

				}, special.scrollstop.latency);

			};

			jQuery(this).bind('scroll', handler).data(uid2, handler);

		},
		teardown: function () {
			jQuery(this).unbind('scroll', jQuery(this).data(uid2));
		}
	};
})();


/*
 * Superfish v1.4.8 - jQuery menu widget
 * Copyright (c) 2008 Joel Birch
 *
 * Dual licensed under the MIT and GPL licenses:
 * 	http://www.opensource.org/licenses/mit-license.php
 * 	http://www.gnu.org/licenses/gpl.html
 *
 * CHANGELOG: http://users.tpg.com.au/j_birch/plugins/superfish/changelog.txt
 */

(function($){
	$.fn.superfish = function(op){

		var sf = $.fn.superfish,
			c = sf.c,
			$arrow = $(['<span class="',c.arrowClass,'"> &#187;</span>'].join('')),
			over = function(){
				var $$ = $(this), menu = getMenu($$);
				clearTimeout(menu.sfTimer);
				$$.showSuperfishUl().siblings().hideSuperfishUl();
			},
			out = function(){
				var $$ = $(this), menu = getMenu($$), o = sf.op;
				clearTimeout(menu.sfTimer);
				menu.sfTimer=setTimeout(function(){
					o.retainPath=($.inArray($$[0],o.$path)>-1);
					$$.hideSuperfishUl();
					if (o.$path.length && $$.parents(['li.',o.hoverClass].join('')).length<1){over.call(o.$path);}
				},o.delay);	
			},
			getMenu = function($menu){
				var menu = $menu.parents(['ul.',c.menuClass,':first'].join(''))[0];
				sf.op = sf.o[menu.serial];
				return menu;
			},
			addArrow = function($a){ $a.addClass(c.anchorClass).append($arrow.clone()); };
			
		return this.each(function() {
			var s = this.serial = sf.o.length;
			var o = $.extend({},sf.defaults,op);
			o.$path = $('li.'+o.pathClass,this).slice(0,o.pathLevels).each(function(){
				$(this).addClass([o.hoverClass,c.bcClass].join(' '))
					.filter('li:has(ul)').removeClass(o.pathClass);
			});
			sf.o[s] = sf.op = o;
			
			$('li:has(ul)',this)[($.fn.hoverIntent && !o.disableHI) ? 'hoverIntent' : 'hover'](over,out).each(function() {
				if (o.autoArrows) addArrow( $('>a:first-child',this) );
			})
			.not('.'+c.bcClass)
				.hideSuperfishUl();
			
			var $a = $('a',this);
			$a.each(function(i){
				var $li = $a.eq(i).parents('li');
				$a.eq(i).focus(function(){over.call($li);}).blur(function(){out.call($li);});
			});
			o.onInit.call(this);
			
		}).each(function() {
			var menuClasses = [c.menuClass];
			if (sf.op.dropShadows  && !($.browser.msie && $.browser.version < 7)) menuClasses.push(c.shadowClass);
			$(this).addClass(menuClasses.join(' '));
		});
	};

	var sf = $.fn.superfish;
	sf.o = [];
	sf.op = {};
	sf.IE7fix = function(){
		var o = sf.op;
		if ($.browser.msie && $.browser.version > 6 && o.dropShadows && o.animation.opacity!=undefined)
			this.toggleClass(sf.c.shadowClass+'-off');
		};
	sf.c = {
		bcClass     : 'sf-breadcrumb',
		menuClass   : 'sf-js-enabled',
		anchorClass : 'sf-with-ul',
		arrowClass  : 'sf-sub-indicator',
		shadowClass : 'sf-shadow'
	};
	sf.defaults = {
		hoverClass	: 'sfHover',
		pathClass	: 'overideThisToUse',
		pathLevels	: 1,
		delay		: 300,
		animation	: {opacity:'show'},
		speed		: 'normal',
		autoArrows	: false,
		dropShadows : true,
		disableHI	: false,		// true disables hoverIntent detection
		onInit		: function(){}, // callback functions
		onBeforeShow: function(){},
		onShow		: function(){},
		onHide		: function(){}
	};
	$.fn.extend({
		hideSuperfishUl : function(){
			var o = sf.op,
				not = (o.retainPath===true) ? o.$path : '';
			o.retainPath = false;
			var $ul = $(['li.',o.hoverClass].join(''),this).add(this).not(not).removeClass(o.hoverClass)
					.find('>ul').hide().css('visibility','hidden');
			o.onHide.call($ul);
			return this;
		},
		showSuperfishUl : function(){
			var o = sf.op,
				sh = sf.c.shadowClass+'-off',
				$ul = this.addClass(o.hoverClass)
					.find('>ul:hidden').css('visibility','visible');
			sf.IE7fix.call($ul);
			o.onBeforeShow.call($ul);
			$ul.animate(o.animation,o.speed,function(){ sf.IE7fix.call($ul); o.onShow.call($ul); });
			return this;
		}
	});

})(jQuery);



/*
 * jQuery BBQ: Back Button & Query Library - v1.2.1 - 2/17/2010
 * http://benalman.com/projects/jquery-bbq-plugin/
 * 
 * Copyright (c) 2010 "Cowboy" Ben Alman
 * Dual licensed under the MIT and GPL licenses.
 * http://benalman.com/about/license/
 */
(function($,p){var i,m=Array.prototype.slice,r=decodeURIComponent,a=$.param,c,l,v,b=$.bbq=$.bbq||{},q,u,j,e=$.event.special,d="hashchange",A="querystring",D="fragment",y="elemUrlAttr",g="location",k="href",t="src",x=/^.*\?|#.*$/g,w=/^.*\#/,h,C={};function E(F){return typeof F==="string"}function B(G){var F=m.call(arguments,1);return function(){return G.apply(this,F.concat(m.call(arguments)))}}function n(F){return F.replace(/^[^#]*#?(.*)$/,"$1")}function o(F){return F.replace(/(?:^[^?#]*\?([^#]*).*$)?.*/,"$1")}function f(H,M,F,I,G){var O,L,K,N,J;if(I!==i){K=F.match(H?/^([^#]*)\#?(.*)$/:/^([^#?]*)\??([^#]*)(#?.*)/);J=K[3]||"";if(G===2&&E(I)){L=I.replace(H?w:x,"")}else{N=l(K[2]);I=E(I)?l[H?D:A](I):I;L=G===2?I:G===1?$.extend({},I,N):$.extend({},N,I);L=a(L);if(H){L=L.replace(h,r)}}O=K[1]+(H?"#":L||!K[1]?"?":"")+L+J}else{O=M(F!==i?F:p[g][k])}return O}a[A]=B(f,0,o);a[D]=c=B(f,1,n);c.noEscape=function(G){G=G||"";var F=$.map(G.split(""),encodeURIComponent);h=new RegExp(F.join("|"),"g")};c.noEscape(",/");$.deparam=l=function(I,F){var H={},G={"true":!0,"false":!1,"null":null};$.each(I.replace(/\+/g," ").split("&"),function(L,Q){var K=Q.split("="),P=r(K[0]),J,O=H,M=0,R=P.split("]["),N=R.length-1;if(/\[/.test(R[0])&&/\]$/.test(R[N])){R[N]=R[N].replace(/\]$/,"");R=R.shift().split("[").concat(R);N=R.length-1}else{N=0}if(K.length===2){J=r(K[1]);if(F){J=J&&!isNaN(J)?+J:J==="undefined"?i:G[J]!==i?G[J]:J}if(N){for(;M<=N;M++){P=R[M]===""?O.length:R[M];O=O[P]=M<N?O[P]||(R[M+1]&&isNaN(R[M+1])?{}:[]):J}}else{if($.isArray(H[P])){H[P].push(J)}else{if(H[P]!==i){H[P]=[H[P],J]}else{H[P]=J}}}}else{if(P){H[P]=F?i:""}}});return H};function z(H,F,G){if(F===i||typeof F==="boolean"){G=F;F=a[H?D:A]()}else{F=E(F)?F.replace(H?w:x,""):F}return l(F,G)}l[A]=B(z,0);l[D]=v=B(z,1);$[y]||($[y]=function(F){return $.extend(C,F)})({a:k,base:k,iframe:t,img:t,input:t,form:"action",link:k,script:t});j=$[y];function s(I,G,H,F){if(!E(H)&&typeof H!=="object"){F=H;H=G;G=i}return this.each(function(){var L=$(this),J=G||j()[(this.nodeName||"").toLowerCase()]||"",K=J&&L.attr(J)||"";L.attr(J,a[I](K,H,F))})}$.fn[A]=B(s,A);$.fn[D]=B(s,D);b.pushState=q=function(I,F){if(E(I)&&/^#/.test(I)&&F===i){F=2}var H=I!==i,G=c(p[g][k],H?I:{},H?F:2);p[g][k]=G+(/#/.test(G)?"":"#")};b.getState=u=function(F,G){return F===i||typeof F==="boolean"?v(F):v(G)[F]};b.removeState=function(F){var G={};if(F!==i){G=u();$.each($.isArray(F)?F:arguments,function(I,H){delete G[H]})}q(G,2)};e[d]=$.extend(e[d],{add:function(F){var H;function G(J){var I=J[D]=c();J.getState=function(K,L){return K===i||typeof K==="boolean"?l(I,K):l(I,L)[K]};H.apply(this,arguments)}if($.isFunction(F)){H=F;return G}else{H=F.handler;F.handler=G}}})})(jQuery,this);
/*
 * jQuery hashchange event - v1.2 - 2/11/2010
 * http://benalman.com/projects/jquery-hashchange-plugin/
 * 
 * Copyright (c) 2010 "Cowboy" Ben Alman
 * Dual licensed under the MIT and GPL licenses.
 * http://benalman.com/about/license/
 */
(function($,i,b){var j,k=$.event.special,c="location",d="hashchange",l="href",f=$.browser,g=document.documentMode,h=f.msie&&(g===b||g<8),e="on"+d in i&&!h;function a(m){m=m||i[c][l];return m.replace(/^[^#]*#?(.*)$/,"$1")}$[d+"Delay"]=100;k[d]=$.extend(k[d],{setup:function(){if(e){return false}$(j.start)},teardown:function(){if(e){return false}$(j.stop)}});j=(function(){var m={},r,n,o,q;function p(){o=q=function(s){return s};if(h){n=$('<iframe src="javascript:0"/>').hide().insertAfter("body")[0].contentWindow;q=function(){return a(n.document[c][l])};o=function(u,s){if(u!==s){var t=n.document;t.open().close();t[c].hash="#"+u}};o(a())}}m.start=function(){if(r){return}var t=a();o||p();(function s(){var v=a(),u=q(t);if(v!==t){o(t=v,u);$(i).trigger(d)}else{if(u!==t){i[c][l]=i[c][l].replace(/#.*/,"")+"#"+u}}r=setTimeout(s,$[d+"Delay"])})()};m.stop=function(){if(!n){r&&clearTimeout(r);r=0}};return m})()})(jQuery,this);
