﻿// mousewheel
/* Copyright (c) 2006 Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
 *
 * $LastChangedDate: 2007-12-20 09:02:08 -0600 (Thu, 20 Dec 2007) $
 * $Rev: 4265 $
 *
 * Version: 3.0
 * 
 * Requires: $ 1.2.2+
 */

(function($) {

$.event.special.mousewheel = {
	setup: function() {
		var handler = $.event.special.mousewheel.handler;
		
		// Fix pageX, pageY, clientX and clientY for mozilla
		if ( $.browser.mozilla )
			$(this).bind('mousemove.mousewheel', function(event) {
				$.data(this, 'mwcursorposdata', {
					pageX: event.pageX,
					pageY: event.pageY,
					clientX: event.clientX,
					clientY: event.clientY
				});
			});
	
		if ( this.addEventListener )
			this.addEventListener( ($.browser.mozilla ? 'DOMMouseScroll' : 'mousewheel'), handler, false);
		else
			this.onmousewheel = handler;
	},
	
	teardown: function() {
		var handler = $.event.special.mousewheel.handler;
		
		$(this).unbind('mousemove.mousewheel');
		
		if ( this.removeEventListener )
			this.removeEventListener( ($.browser.mozilla ? 'DOMMouseScroll' : 'mousewheel'), handler, false);
		else
			this.onmousewheel = function(){};
		
		$.removeData(this, 'mwcursorposdata');
	},
	
	handler: function(event) {
		var args = Array.prototype.slice.call( arguments, 1 );
		
		event = $.event.fix(event || window.event);
		// Get correct pageX, pageY, clientX and clientY for mozilla
		$.extend( event, $.data(this, 'mwcursorposdata') || {} );
		var delta = 0, returnValue = true;
		
		if ( event.wheelDelta ) delta = event.wheelDelta/120;
		if ( event.detail     ) delta = -event.detail/3;
//		if ( $.browser.opera  ) delta = -event.wheelDelta;
		
		event.data  = event.data || {};
		event.type  = "mousewheel";
		
		// Add delta to the front of the arguments
		args.unshift(delta);
		// Add event to the front of the arguments
		args.unshift(event);

		return $.event.handle.apply(this, args);
	}
};

$.fn.extend({
	mousewheel: function(fn) {
		return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");
	},
	
	unmousewheel: function(fn) {
		return this.unbind("mousewheel", fn);
	}
});

})(jQuery);

// em font sizes
/**
 * @projectDescription Monitor Font Size Changes with jQuery
 *
 * @version 1.0
 * @author Dave Cardwell
 *
 * jQuery-Em - $Revision: 24 $ ($Date: 2007-08-19 11:24:56 +0100 (Sun, 19 Aug 2007) $)
 * http://davecardwell.co.uk/javascript/jquery/plugins/jquery-em/
 *
 * Copyright ©2007 Dave Cardwell <http://davecardwell.co.uk/>
 *
 * Released under the MIT licence:
 * http://www.opensource.org/licenses/mit-license.php
 */

// Upon $(document).ready()…
jQuery(function($) {
    // Configuration…
    var eventName = 'emchange';
    
    
    // Set up default options.
    $.em = $.extend({
        /**
         * The jQuery-Em version string.
         *
         * @example $.em.version;
         * @desc '1.0a'
         *
         * @property
         * @name version
         * @type String
         * @cat Plugins/Em
         */
        version: '1.0',
        
        /**
         * The number of milliseconds to wait when polling for changes to the
         * font size.
         *
         * @example $.em.delay = 400;
         * @desc Defaults to 200.
         *
         * @property
         * @name delay
         * @type Number
         * @cat Plugins/Em
         */
        delay: 200,
        
        /**
         * The element used to detect changes to the font size.
         *
         * @example $.em.element = $('<div />')[0];
         * @desc Default is an empty, absolutely positioned, 100em-wide <div>.
         *
         * @private
         * @property
         * @name element
         * @type Element
         * @cat Plugins/Em
         */
        element: $('<div />').css({ left:     '-100em',
                                    position: 'absolute',
                                    width:    '100em' })
                             .prependTo('body')[0],
        
        /**
         * The action to perform when a change in the font size is detected.
         *
         * @example $.em.action = function() { ... }
         * @desc The default action is to trigger a global “emchange” event.
         * You probably shouldn’t change this behaviour as other plugins may
         * rely on it, but the option is here for completion.
         *
         * @example $(document).bind('emchange', function(e, cur, prev) {...})
         * @desc Any functions triggered on this event are passed the current
         * font size, and last known font size as additional parameters.
         *
         * @private
         * @property
         * @name action
         * @type Function
         * @cat Plugins/Em
         * @see current
         * @see previous
         */
        action: function() {
            var currentWidth = $.em.element.offsetWidth / 100;
            
            // If the font size has changed since we last checked…
            if ( currentWidth != $.em.current ) {
                /**
                 * The previous pixel value of the user agent’s font size. See
                 * $.em.current for caveats. Will initially be undefined until
                 * the “emchange” event is triggered.
                 *
                 * @example $.em.previous;
                 * @result 16
                 *
                 * @property
                 * @name previous
                 * @type Number
                 * @cat Plugins/Em
                 * @see current
                 */
                $.em.previous = $.em.current;
                
                /**
                 * The current pixel value of the user agent’s font size. As
                 * with $.em.previous, this value *may* be subject to minor
                 * browser rounding errors that mean you might not want to
                 * rely upon it as an absolute value.
                 *
                 * @example $.em.current;
                 * @result 14
                 *
                 * @property
                 * @name current
                 * @type Number
                 * @cat Plugins/Em
                 * @see previous
                 */
                $.em.current = currentWidth;
                
                $.event.trigger(eventName, [$.em.current, $.em.previous]);
            }
        }
    }, $.em );
    
    
    /**
     * Bind a function to the emchange event of each matched element.
     *
     * @example $("p").emchange( function() { alert("Hello"); } );
     *
     * @name emchange
     * @type jQuery
     * @param Function fn A function to bind to the emchange event.
     * @cat Plugins/Em
     */

    /**
     * Trigger the emchange event of each matched element.
     *
     * @example $("p").emchange()
     *
     * @name emchange
     * @type jQuery
     * @cat Plugins/Em
     */
    $.fn[eventName] = function(fn) { return fn ? this.bind(eventName, fn)
                                               : this.trigger(eventName); };
    
    
    // Store the initial pixel value of the user agent’s font size.
    $.em.current = $.em.element.offsetWidth / 100;
    
    /**
     * While polling for font-size changes, $.em.iid stores the intervalID in
     * case you should want to cancel with clearInterval().
     *
     * @example window.clearInterval( $.em.iid );
     * 
     * @property
     * @name iid
     * @type Number
     * @cat Plugins/Em
     */
    $.em.iid = setInterval( $.em.action, $.em.delay );
});

// scrollpane
/* Copyright (c) 2009 Kelvin Luck (kelvin AT kelvinluck DOT com || http://www.kelvinluck.com)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 * 
 * See http://kelvinluck.com/assets/jquery/jScrollPane/
 * $Id: jScrollPane.js 90 2010-01-25 03:52:10Z kelvin.luck $
 */

/**
 * Replace the vertical scroll bars on any matched elements with a fancy
 * styleable (via CSS) version. With JS disabled the elements will
 * gracefully degrade to the browsers own implementation of overflow:auto.
 * If the mousewheel plugin has been included on the page then the scrollable areas will also
 * respond to the mouse wheel.
 *
 * @example jQuery(".scroll-pane").jScrollPane();
 *
 * @name jScrollPane
 * @type jQuery
 * @param Object	settings	hash with options, described below.
 *								scrollbarWidth	-	The width of the generated scrollbar in pixels
 *								scrollbarMargin	-	The amount of space to leave on the side of the scrollbar in pixels
 *								wheelSpeed		-	The speed the pane will scroll in response to the mouse wheel in pixels
 *								showArrows		-	Whether to display arrows for the user to scroll with
 *								arrowSize		-	The height of the arrow buttons if showArrows=true
 *								animateTo		-	Whether to animate when calling scrollTo and scrollBy
 *								dragMinHeight	-	The minimum height to allow the drag bar to be
 *								dragMaxHeight	-	The maximum height to allow the drag bar to be
 *								animateInterval	-	The interval in milliseconds to update an animating scrollPane (default 100)
 *								animateStep		-	The amount to divide the remaining scroll distance by when animating (default 3)
 *								maintainPosition-	Whether you want the contents of the scroll pane to maintain it's position when you re-initialise it - so it doesn't scroll as you add more content (default true)
 *								tabIndex		-	The tabindex for this jScrollPane to control when it is tabbed to when navigating via keyboard (default 0)
 *								enableKeyboardNavigation - Whether to allow keyboard scrolling of this jScrollPane when it is focused (default true)
 *								animateToInternalLinks - Whether the move to an internal link (e.g. when it's focused by tabbing or by a hash change in the URL) should be animated or instant (default false)
 *								scrollbarOnLeft	-	Display the scrollbar on the left side?  (needs stylesheet changes, see examples.html)
 *								reinitialiseOnImageLoad - Whether the jScrollPane should automatically re-initialise itself when any contained images are loaded (default false)
 *								topCapHeight	-	The height of the "cap" area between the top of the jScrollPane and the top of the track/ buttons
 *								bottomCapHeight	-	The height of the "cap" area between the bottom of the jScrollPane and the bottom of the track/ buttons
 *								observeHash		-	Whether jScrollPane should attempt to automagically scroll to the correct place when an anchor inside the scrollpane is linked to (default true)
 * @return jQuery
 * @cat Plugins/jScrollPane
 * @author Kelvin Luck (kelvin AT kelvinluck DOT com || http://www.kelvinluck.com)
 */

(function($) {

$.jScrollPane = {
	active : []
};
$.fn.jScrollPane = function(settings)
{
	settings = $.extend({}, $.fn.jScrollPane.defaults, settings);

	var rf = function() { return false; };
	
	return this.each(
		function()
		{
			var $this = $(this);
			var paneEle = this;
			var currentScrollPosition = 0;
			var paneWidth;
			var paneHeight;
			var trackHeight;
			var trackOffset = settings.topCapHeight;
			var $container;
			
			if ($(this).parent().is('.jScrollPaneContainer')) {
				$container = $(this).parent();
				currentScrollPosition = settings.maintainPosition ? $this.position().top : 0;
				var $c = $(this).parent();
				paneWidth = $c.innerWidth();
				paneHeight = $c.outerHeight();
				$('>.jScrollPaneTrack, >.jScrollArrowUp, >.jScrollArrowDown, >.jScrollCap', $c).remove();
				$this.css({'top':0});
			} else {
				$this.data('originalStyleTag', $this.attr('style'));
				// Switch the element's overflow to hidden to ensure we get the size of the element without the scrollbars [http://plugins.jquery.com/node/1208]
				$this.css('overflow', 'hidden');
				this.originalPadding = $this.css('paddingTop') + ' ' + $this.css('paddingRight') + ' ' + $this.css('paddingBottom') + ' ' + $this.css('paddingLeft');
				this.originalSidePaddingTotal = (parseInt($this.css('paddingLeft')) || 0) + (parseInt($this.css('paddingRight')) || 0);
				paneWidth = $this.innerWidth();
				paneHeight = $this.innerHeight();
				$container = $('<div></div>')
					.attr({'className':'jScrollPaneContainer'})
					.css(
						{
							'height':paneHeight+'px', 
							'width':paneWidth+'px'
						}
					);
				if (settings.enableKeyboardNavigation) {
					$container.attr(
						'tabindex', 
						settings.tabIndex
					);
				}
				$this.wrap($container);
				$container = $this.parent();
				// deal with text size changes (if the jquery.em plugin is included)
				// and re-initialise the scrollPane so the track maintains the
				// correct size
				$(document).bind(
					'emchange', 
					function(e, cur, prev)
					{
						$this.jScrollPane(settings);
					}
				);
				
			}
			trackHeight = paneHeight;
			
			if (settings.reinitialiseOnImageLoad) {
				// code inspired by jquery.onImagesLoad: http://plugins.jquery.com/project/onImagesLoad
				// except we re-initialise the scroll pane when each image loads so that the scroll pane is always up to size...
				// TODO: Do I even need to store it in $.data? Is a local variable here the same since I don't pass the reinitialiseOnImageLoad when I re-initialise?
				var $imagesToLoad = $.data(paneEle, 'jScrollPaneImagesToLoad') || $('img', $this);
				var loadedImages = [];
				
				if ($imagesToLoad.length) {
					$imagesToLoad.each(function(i, val)	{
						$(this).bind('load readystatechange', function() {
							if($.inArray(i, loadedImages) == -1){ //don't double count images
								loadedImages.push(val); //keep a record of images we've seen
								$imagesToLoad = $.grep($imagesToLoad, function(n, i) {
									return n != val;
								});
								$.data(paneEle, 'jScrollPaneImagesToLoad', $imagesToLoad);
								var s2 = $.extend(settings, {reinitialiseOnImageLoad:false});
								$this.jScrollPane(s2); // re-initialise
							}
						}).each(function(i, val) {
							if(this.complete || this.complete===undefined) { 
								//needed for potential cached images
								this.src = this.src; 
							} 
						});
					});
				};
			}

			var p = this.originalSidePaddingTotal;
			var realPaneWidth = paneWidth - settings.scrollbarWidth - settings.scrollbarMargin - p;

			var cssToApply = {
				'height':'auto',
				'width': realPaneWidth + 'px'
			}

			if(settings.scrollbarOnLeft) {
				cssToApply.paddingLeft = settings.scrollbarMargin + settings.scrollbarWidth + 'px';
			} else {
				cssToApply.paddingRight = settings.scrollbarMargin + 'px';
			}

			$this.css(cssToApply);

			var contentHeight = $this.outerHeight();
			var percentInView = paneHeight / contentHeight;
			
			var isScrollable = percentInView < .99;
			$container[isScrollable ? 'addClass' : 'removeClass']('jScrollPaneScrollable');

			if (isScrollable) {
				$container.append(
					$('<div></div>').addClass('jScrollCap jScrollCapTop').css({height:settings.topCapHeight}),
					$('<div></div>').attr({'className':'jScrollPaneTrack'}).css({'width':settings.scrollbarWidth+'px'}).append(
						$('<div></div>').attr({'className':'jScrollPaneDrag'}).css({'width':settings.scrollbarWidth+'px'}).append(
							$('<div></div>').attr({'className':'jScrollPaneDragTop'}).css({'width':settings.scrollbarWidth+'px'}),
							$('<div></div>').attr({'className':'jScrollPaneDragBottom'}).css({'width':settings.scrollbarWidth+'px'})
						)
					),
					$('<div></div>').addClass('jScrollCap jScrollCapBottom').css({height:settings.bottomCapHeight})
				);
				
				var $track = $('>.jScrollPaneTrack', $container);
				var $drag = $('>.jScrollPaneTrack .jScrollPaneDrag', $container);
				
				
				var currentArrowDirection;
				var currentArrowTimerArr = [];// Array is used to store timers since they can stack up when dealing with keyboard events. This ensures all timers are cleaned up in the end, preventing an acceleration bug.
				var currentArrowInc;
				var whileArrowButtonDown = function() 
				{
					if (currentArrowInc > 4 || currentArrowInc % 4 == 0) {
						positionDrag(dragPosition + currentArrowDirection * mouseWheelMultiplier);
					}
					currentArrowInc++;
				};

				if (settings.enableKeyboardNavigation) {
					$container.bind(
						'keydown.jscrollpane',
						function(e) 
						{
							switch (e.keyCode) {
								case 38: //up
									currentArrowDirection = -1;
									currentArrowInc = 0;
									whileArrowButtonDown();
									currentArrowTimerArr[currentArrowTimerArr.length] = setInterval(whileArrowButtonDown, 100);
									return false;
								case 40: //down
									currentArrowDirection = 1;
									currentArrowInc = 0;
									whileArrowButtonDown();
									currentArrowTimerArr[currentArrowTimerArr.length] = setInterval(whileArrowButtonDown, 100);
									return false;
								case 33: // page up
								case 34: // page down
									// TODO
									return false;
								default:
							}
						}
					).bind(
						'keyup.jscrollpane',
						function(e) 
						{
							if (e.keyCode == 38 || e.keyCode == 40) {
								for (var i = 0; i < currentArrowTimerArr.length; i++) {
									clearInterval(currentArrowTimerArr[i]);
								}
								return false;
							}
						}
					);
				}

				if (settings.showArrows) {
					
					var currentArrowButton;
					var currentArrowInterval;

					var onArrowMouseUp = function(event)
					{
						$('html').unbind('mouseup', onArrowMouseUp);
						currentArrowButton.removeClass('jScrollActiveArrowButton');
						clearInterval(currentArrowInterval);
					};
					var onArrowMouseDown = function() {
						$('html').bind('mouseup', onArrowMouseUp);
						currentArrowButton.addClass('jScrollActiveArrowButton');
						currentArrowInc = 0;
						whileArrowButtonDown();
						currentArrowInterval = setInterval(whileArrowButtonDown, 100);
					};
					$container
						.append(
							$('<a></a>')
								.attr(
									{
										'href':'javascript:;', 
										'className':'jScrollArrowUp', 
										'tabindex':-1
									}
								)
								.css(
									{
										'width':settings.scrollbarWidth+'px',
										'top':settings.topCapHeight + 'px'
									}
								)
								.html('Scroll up')
								.bind('mousedown', function()
								{
									currentArrowButton = $(this);
									currentArrowDirection = -1;
									onArrowMouseDown();
									this.blur();
									return false;
								})
								.bind('click', rf),
							$('<a></a>')
								.attr(
									{
										'href':'javascript:;', 
										'className':'jScrollArrowDown', 
										'tabindex':-1
									}
								)
								.css(
									{
										'width':settings.scrollbarWidth+'px',
										'bottom':settings.bottomCapHeight + 'px'
									}
								)
								.html('Scroll down')
								.bind('mousedown', function()
								{
									currentArrowButton = $(this);
									currentArrowDirection = 1;
									onArrowMouseDown();
									this.blur();
									return false;
								})
								.bind('click', rf)
						);
					var $upArrow = $('>.jScrollArrowUp', $container);
					var $downArrow = $('>.jScrollArrowDown', $container);
				}
				
				if (settings.arrowSize) {
					trackHeight = paneHeight - settings.arrowSize - settings.arrowSize;
					trackOffset += settings.arrowSize;
				} else if ($upArrow) {
					var topArrowHeight = $upArrow.height();
					settings.arrowSize = topArrowHeight;
					trackHeight = paneHeight - topArrowHeight - $downArrow.height();
					trackOffset += topArrowHeight;
				}
				trackHeight -= settings.topCapHeight + settings.bottomCapHeight;
				$track.css({'height': trackHeight+'px', top:trackOffset+'px'})
				
				var $pane = $(this).css({'position':'absolute', 'overflow':'visible'});
				
				var currentOffset;
				var maxY;
				var mouseWheelMultiplier;
				// store this in a seperate variable so we can keep track more accurately than just updating the css property..
				var dragPosition = 0;
				var dragMiddle = percentInView*paneHeight/2;
				
				// pos function borrowed from tooltip plugin and adapted...
				var getPos = function (event, c) {
					var p = c == 'X' ? 'Left' : 'Top';
					return event['page' + c] || (event['client' + c] + (document.documentElement['scroll' + p] || document.body['scroll' + p])) || 0;
				};
				
				var ignoreNativeDrag = function() {	return false; };
				
				var initDrag = function()
				{
					ceaseAnimation();
					currentOffset = $drag.offset(false);
					currentOffset.top -= dragPosition;
					maxY = trackHeight - $drag[0].offsetHeight;
					mouseWheelMultiplier = 2 * settings.wheelSpeed * maxY / contentHeight;
				};
				
				var onStartDrag = function(event)
				{
					initDrag();
					dragMiddle = getPos(event, 'Y') - dragPosition - currentOffset.top;
					$('html').bind('mouseup', onStopDrag).bind('mousemove', updateScroll);
					if ($.browser.msie) {
						$('html').bind('dragstart', ignoreNativeDrag).bind('selectstart', ignoreNativeDrag);
					}
					return false;
				};
				var onStopDrag = function()
				{
					$('html').unbind('mouseup', onStopDrag).unbind('mousemove', updateScroll);
					dragMiddle = percentInView*paneHeight/2;
					if ($.browser.msie) {
						$('html').unbind('dragstart', ignoreNativeDrag).unbind('selectstart', ignoreNativeDrag);
					}
				};
				var positionDrag = function(destY)
				{
					$container.scrollTop(0);
					destY = destY < 0 ? 0 : (destY > maxY ? maxY : destY);
					dragPosition = destY;
					$drag.css({'top':destY+'px'});
					var p = destY / maxY;
					$this.data('jScrollPanePosition', (paneHeight-contentHeight)*-p);
					$pane.css({'top':((paneHeight-contentHeight)*p) + 'px'});
					$this.trigger('scroll');
					if (settings.showArrows) {
						$upArrow[destY == 0 ? 'addClass' : 'removeClass']('disabled');
						$downArrow[destY == maxY ? 'addClass' : 'removeClass']('disabled');
					}
				};
				var updateScroll = function(e)
				{
					positionDrag(getPos(e, 'Y') - currentOffset.top - dragMiddle);
				};
				
				var dragH = Math.max(Math.min(percentInView*(paneHeight-settings.arrowSize*2), settings.dragMaxHeight), settings.dragMinHeight);
				
				$drag.css(
					{'height':dragH+'px'}
				).bind('mousedown', onStartDrag);
				
				var trackScrollInterval;
				var trackScrollInc;
				var trackScrollMousePos;
				var doTrackScroll = function()
				{
					if (trackScrollInc > 8 || trackScrollInc%4==0) {
						positionDrag((dragPosition - ((dragPosition - trackScrollMousePos) / 2)));
					}
					trackScrollInc ++;
				};
				var onStopTrackClick = function()
				{
					clearInterval(trackScrollInterval);
					$('html').unbind('mouseup', onStopTrackClick).unbind('mousemove', onTrackMouseMove);
				};
				var onTrackMouseMove = function(event)
				{
					trackScrollMousePos = getPos(event, 'Y') - currentOffset.top - dragMiddle;
				};
				var onTrackClick = function(event)
				{
					initDrag();
					onTrackMouseMove(event);
					trackScrollInc = 0;
					$('html').bind('mouseup', onStopTrackClick).bind('mousemove', onTrackMouseMove);
					trackScrollInterval = setInterval(doTrackScroll, 100);
					doTrackScroll();
					return false;
				};
				
				$track.bind('mousedown', onTrackClick);
				
				$container.bind(
					'mousewheel',
					function (event, delta) {
						delta = delta || (event.wheelDelta ? event.wheelDelta / 120 : (event.detail) ?
-event.detail/3 : 0);
						initDrag();
						ceaseAnimation();
						var d = dragPosition;
						positionDrag(dragPosition - delta * mouseWheelMultiplier);
						var dragOccured = d != dragPosition;
						return !dragOccured;
					}
				);

				var _animateToPosition;
				var _animateToInterval;
				function animateToPosition()
				{
					var diff = (_animateToPosition - dragPosition) / settings.animateStep;
					if (diff > 1 || diff < -1) {
						positionDrag(dragPosition + diff);
					} else {
						positionDrag(_animateToPosition);
						ceaseAnimation();
					}
				}
				var ceaseAnimation = function()
				{
					if (_animateToInterval) {
						clearInterval(_animateToInterval);
						delete _animateToPosition;
					}
				};
				var scrollTo = function(pos, preventAni)
				{
					if (typeof pos == "string") {
						// Legal hash values aren't necessarily legal jQuery selectors so we need to catch any
						// errors from the lookup...
						try {
							$e = $(pos, $this);
						} catch (err) {
							return;
						}
						if (!$e.length) return;
						pos = $e.offset().top - $this.offset().top;
					}
					ceaseAnimation();
					var maxScroll = contentHeight - paneHeight;
					pos = pos > maxScroll ? maxScroll : pos;
					$this.data('jScrollPaneMaxScroll', maxScroll);
					var destDragPosition = pos/maxScroll * maxY;
					if (preventAni || !settings.animateTo) {
						positionDrag(destDragPosition);
					} else {
						$container.scrollTop(0);
						_animateToPosition = destDragPosition;
						_animateToInterval = setInterval(animateToPosition, settings.animateInterval);
					}
				};
				$this[0].scrollTo = scrollTo;
				
				$this[0].scrollBy = function(delta)
				{
					var currentPos = -parseInt($pane.css('top')) || 0;
					scrollTo(currentPos + delta);
				};
				
				initDrag();
				
				scrollTo(-currentScrollPosition, true);
			
				// Deal with it when the user tabs to a link or form element within this scrollpane
				$('*', this).bind(
					'focus',
					function(event)
					{
						var $e = $(this);
						
						// loop through parents adding the offset top of any elements that are relatively positioned between
						// the focused element and the jScrollPaneContainer so we can get the true distance from the top
						// of the focused element to the top of the scrollpane...
						var eleTop = 0;
						
						while ($e[0] != $this[0]) {
							eleTop += $e.position().top;
							$e = $e.offsetParent();
						}
						
						var viewportTop = -parseInt($pane.css('top')) || 0;
						var maxVisibleEleTop = viewportTop + paneHeight;
						var eleInView = eleTop > viewportTop && eleTop < maxVisibleEleTop;
						if (!eleInView) {
							var destPos = eleTop - settings.scrollbarMargin;
							if (eleTop > viewportTop) { // element is below viewport - scroll so it is at bottom.
								destPos += $(this).height() + 15 + settings.scrollbarMargin - paneHeight;
							}
							scrollTo(destPos);
						}
					}
				)
				
				
				if (settings.observeHash) {
					if (location.hash && location.hash.length > 1) {
						setTimeout(function(){
							scrollTo(location.hash);
						}, $.browser.safari ? 100 : 0);
					}
					
					// use event delegation to listen for all clicks on links and hijack them if they are links to
					// anchors within our content...
					$(document).bind('click', function(e){
						$target = $(e.target);
						if ($target.is('a')) {
							var h = $target.attr('href');
							if (h && h.substr(0, 1) == '#' && h.length > 1) {
								setTimeout(function(){
									scrollTo(h, !settings.animateToInternalLinks);
								}, $.browser.safari ? 100 : 0);
							}
						}
					});
				}
				
				// Deal with dragging and selecting text to make the scrollpane scroll...
				function onSelectScrollMouseDown(e)
				{
				   $(document).bind('mousemove.jScrollPaneDragging', onTextSelectionScrollMouseMove);
				   $(document).bind('mouseup.jScrollPaneDragging',   onSelectScrollMouseUp);
				  
				}
				
				var textDragDistanceAway;
				var textSelectionInterval;
				
				function onTextSelectionInterval()
				{
					direction = textDragDistanceAway < 0 ? -1 : 1;
					$this[0].scrollBy(textDragDistanceAway / 2);
				}

				function clearTextSelectionInterval()
				{
					if (textSelectionInterval) {
						clearInterval(textSelectionInterval);
						textSelectionInterval = undefined;
					}
				}
				
				function onTextSelectionScrollMouseMove(e)
				{
					var offset = $this.parent().offset().top;
					var maxOffset = offset + paneHeight;
					var mouseOffset = getPos(e, 'Y');
					textDragDistanceAway = mouseOffset < offset ? mouseOffset - offset : (mouseOffset > maxOffset ? mouseOffset - maxOffset : 0);
					if (textDragDistanceAway == 0) {
						clearTextSelectionInterval();
					} else {
						if (!textSelectionInterval) {
							textSelectionInterval  = setInterval(onTextSelectionInterval, 100);
						}
					}
				}

				function onSelectScrollMouseUp(e)
				{
				   $(document)
					  .unbind('mousemove.jScrollPaneDragging')
					  .unbind('mouseup.jScrollPaneDragging');
				   clearTextSelectionInterval();
				}

				$container.bind('mousedown.jScrollPane', onSelectScrollMouseDown);

				
				$.jScrollPane.active.push($this[0]);
				
			} else {
				$this.css(
					{
						'height':paneHeight+'px',
						'width':paneWidth-this.originalSidePaddingTotal+'px',
						'padding':this.originalPadding
					}
				);
				$this[0].scrollTo = $this[0].scrollBy = function() {};
				// clean up listeners
				$this.parent().unbind('mousewheel').unbind('mousedown.jScrollPane').unbind('keydown.jscrollpane').unbind('keyup.jscrollpane');
			}
			
		}
	)
};

$.fn.jScrollPaneRemove = function()
{
	$(this).each(function()
	{
		$this = $(this);
		var $c = $this.parent();
		if ($c.is('.jScrollPaneContainer')) {
			$this.css(
				{
					'top':'',
					'height':'',
					'width':'',
					'padding':'',
					'overflow':'',
					'position':''
				}
			);
			$this.attr('style', $this.data('originalStyleTag'));
			$c.after($this).remove();
		}
	});
}

$.fn.jScrollPane.defaults = {
	scrollbarWidth : 10,
	scrollbarMargin : 5,
	wheelSpeed : 18,
	showArrows : false,
	arrowSize : 0,
	animateTo : false,
	dragMinHeight : 1,
	dragMaxHeight : 99999,
	animateInterval : 100,
	animateStep: 3,
	maintainPosition: true,
	scrollbarOnLeft: false,
	reinitialiseOnImageLoad: false,
	tabIndex : 0,
	enableKeyboardNavigation: true,
	animateToInternalLinks: false,
	topCapHeight: 0,
	bottomCapHeight: 0,
	observeHash: true
};

// clean up the scrollTo expandos
$(window)
	.bind('unload', function() {
		var els = $.jScrollPane.active; 
		for (var i=0; i<els.length; i++) {
			els[i].scrollTo = els[i].scrollBy = null;
		}
	}
);

})(jQuery);

// url parser
jQuery.url=function(){var segments={};var parsed={};var options={url:window.location,strictMode:false,key:["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],q:{name:"queryKey",parser:/(?:^|&)([^&=]*)=?([^&]*)/g},parser:{strict:/^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,loose:/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/}};var parseUri=function(){str=decodeURI(options.url);var m=options.parser[options.strictMode?"strict":"loose"].exec(str);var uri={};var i=14;while(i--){uri[options.key[i]]=m[i]||""}uri[options.q.name]={};uri[options.key[12]].replace(options.q.parser,function($0,$1,$2){if($1){uri[options.q.name][$1]=$2}});return uri};var key=function(key){if(!parsed.length){setUp()}if(key=="base"){if(parsed.port!==null&&parsed.port!==""){return parsed.protocol+"://"+parsed.host+":"+parsed.port+"/"}else{return parsed.protocol+"://"+parsed.host+"/"}}return(parsed[key]==="")?null:parsed[key]};var param=function(item){if(!parsed.length){setUp()}return(parsed.queryKey[item]===null)?null:parsed.queryKey[item]};var setUp=function(){parsed=parseUri();getSegments()};var getSegments=function(){var p=parsed.path;segments=[];segments=parsed.path.length==1?{}:(p.charAt(p.length-1)=="/"?p.substring(1,p.length-1):path=p.substring(1)).split("/")};return{setMode:function(mode){strictMode=mode=="strict"?true:false;return this},setUrl:function(newUri){options.url=newUri===undefined?window.location:newUri;setUp();return this},segment:function(pos){if(!parsed.length){setUp()}if(pos===undefined){return segments.length}return(segments[pos]===""||segments[pos]===undefined)?null:segments[pos]},attr:key,param:param}}();


// clear field

/**
 * jQuery-Plugin "clearField"
 * 
 * @version: 1.1, 04.12.2010
 * 
 * @author: Stijn Van Minnebruggen
 *          stijn@donotfold.be
 *          http://www.donotfold.be
 * 
 * @example: $('selector').clearField();
 * @example: $('selector').clearField({ blurClass: 'myBlurredClass', activeClass: 'myactiveClass' });
 * 
 */
	
	(function($){$.fn.clearField=function(s){s=jQuery.extend({blurClass:'clearFieldBlurred',activeClass:'clearFieldActive',attribute:'rel',value:''},s);return $(this).each(function(){var el=$(this);s.value=el.val();if(el.attr(s.attribute)==undefined){el.attr(s.attribute,el.val()).addClass(s.blurClass)}else{s.value=el.attr(s.attribute)}el.focus(function(){if(el.val()==el.attr(s.attribute)){el.val('').removeClass(s.blurClass).addClass(s.activeClass)}});el.blur(function(){if(el.val()==''){el.val(el.attr(s.attribute)).removeClass(s.activeClass).addClass(s.blurClass)}})})}})(jQuery);



// stylish select
/*
Stylish Select 0.4.1 - $ plugin to replace a select drop down box with a stylable unordered list
http://github.com/sko77sun/Stylish-Select

Requires: jQuery 1.3 or newer

Contributions from Justin Beasley: http://www.harvest.org/ & Anatoly Ressin: http://www.artazor.lv/

Dual licensed under the MIT and GPL licenses.

*/
(function($){
	//add class to html tag
	$('html').addClass('stylish-select');

	//create cross-browser indexOf
	Array.prototype.indexOf = function (obj, start) {
		for (var i = (start || 0); i < this.length; i++) {
			if (this[i] == obj) {
				return i;
			}
		}
	}

	//utility methods
	$.fn.extend({
		getSetSSValue: function(value){
			if (value){
				//set value and trigger change event
				$(this).val(value).change();
				return this;
			} else {
				return $(this).find(':selected').val();
			}
		},
		//added by Justin Beasley
		resetSS: function(){
			var oldOpts = $(this).data('ssOpts');
			$this = $(this);
			$this.next().remove();
			//unbind all events and redraw
			$this.unbind('.sSelect').sSelect(oldOpts);
		}
	});

	$.fn.sSelect = function(options) {

		return this.each(function(){

		var defaults = {
			defaultText: 'Please select',
			animationSpeed: 0, //set speed of dropdown
			ddMaxHeight: '125', //set css max-height value of dropdown
			containerClass: '' //additional classes for container div
		};

		//initial variables
		var opts = $.extend(defaults, options),
		$input = $(this),
		$containerDivText = $('<div class="selectedTxt"></div>'),
		$containerDiv = $('<div class="newListSelected ' + opts.containerClass + '"></div>'),
		$newUl = $('<ul class="newList" style="visibility:hidden;"></ul>'),
		itemIndex = -1,
		currentIndex = -1,
		keys = [],
		prevKey = false,
		prevented = false,
		$newLi;
		//$hiddenInput = $('<input name="' + $(this).attr('name') + '" type="hidden" value="' + '' + '"  id="' + $(this).attr('id') + '-hidden" />'); // added by Brian Kuzma

		//added by Justin Beasley
		$(this).data('ssOpts',options);

		//build new list
		$containerDiv.insertAfter($input);
		$containerDiv.attr("tabindex", $input.attr("tabindex") || "0");
		$containerDivText.prependTo($containerDiv);
		$newUl.appendTo($containerDiv);
		$input.hide();

		// added by Brian Kuzma
		// insert hidden input before SS list		
		//$hiddenInput.insertAfter($containerDiv);

		//added by Justin Beasley (used for lists initialized while hidden)
		$containerDivText.data('ssReRender',!$containerDivText.is(':visible'));

            //test for optgroup
            if ($input.children('optgroup').length == 0){
                $input.children().each(function(i){
                    var option = $(this).html();
                    var key = $(this).val();

                    //add first letter of each word to array
                    keys.push(option.charAt(0).toLowerCase());
                    if ($(this).attr('selected') == true){
                        opts.defaultText = option;
                        currentIndex = i;
                    }
                    $newUl.append($('<li><a href="JavaScript:void(0);">'+option+'</a></li>').data('key', key));

                });
                //cache list items object
                $newLi = $newUl.children().children();

            } else { //optgroup
                $input.children('optgroup').each(function(){

                    var optionTitle = $(this).attr('label'),
                    $optGroup = $('<li class="newListOptionTitle">'+optionTitle+'</li>');

                    $optGroup.appendTo($newUl);

                    var $optGroupList = $('<ul></ul>');

                    $optGroupList.appendTo($optGroup);

                    $(this).children().each(function(){
                        ++itemIndex;
                        var option = $(this).html();
                        var key = $(this).val();
                        //add first letter of each word to array
                        keys.push(option.charAt(0).toLowerCase());
                        if ($(this).attr('selected') == true){
                            opts.defaultText = option;
                            currentIndex = itemIndex;
                        }
                        $optGroupList.append($('<li><a href="JavaScript:void(0);">'+option+'</a></li>').data('key',key));
                    })
                });
                //cache list items object
                $newLi = $newUl.find('ul li a');
            }

            //get heights of new elements for use later
            var newUlHeight = $newUl.height(),
            containerHeight = $containerDiv.height(),
            newLiLength = $newLi.length;

            //check if a value is selected
            if (currentIndex != -1){
                navigateList(currentIndex, true);
            } else {
                //set placeholder text
                $containerDivText.text(opts.defaultText);
            }

            //decide if to place the new list above or below the drop-down
            function newUlPos(){
                var containerPosY = $containerDiv.offset().top,
                docHeight = jQuery(window).height(),
                scrollTop = jQuery(window).scrollTop();

                //if height of list is greater then max height, set list height to max height value
                if (newUlHeight > parseInt(opts.ddMaxHeight)) {
                    newUlHeight = parseInt(opts.ddMaxHeight);
                }

                containerPosY = containerPosY-scrollTop;
                if (containerPosY+newUlHeight >= docHeight){
                    $newUl.css({
                        top: newUlHeight+'px',
                        height: newUlHeight
                    });
                    $input.onTop = true;
                } else {
                    $newUl.css({
                        top: containerHeight+'px',
                        height: newUlHeight
                    });
                    $input.onTop = false;
                }
            }

            //run function on page load
            newUlPos();

            //run function on browser window resize
			$(window).bind('resize.sSelect scroll.sSelect', newUlPos);

            //positioning
            function positionFix(){
                $containerDiv.css('position','relative');
            }

            function positionHideFix(){
                $containerDiv.css('position','static');
            }

            $containerDivText.bind('click.sSelect',function(event){
                event.stopPropagation();

				//added by Justin Beasley
				if($(this).data('ssReRender')) {
					newUlHeight = $newUl.height('').height();
					containerHeight = $containerDiv.height();
					$(this).data('ssReRender',false);
					newUlPos();
				}

                //hide all menus apart from this one
				$('.newList').not($(this).next()).hide()
                    .parent()
                        .css('position', 'static')
                        .removeClass('newListSelFocus');

                //show/hide this menu
                $newUl.toggle();
                positionFix();
                //scroll list to selected item
                $newLi.eq(currentIndex).focus();
				
				// added by Brian Kuzma
				// instantiate scroll-pane inside dropdown                
                //$newUl.find('.scroll-pane').jScrollPane({showArrows:true, scrollbarWidth:12, scrollbarMargin:0});
                //$newUl.parent().jScrollPane({showArrows:true, scrollbarWidth:12, scrollbarMargin:0});
            });

            $newLi.bind('click.sSelect',function(e){
                var $clickedLi = $(e.target);

                //update counter
                currentIndex = $newLi.index($clickedLi);

                //remove all hilites, then add hilite to selected item
                prevented = true;
                navigateList(currentIndex);
                $newUl.hide();
                $containerDiv.css('position','static');//ie
				
				// update hidden form
				//$hiddenInput.val('yo');
            });

            $newLi.bind('mouseenter.sSelect',
				function(e) {
					var $hoveredLi = $(e.target);
					$hoveredLi.addClass('newListHover');
				}
			).bind('mouseleave.sSelect',
				function(e) {
					var $hoveredLi = $(e.target);
					$hoveredLi.removeClass('newListHover');
				}
			);

            function navigateList(currentIndex, init){
                $newLi.removeClass('hiLite')
                .eq(currentIndex)
                .addClass('hiLite');

                if ($newUl.is(':visible')){
                    $newLi.eq(currentIndex).focus();
                }

                var text = $newLi.eq(currentIndex).html();
                var val = $newLi.eq(currentIndex).parent().data('key');

                //page load
                if (init == true){
                    $input.val(val);
                    $containerDivText.text(text);
                    return false;
                }

		try {
		    $input.val(val)
		} catch(ex) {
		    // handle ie6 exception
		    $input[0].selectedIndex = currentIndex;
		}

                $input.change();
                $containerDivText.text(text);
            }

            $input.bind('change.sSelect',function(event){
                $targetInput = $(event.target);
                //stop change function from firing
                if (prevented == true){
                    prevented = false;
                    return false;
                }
                $currentOpt = $targetInput.find(':selected');

                //currentIndex = $targetInput.find('option').index($currentOpt);
                currentIndex = $targetInput.find('option').index($currentOpt);

                navigateList(currentIndex, true);
			});

            //handle up and down keys
            function keyPress(element) {
                //when keys are pressed
                $(element).unbind('keydown.sSelect').bind('keydown.sSelect',function(e){
                    var keycode = e.which;

                    //prevent change function from firing
                    prevented = true;

                    switch(keycode) {
                        case 40: //down
                        case 39: //right
                            incrementList();
                            return false;
                            break;
                        case 38: //up
                        case 37: //left
                            decrementList();
                            return false;
                            break;
                        case 33: //page up
                        case 36: //home
                            gotoFirst();
                            return false;
                            break;
                        case 34: //page down
                        case 35: //end
                            gotoLast();
                            return false;
                            break;
                        case 13:
                        case 27:
                            $newUl.hide();
                            positionHideFix();
                            return false;
                            break;
                    }

                    //check for keyboard shortcuts
                    keyPressed = String.fromCharCode(keycode).toLowerCase();

                    var currentKeyIndex = keys.indexOf(keyPressed);

                    if (typeof currentKeyIndex != 'undefined') { //if key code found in array
                        ++currentIndex;
                        currentIndex = keys.indexOf(keyPressed, currentIndex); //search array from current index
                        if (currentIndex == -1 || currentIndex == null || prevKey != keyPressed) currentIndex = keys.indexOf(keyPressed); //if no entry was found or new key pressed search from start of array


                        navigateList(currentIndex);
                        //store last key pressed
                        prevKey = keyPressed;
                        return false;
                    }
                });
            }

            function incrementList(){
                if (currentIndex < (newLiLength-1)) {
                    ++currentIndex;
                    navigateList(currentIndex);
                }
            }

            function decrementList(){
                if (currentIndex > 0) {
                    --currentIndex;
                    navigateList(currentIndex);
                }
            }

            function gotoFirst(){
                currentIndex = 0;
                navigateList(currentIndex);
            }

            function gotoLast(){
                currentIndex = newLiLength-1;
                navigateList(currentIndex);
            }

            $containerDiv.bind('click.sSelect',function(e){
                e.stopPropagation();
                keyPress(this);
            });

            $containerDiv.bind('focus.sSelect',function(){
                $(this).addClass('newListSelFocus');
                keyPress(this);
            });

            $containerDiv.bind('blur.sSelect',function(){
                $(this).removeClass('newListSelFocus');
            });

            //hide list on blur
            $(document).bind('click.sSelect',function(){
                $containerDiv.removeClass('newListSelFocus');
                $newUl.hide();
                positionHideFix();
            });

            //add classes on hover
            $containerDivText.bind('mouseenter.sSelect',
				function(e) {
					var $hoveredTxt = $(e.target);
					$hoveredTxt.parent().addClass('newListSelHover');
				}
			).bind('mouseleave.sSelect',
				function(e) {
					var $hoveredTxt = $(e.target);
					$hoveredTxt.parent().removeClass('newListSelHover');
				}
            );

            //reset left property and hide
            $newUl.css({
                left: '0',
                display: 'none',
                visibility: 'visible'
            });

        });

    };

})(jQuery);




// ------------- FORM PROCESSING BEGINS -------------------

// validation
$(document).ready(function() {

////////////////////// from script.js

		//  form register
		initial_load_login = '';
		initial_load_register = '';
		
		$('.button-close').live("click",function(){
			var which_form_to_close = $(this).parents('.forms-panel').attr('id').replace('forms-','');
			$('.forms-panel').hide('fast');
			$('#' + which_form_to_close).slideUp();
		});

		$('#nav-t-6-a').click(function(){
		
			//if(initial_load_login != 'y'){
			//	$('#form-login').load('/forms/sign-in.html' );			
			//}
			
			//initial_load_login = 'y';
			
			if($('#form-login').is(":hidden")){
				if($('#form-register').is(":hidden")){
					resetForms();
					$('#form-login').slideDown(function(){
						$('#forms-form-login').fadeIn('fast');
					});
				}
				else{
					$('#forms-form-register').hide('fast');
					$('#form-register').slideUp(function(){
						resetForms();
						$('#form-login').slideDown(function(){
							$('#forms-form-login').fadeIn('fast');
						});
					});
				}	
			}
			else {
				$('#forms-form-login').hide('fast');
				$('#form-login').slideUp();
			}
		});

		// ----------- register button clicked -----------
		$('#nav-t-7-a').click(function(){
		
			//clear edit profile cache
			//if(initial_load_register != 'y'){
			//	$('#form-register').load('/forms/register.php' );			
			//}
			
			//initial_load_register = 'y';

			//do not show the age check form if the age check has already been completed and if it passed or failed.
			if($('#age-check-wrapper').is(":hidden") && $('#register-wrapper').is(":hidden")){
				if ( (!$.cookie('age_check') || ($.cookie('age_check') != "failure")) ){ 
					$('#age-check-wrapper').fadeIn();
				}  else { 
				//age check failed so alert user that they can not participate
				//if ($.cookie('age_check') == "failure") {
					alert("We're sorry you're ineligible to participate");
					return false;
				}	
			}

			
			if($('#form-register').is(":hidden")){
				if($('#form-login').is(":hidden")){
					resetForms();
					$('#form-register').slideDown(function(){
						$('#forms-form-register').fadeIn('fast');
					});
				}
				else{
					$('#forms-form-login').hide('fast');
					$('#form-login').slideUp(function(){
						resetForms();
						$('#form-register').slideDown(function(){
							$('#forms-form-register').fadeIn('fast');
						});
					})
				}	
				
					if ($.cookie('age_check') && ($.cookie('age_check') != "failure")){

							$('.form-register').addClass('form-register-final');
							$('#age-check-wrapper').hide();
							$('.form-register-final').slideDown('slow',function(){
								$('#forms-form-register').fadeIn();
							})

							$('#form-register').slideDown(function(){
								$('#register-wrapper').fadeIn();
							}); 
				
					}
			}
			else {
				$('#forms-form-register').hide('fast');
				$('#form-register').slideUp();
			}
			


		});

		// ----------- edit profile button clicked -----------
		$('#nav-t-9-a').click(function(){
			$('#ymymj_2212').val('1');
			if($('#form-register').is(":hidden")){
				//if we haven't gotten the profile data yet, then get it from the server
					$.ajax({
						  type: 'POST',
						  url: "/profile/edit?submit=1",
						  data: $("#sign-in-form").serialize(),
						  dataType: "json",
						  success:	function(data){
										 if (! data) document.location = "/index";

										//alert(data.status);
										if ( (data) && (data.status == "success") ) {
											//fill in form fields
											$('#first_name').val(data.userInfo.first_name);	
											$('#username').val(data.userInfo.username);
											$('#password').val(data.userInfo.password);
											$('#password_confirm').val(data.userInfo.password);
											$('#last_name').val(data.userInfo.last_name);
											$('#email').val(data.userInfo.email_address);
											$('#address_1').val(data.userInfo.address_1);
											$('#address_2').val(data.userInfo.address_2);
											$('#city').val(data.userInfo.city);
											$('#state-select').getSetSSValue(data.userInfo.state_province);
											$('#zip').val(data.userInfo.zip);
											$('#phone').val(data.userInfo.phone);
											$('#sex-select').getSetSSValue(data.userInfo.gender);
											$('#birthday-month-select').val(data.userInfo.dob_mm);
											$('#birthday-day-select').val(data.userInfo.dob_dd);
											$('#birthday-year-select').val(data.userInfo.dob_yyyy);
											
											if(data.userInfo.optin == 'I'){
												$('a#opt-in-button').click();
											}
											//set a flag indicating we have retrieved the edit profile data
										}
									}, //end of success
									error : function() {
										alert("A system error occured processing your request, please try again");
										return false;
									} // end of error							
					}); // end of ajax post

				
				
					resetForms();
				
				// move form down more
				$('.form-register').addClass('form-register-final');
				$('#age-check-wrapper').hide();
				//get the edit profile form

				// fade in register form and fill in data
				$('.form-register-final').slideDown('slow',function(){
					$('#forms-form-register').fadeIn();
				});
				
				$('#form-register').slideDown(function(){
								$('#register-wrapper').fadeIn();
				}); 

			}
			else 
			{
				$('#forms-form-register').fadeOut('fast');
				$('#form-register').slideUp();
			}
			
			//need to do a return so validator doesnt break
			return true;
		});
		
		$('#cancel').click(function(){
			$('#button-close-register').trigger('click');
			return false;
		})
		
		$('#no-account a').click(function(){

			if ( ($.cookie('age_check') && ($.cookie('age_check') == "failure")) ){
				alert("We're sorry you're ineligible to participate");
				return false;
			}else {
				$('#forms-form-login').hide('fast');
				$('#form-login').slideUp(function(){
					resetForms();
					$('#form-register').slideDown(function(){
						$('#forms-form-register').show('fast');
					});
				});
			}

		});
		
		$('.have-account a').click(function(){
			$('#forms-form-register').hide('fast');
			$('#form-register').slideUp(function(){
				resetForms();
				$('#form-login').slideDown(function(){
					$('#forms-form-login').show('fast');
				});
			});
		})
		
		function resetForms()
		{
			// clear password in login form
			$('#password-password').val('');
			$('#password-password').blur();
			
			// remove password error class from password clear field
			$('#password-clear').removeClass('passwordError');
			
			// remove error class from select dropdowns
			$('.newListSelected').removeClass('error');				
			
			// reset form fields and remove errors
			registerValidator.resetForm();
			signInValidator.resetForm();
			forgotPasswordValidator.resetForm();
			
			$('.ostrich').show();
			$('.ostrich-error').hide();
			$('#personal-info .required-fields').css('color', '#FFFFFF');
			
			// reset login form in case it was in forgot password state //////////////
			$('#link-forgot-password').show();
			
			// swap forgot password form for login form
			$('#forgot-password-form').hide();
			$('#sign-in-form').show();
			
			// clear value in email field
			$('#email-forgot-password').val('Your email');
			
			// show diff message in ostrich bubble
			$('#sign-in-wrapper .ostrich-bubble').html('Registering gets you<br />all kinds of cool news<br />and extras from STRIDE&reg;!');
			$("#sign-in-wrapper .ostrich-bubble").css('color', '#000000');
			$('#sign-in-wrapper .ostrich-image').css('backgroundPosition', 'top left');
		}

//////////////////////

	function getAge(Y,M,D)
	{
		var now=new Date(),m=now.getMonth()+1,d=now.getDate();
		return now.getFullYear()-Y+(M>m?-1:M==m&&D>d?-1:0);
	}
	
	// forgot password button
	$('#link-forgot-password').click(function() {
		// hide fields
		$(this).hide();
		
		$('#sign-in-form').hide();
		$('#forgot-password-form').show();
		
		// show diff message in ostrich bubble and reset color
		$('#sign-in-wrapper .ostrich-bubble').html('Please enter the <br/>email address associated<br/> with your account!');
		$("#sign-in-wrapper .ostrich-bubble").css('color', '#000000');
		$('#sign-in-wrapper .ostrich-image').css('backgroundPosition', 'top left');
	});
	
	// ------ log out button clicked
	$('#nav-t-10-a').click(function() {
		$.ajax({
			  type: 'POST',
			  url: "/profile/logout",
			  data: null,
			  dataType: "json",
			  success:	function(data){
						//delete the cached edit profile data and action
						$.cookie('logged_in', null);
						$.cookie('u', null);			
						hideLogOutButton();
						
						$('#form-register').slideUp(400, function() {	
							hideEditProfileFields();
							resetForms();
						});
						location.reload();
						}, //end of success
			error : function() {
						alert("A system error occured processing your request, please try again");
						return false;
			} // end of post error							
		}); // end of ajax post
	});
	
	function showLogOutButton () 
	{
		$('#nav-6').hide();
		$('#nav-7').hide();
		$('#nav-8').show();
		$('#nav-9').show();
		$('#nav-10').show();
	}
	
	function hideLogOutButton () 
	{
		$('#nav-6').show();
		$('#nav-7').show();
		$('#nav-8').hide();
		$('#nav-9').hide();
		$('#nav-10').hide();
		
		$('#register-wrapper').hide();
		$('#form-register').removeClass('form-register-final');
		$('#age-check-wrapper').hide();
	}
	
	function showEditProfileFields()
	{
		
		$('#user-pass legend').css('background-position', '0 -20px');
		$('#personal-info legend').css('background-position', '0 -20px');
		//$('#register-wrapper #username').attr('disabled', true);
		$('#register-wrapper #username').attr('readonly', 'readonly');
		$('#register-wrapper #username').addClass('inactive');
		$('#register-wrapper #email').attr('readonly', 'readonly');
		$('#register-wrapper #email').addClass('inactive');
		$('#register-wrapper .have-account').hide();
	}
	
	function hideEditProfileFields()
	{
		$('#user-pass legend').css('background-position', '0 0');
		$('#personal-info legend').css('background-position', '0 0');
		//$('#register-wrapper #username').attr('disabled', false);
		$('#register-wrapper #username').removeClass('inactive');
		$('#register-wrapper #email').removeClass('inactive');
		$('#register-wrapper .have-account').show();
	}

	// min length for username/password/zip
	var minLengthUsername = 2;
	var minLengthPassword = 5;
	var minLengthZipCode = 5;
	
	// check that username on sign-in page is not "Your username"
	jQuery.validator.addMethod("username-sign-in", function( value, element ) {
		var result = this.optional(element) || value != "Your email";
		if (!result) {
			var validator = this;
			setTimeout(function() {
				validator.blockFocusCleanup = true;
				validator.blockFocusCleanup = false;
			}, 1);
		}
		return result;
	}, "");
	
	// check that fake password field on sign-in page is not "Your password", so that this field will get the .error class
	/*jQuery.validator.addMethod("password-sign-in", function( value, element ) {
		var result = this.optional(element) || value != "Your password";
		if (!result) {
			//element.value = "";
			var validator = this;
			setTimeout(function() {
				validator.blockFocusCleanup = true;
				//element.focus();
				validator.blockFocusCleanup = false;
			}, 1);
		}
		return result;
	}, "");*/
	
	// check that email on forgot-password-form is not "Your email"
	jQuery.validator.addMethod("email-forgot-password", function( value, element ) {
		var result = this.optional(element) || value != "Your email";
		if (!result) {
			//element.value = "";
			var validator = this;
			setTimeout(function() {
				validator.blockFocusCleanup = true;
				//element.focus();
				validator.blockFocusCleanup = false;
			}, 1);
		}
		return result;
	}, "");
	
jQuery.validator.addMethod("phoneUS", function(phone_number, element) {
    phone_number = phone_number.replace(/\s+/g, ""); 
	return this.optional(element) || phone_number.length > 9 &&
		phone_number.match(/^(1-?)?(\([2-9]\d{2}\)|[2-9]\d{2})-?[2-9]\d{2}-?\d{4}$/);
}, "Please specify a valid phone number");

	
	var signInValidator = $("#sign-in-form").validate({
		invalidHandler: function(e, validator) {
			var errors = validator.numberOfInvalids();
			if (errors) 
			{
				var message = "ostrich text";
				$("#sign-in-wrapper .ostrich-bubble").html("Hold your ostriches!<br />You have to fill out all<br />the fields right first!");
				$("#sign-in-wrapper .ostrich-bubble").css('color', '#ed1c24');
				$('#sign-in-wrapper  .ostrich-image').css('backgroundPosition', 'bottom left');
				
				// if password field is empty, add error class to fake password field
				if ($('#password-password').val() == '')
				{
					$('#password-clear').addClass('passwordError');
				}
			} 
			else 
			{
				
			}
		},
		onkeyup: false,
		submitHandler: function() {			
			$("#sign-in-wrapper .ostrich-bubble").html("Registering gets you<br />all kinds of cool news<br />and extras from Stride! ");
			$("#sign-in-wrapper .ostrich-bubble").css('color', '#000000');
			$('#sign-in-wrapper .ostrich-image').css('backgroundPosition', 'top left');
			
			// ----------- login button clicked -----------
			// submit form with ajax
			$.ajax({
				  type: 'POST',
				  url: "/profile/login",
				  data: $("#sign-in-form").serialize(),
				  dataType: "json",
				  success:	function(data){
							if (! data) { 
								alert("A system error occured processing your request, please try again");
								return false;
							}
							//successful login check
							if ( (data) && (data.status == "success") ) {
								//login ok
								$('#nav-8-first-name').text(data.data.firstname_short);
								$('#forms-form-register,#forms-form-login').hide('fast');
								$('#form-register,#form-login').slideUp();
								//alert(tractionObject.data.logged_in);
								showLogOutButton();
								
								// hide age check form and show register form
								$('#age-check-wrapper').hide();
								$('#register-wrapper').show();
								
								// modify register form to be edit profile form
								showEditProfileFields();					
								$('#form-login').slideUp(400, function(){});
							} else {
								//login fail
								var errorMessage = "Sorry your Email Address and/or Password are incorrect.  Please try again.";
								if (data.errors.error_messages != null) errorMessage = data.errors.error_messages;
								alert(errorMessage);
								return false;
							} 
						}, //end of success
						error : function() {
							alert("A system error occured processing your request, please try again");
							return false;
						} // end of post error							
		}); // end of ajax post
		},
		messages: {
			email_address: {
				required: "",
				minlength: ""
			},
			password: {
				required: "",
				minlength: ""
			}
		},
		rules: {
			email_address: {
				minlength: minLengthUsername
			},
			zip: {
				minlength: minLengthZipCode
			},
			password: {
				required: true,
				minlength: minLengthPassword
				}
			}, 
		debug:false,
		focusInvalid:false
	});

	var forgotPasswordValidator = $('#forgot-password-form').validate({
		invalidHandler: function(e, validator) {
			var errors = validator.numberOfInvalids();
			if (errors) 
			{
				var message = "ostrich text";
				$("#sign-in-wrapper .ostrich-bubble").html("Hold your ostriches!<br />You have to fill out all<br />the fields right first!");
				$("#sign-in-wrapper .ostrich-bubble").css('color', '#ed1c24');
				$('#sign-in-wrapper .ostrich-image').css('backgroundPosition', 'bottom left');
			} 
			else 
			{
			}
		},
		onkeyup: false,
		submitHandler: function(form) {			
			$('#sign-in-wrapper .ostrich-bubble').html('Please enter the <br/>email address associated<br/> with your account!');
			$("#sign-in-wrapper .ostrich-bubble").css('color', '#000000');
			$('#sign-in-wrapper .ostrich-image').css('backgroundPosition', 'top left');
			
			// ----------- forgot password button clicked -----------
			$.ajax({
				  type: 'POST',
				  url: "/profile/forgotpassword",
				  data: $("#forgot-password-form").serialize(),
				  dataType: "json",
				  success:  function(data){
								if (! data)  {
									alert("A system error occured processing your request, please try again");
									//return false;
								}
								//successful login check
								if (data.status == "success") {
									alert('Your password has been emailed to you.');
									resetForms();
									//return true;
								} else if (data.status == "failure") {
									//login fail
									var errorMessage = "Sorry we couldn't find your email address.";
									if (data.errors.error_messages != null) errorMessage = data.errors.error_messages;
									alert(errorMessage);
									//return false;
								} else {
									alert("A system error occured processing your request, please try again");
									//return false;
								}
							}, //end of post success
				error : function() {
								alert("A system error occured processing your request, please try again");
							} // end of post error							
			}); // end of ajax post
		},
		debug:false,
		focusInvalid:false,
		messages: {
			email_address_forgot_password: {
				required: "",
				email: ""
			}
		},
		rules: {
            email_address_forgot_password: {
                email:true
            }
        }
	});
	
	var ageCheckValidator = $("#age-check-form").validate({
		invalidHandler: function(e, validator) {
		

			// change message in ostrich bubble
			$("#age-check-wrapper .ostrich-bubble").html("Hold your ostriches!<br />You have to fill out all<br />the fields right first!");
			$("#age-check-wrapper .ostrich-bubble").css('color', '#ed1c24');
			$('#age-check-wrapper  .ostrich-image').css('backgroundPosition', 'bottom left');
			
			// assign error class to newListSelected where necessary
			$('#age-check-form select.required').each(function() {
				if ($(this).getSetSSValue() == '')
				{
					$(this).siblings('.newListSelected').addClass('error');				
				}
				else
				{
					$(this).siblings('.newListSelected').removeClass('error');				
				}
			});
		},
		onkeyup: false,
		submitHandler: function() {			
			
				
			// get age
			var year = $('#age-check-birthday-year-select').getSetSSValue();
			var monthValue = $('#age-check-birthday-month-select').getSetSSValue();
			var monthNumber = $('#age-check-birthday-month .hiLite').parent().index();
			var day = $('#age-check-birthday-day-select').getSetSSValue();		
			var age = getAge(year, monthNumber, day);

			// ----------- age check button clicked -----------
			$.ajax({
				  type: 'POST',
				  url: "/profile/agecheck",
				  data: $("#age-check-form").serialize(),
				  dataType: "json",
				  success:  function(data){
							if (!data) location.reload();
							if (data.status == "success")  {
								// fade out age check form
								$('#age-check-wrapper').fadeOut(400, function() {
									// set DOB fields in register form
									$('#birthday-year-select').getSetSSValue(year);
									$('#birthday-month-select').getSetSSValue(monthValue);
									$('#birthday-day-select').getSetSSValue(day);
									
									// move form down more
									$('.form-register').addClass('form-register-final');
									
									// fade in register form
									$('.form-register-final').slideDown('slow',function(){
										$('#register-wrapper').fadeIn();
									});
									
								});
							} else if (data.status == "failure") {
								alert("We're sorry you're ineligible to participate");
								$('#button-close-age-check').click();
							}
						}, //end of post success
				error : function() {
								alert("A system error occured processing your request, please try again");
							} // end of post error							
			}); // end of ajax post

			// clear error class from .newListSelected
			$('.newListSelected').removeClass('error');
			
			// return ostrich to normal
			$("#age-check-wrapper .ostrich-bubble").html("Registering gets you<br />all kinds of cool news<br />and extras from Stride! ");
			$("#age-check-wrapper .ostrich-bubble").css('color', '#000000');
			$('#age-check-wrapper .ostrich-image').css('backgroundPosition', 'top left');
		},
		messages: {
			"age-check-dob-mm": {
				required: ""
			},
			"age-check-dob-dd": {
				required: ""
			},
			"age-check-dob-yyyy": {
				required: ""
			}
		},
		debug:false
	});
	
	
	var registerValidator = $("#register-form").validate({
		invalidHandler: function(e, validator) {
			var errors = validator.numberOfInvalids();
			if (errors) 
			{
				// switch out ostrich
				$('.ostrich').hide();
				$('.ostrich-error').show();
				
				setTimeout(function() {$(".scroll-pane").jScrollPane({showArrows:true, scrollbarWidth:12, scrollbarMargin:0})}, 1);
				
				// change "required fields" to be red
				$('#personal-info .required-fields').css('color', '#FF0000');
				
				// assign error class to newListSelected where necessary
				$('#register-form select.required').each(function() {
					if ($(this).getSetSSValue() == '')
					{
						$(this).siblings('.newListSelected').addClass('error');				
					}
					else
					{
						$(this).siblings('.newListSelected').removeClass('error');				
					}
				});
			} 
			else 
			{
				// not sure if this block is ever reached
			}
		},
	   errorLabelContainer: "#form-error-list",
	   wrapper: "li",
		onkeyup: false,
		submitHandler: function(form) {			
			$('.ostrich').show();
			$('.ostrich-error').hide();
			$('#personal-info .required-fields').css('color', '#FFFFFF');
			
			// clear error class from .newListSelected
			$('.newListSelected').removeClass('error');

			// ----------- register button clicked -----------
			//enable edit profile or register mode
			var formUrl = "/profile/register";
			if ($('#ymymj_2212').val() == 0) {
				formUrl = "/profile/register";
			} else if ($('#ymymj_2212').val() == 1) {
				formUrl = "/profile/register/mode/edit";
			}

		
			
			$.ajax({
				  type: 'POST',
				  url: formUrl,
				  data: $("#register-form").serialize(),
				  dataType: "json",
				  success: function(data){
								if (!data) { 
									alert("An error occured processing your registration");
									return false;
								}
								
								
								if ( (data) && (data.status) && (data.status == "success") )  {
									//$('#nav-8-first-name').text(data.userName);						
									//show the html message on new reg and slide up form on edit
									/*
									 
									 if ($.cookie('profile_edit')) {
										//edit
										alert("Your profile has been updated");
										$('#button-close-register').trigger('click');
									} else {
										//new reg
									*/	
										$("#register-wrapper").html(data.html);
									//}
									// clear the edit profile cookies so that we grab the latest information on edit profile
									
									showLogOutButton();
									$('#form-register').removeClass('form-register-final');
									$('#register-wrapper').css("height","127px");
									return true;
								} else if (data.status == "failure") {
									if (data.message)  { 
										alert(data.message);
										return false;
									} else {
										alert("An error occured processing your registration");
										return false;
									}
								} else {
									//system error display the html
									if ( (data) && (data.html) ) {  
										$("#register-wrapper").html(data.html);
										return false;
									} else {
										$("#register-wrapper").html("An error occured processing your registration");
										return false;
									}
								} //end of main if
							}, // end of post success
							
					error : function() {
							alert("An error occured processing your registration");
							return false;
							} // end of post error
				  
				});

		},
		rules: {
			username: {
				minlength: minLengthUsername
			},
			zip: {
				minlength: minLengthZipCode
			},
			password: {
				required: true,
				minlength: minLengthPassword
			},
			password_confirm: {
				equalTo: "#password"
			},
			email: {
				required: true,
				email:true
			}
		}, 
		messages: {
			username: {
				required: "Username required.",
				minlength: "Username must be at least " + minLengthUsername + " characters."
			},
			password: {
				required: "Password required.",
				minlength: "Password must be at least " + minLengthPassword + " characters."
			},
			password_confirm: {
				required: "Repeat password required.",
				equalTo: "Please enter the same password in both fields."	
			},
			first_name: {
	        	required: "First name required."
	        },
	        last_name: {
	        	required: "Last name required."
	        },
			email_address: {
				required: "An email address is required.",
				email: "Must enter valid email."
			},
			address_1: {
	        	required: "Address required."
	        },
	        city: {
	        	required: "City required."
	        },
	        state_province: {
	        	required: "State required."
	        },
	        zip: {
	        	required: "Zip required.",
				minlength: "Zip must be at least " + minLengthZipCode + " characters."
	        },
	        phone: {
				required: "Phone required.",
				phoneUS: "Please enter valid phone number."
	        },
	        dob_mm: {
	        	required: "Birthday month required."
	        },
	        dob_dd: {
	        	required: "Birthday day required."
	        },
	        dob_yyyy: {
	        	required: "Birthday year required."
	        }
		},
		debug:false
	});
	
});



