/**
 * jQuery History Plugin (balupton edition) - Simple History Handler/Remote for Hash, State, Bookmarking, and Forward Back Buttons
 * Copyright (C) 2008-2009 Benjamin Arthur Lupton
 * http://www.balupton.com/projects/jquery_history/
 *
 * This file is part of jQuery History Plugin (balupton edition).
 * 
 * jQuery History Plugin (balupton edition) is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * jQuery History Plugin (balupton edition) is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 * 
 * You should have received a copy of the GNU Affero General Public License
 * along with jQuery History Plugin (balupton edition).  If not, see <http://www.gnu.org/licenses/>.
 *
 * @name jqsmarty: jquery.history.js
 * @package jQuery History Plugin (balupton edition)
 * @version 1.1.0-final
 * @date July 14, 2009
 * @category jquery plugin
 * @author Benjamin "balupton" Lupton {@link http://www.balupton.com}
 * @copyright (c) 2008-2009 Benjamin Arthur Lupton {@link http://www.balupton.com}
 * @license GNU Affero General Public License - {@link http://www.gnu.org/licenses/agpl.html}
 * @example Visit {@link http://jquery.com/plugins/project/jquery_history_bal} for more information.
 * 
 * 
 * I would like to take this space to thank the following projects, blogs, articles and people:
 * - jQuery {@link http://jquery.com/}
 * - jQuery UI History - Klaus Hartl {@link http://www.stilbuero.de/jquery/ui_history/}
 * - Really Simple History - Brian Dillard and Brad Neuberg {@link http://code.google.com/p/reallysimplehistory/}
 * - jQuery History Plugin - Taku Sano (Mikage Sawatari) {@link http://www.mikage.to/jquery/jquery_history.html}
 * - jQuery History Remote Plugin - Klaus Hartl {@link http://stilbuero.de/jquery/history/}
 * - Content With Style: Fixing the back button and enabling bookmarking for ajax apps - Mike Stenhouse {@link http://www.contentwithstyle.co.uk/Articles/38/fixing-the-back-button-and-enabling-bookmarking-for-ajax-apps}
 * - Bookmarks and Back Buttons {@link http://ajax.howtosetup.info/options-and-efficiencies/bookmarks-and-back-buttons/}
 * - Ajax: How to handle bookmarks and back buttons - Brad Neuberg {@link http://dev.aol.com/ajax-handling-bookmarks-and-back-button}
 *
 **
 ***
 * CHANGELOG
 **
 * v1.1.0-final, July 14, 2009
 * - Rewrote IE<8 hash code
 * - Cut down format to accept all hash types
 * 
 * v1.0.1-final, July 11, 2009
 * - Restructured a little bit
 * - Documented
 * - Cleaned go/request
 *
 * v1.0.0-final, June 19, 2009
 * - Been stable for over a year now, pushing live.
 * 
 * v0.1.0-dev, July 24, 2008
 * - Initial Release
 * 
 */

// Start of our jQuery Plugin
(function($)
{	// Create our Plugin function, with $ as the argument (we pass the jQuery object over later)
	// More info: http://docs.jquery.com/Plugins/Authoring#Custom_Alias
	
	// Debug
	if (typeof console === 'undefined') {
		console = typeof window.console !== 'undefined' ? window.console : {};
	}
	console.log			= console.log 			|| function(){};
	console.debug		= console.debug 		|| console.log;
	console.warn		= console.warn			|| console.log;
	console.error		= console.error			|| function(){var args = [];for (var i = 0; i < arguments.length; i++) { args.push(arguments[i]); } alert(args.join("\n")); };
	console.trace		= console.trace			|| console.log;
	console.group		= console.group			|| console.log;
	console.groupEnd	= console.groupEnd		|| console.log;
	console.profile		= console.profile		|| console.log;
	console.profileEnd	= console.profileEnd	|| console.log;
	
	// Declare our class
	$.History = {
		// Our Plugin definition
		
		// -----------------
		// Options
		
		options: {
			debug: false
		},
		
		// -----------------
		// Variables
		
		state:		'',
		$window:	null,
		$iframe:	null,
		handlers:	{
			generic:	[],
			specific:	{}
		},
		
		// --------------------------------------------------
		// Functions
		
		/**
		 * Format a hash into a proper state
		 * @param {String} hash
		 */
		format: function ( hash ) {
			// Format the hash
			hash = hash
				.replace(/^.*#/g, '') /* strip anything before the anchor in case we were passed a url */
				;
			
			// Return the hash
			return hash;
		},
		
		/**
		 * Get the current state of the application
		 */
        getState: function ( ) {
			var History = $.History;
			
			// Get the current state
			return History.state;
        },
		/**
		 * Set the current state of the application
		 * @param {String} hash
		 */
		setState: function ( state ) {
			var History = $.History;
			// Format the state
			state = History.format(state)
			
			// Apply the state
			History.state = state;
			
			// Return the state
			return History.state;
		},
		
		/**
		 * Get the current hash of the browser
		 */
		getHash: function ( ) {
			var History = $.History;
			
			// Get the hash
			var hash = History.format(window.location.hash || location.hash);
			
			// Return the hash
			return hash;
		},
		
		/**
		 * Set the current hash of the browser and iframe if present
		 * @param {String} hash
		 */
		setHash: function ( hash ) {
			var History = $.History;
			
			// Prepare hash
			hash = History.format(hash);
			
			// Write hash
			if ( typeof window.location.hash !== 'undefined' ) {
				if ( window.location.hash !== hash ) {
					window.location.hash = hash;
				}
			} else if ( location.hash !== hash ) {
				location.hash = hash;
			}
			
			// Done
			return hash;
		},
		
		/**
		 * Go to the specific state - does not force a history entry like setHash
		 * @param {String} to
		 */
		go: function ( to ) {
			var History = $.History;
			
			// Format
			to = History.format(to);
			
			// Get current
			var hash = History.getHash();
			var state = History.getState();
			
			// Has the hash changed
			if ( to !== hash ) {
				// Yes, update the hash
				// And wait for the next automatic fire
				History.setHash(to);
			} else {
				// Hash the state changed?
				if ( to !== state ) {
					// Yes, Update the state
					History.setState(to);
				}
				
				// Trigger our change
				History.trigger();
			}
			
			// Done
			return true;
		},
		
		/**
		 * Handle when the hash has changed
		 * @param {Event} e
		 */
		hashchange: function ( e ) {
			var History = $.History;
			
			// Get Hash
			var hash = History.getHash();
			
			// Handle the new hash
			History.go(hash);
			
			// All done
			return true;
		},
		
		/**
		 * Bind a handler to a hash
		 * @param {Object} state
		 * @param {Object} handler
		 */
		bind: function ( state, handler ) {
			var History = $.History;
			
			// 
			if ( handler ) {
				// We have a state specific handler
				// Prepare
				if ( typeof History.handlers.specific[state] === 'undefined' )
				{	// Make it an array
					History.handlers.specific[state] = [];
				}
				// Push new handler
				History.handlers.specific[state].push(handler);
			}
			else {
				// We have a generic handler
				handler = state;
				History.handlers.generic.push(handler);
			}
			
			// Done
			return true;
		},
		
		/**
		 * Trigger a handler for a state
		 * @param {String} state
		 */
		trigger: function ( state ) {
			var History = $.History;
			
			// Prepare
			if ( typeof state === 'undefined' ) {
				// Use current
				state = History.getState();
			}
			var i, n, handler, list;
			
			// Fire specific
			if ( typeof History.handlers.specific[state] !== 'undefined' ) {
				// We have specific handlers
				list = History.handlers.specific[state];
				for ( i = 0, n = list.length; i < n; ++i ) {
					// Fire the specific handler
					handler = list[i];
					handler(state);
				}
			}
			
			// Fire generics
			list = History.handlers.generic;
			for ( i = 0, n = list.length; i < n; ++i ) {
				// Fire the specific handler
				handler = list[i];
				handler(state);
			}
			
			// Done
			return true;
		},
		
		// --------------------------------------------------
		// Constructors
		
		/**
		 * Construct our application
		 */
		construct: function ( ) {
			var History = $.History;
			
			// Modify the document
			$(document).ready(function() {
				// Prepare the document
				History.domReady();
			});
			
			// Done
			return true;
		},
		
		/**
		 * Configure our application
		 * @param {Object} options
		 */
		configure: function ( options ) {
			var History = $.History;
			
			// Set options
			History.options = $.extend(History.options, options);
			
			// Done
			return true;
		},
		
		domReadied: false,
		domReady: function ( ) {
			var History = $.History;
			
			// Runonce
			if ( History.domRedied ) {
				return;
			}
			History.domRedied = true;
			
			// Define window
			History.$window = $(window);
			
			// Apply the hashchange function
			History.$window.bind('hashchange', this.hashchange);
			
			// Force hashchange support for all browsers
			setTimeout(History.hashchangeLoader, 200);
			
			// All done
			return true;
		},
		
		/**
		 * Enable hashchange for all browsers
		 */
		hashchangeLoader: function () {
			var History = $.History;
			
			// More is needed for non IE8 browsers
			if ( !($.browser.msie && parseInt($.browser.version) >= 8) ) {	
				// We are not IE8
			
				// State our checker function, it is used to constantly check the location to detect a change
				var checker;
				
				// Handle depending on the browser
				if ( $.browser.msie ) {
					// We are still IE
					// IE6, IE7, etc
				
					// Append and $iframe to the document, as $iframes are required for back and forward
					// Create a hidden $iframe for hash change tracking
					History.$iframe = $('<iframe id="jquery-history-iframe" style="display: none;"></$iframe>').prependTo(document.body)[0];
					
					// Create initial history entry
					History.$iframe.contentWindow.document.open();
					History.$iframe.contentWindow.document.close();
					
					// Define the checker function (for bookmarks)
					var iframeHit = false;
					checker = function ( ) {
						
						// Fetch
						var hash = History.getHash();
						var state = History.getState();
						var iframeHash = History.format(History.$iframe.contentWindow.document.location.hash);
						
						// Check if the browser hash is different
						if ( state !== hash ) {
							// Browser hash is different
							
							// Check if we need to update the iframe
							if ( !iframeHit ) {
								// Write a iframe/history entry in the browsers back and forward
								// alert('update iframe entry');
								History.$iframe.contentWindow.document.open();
								History.$iframe.contentWindow.document.close();
								// alert('update iframe entry.');
								
								// Update the iframe hash
								// alert('update iframe hash');
								History.$iframe.contentWindow.document.location.hash = hash;
								// alert('update iframe hash.');
							}
							
							// Reset
							iframeHit = false;
							
							// Fire
							// alert('hashchange');
							History.$window.trigger('hashchange');
							// alert('hashchange.');
						}
						else {
							// Browser hash is not different
							
							// Check if the iframe hash is different from the iframe state
							if ( state !== iframeHash ) {
								// Specify we were hit from the iframe
								iframeHit = true;
								
								// Update the browser hash
								// alert('set hash from iframe');
								History.setHash(iframeHash);
								// alert('set hash from iframe.');
							}
						}
						
					};
				}
				else {
					// We are not IE
					// Firefox, Opera, Etc
				
					// Define the checker function (for bookmarks, back, forward)
					checker = function ( ) {
						var hash = History.getHash();
						var state = History.getState();
						// Check
						if ( state !== hash ) {
							// State change
							History.$window.trigger('hashchange');
						}
					};
				}
				
				// Apply the checker function
				setInterval(checker, 200);
			}
			else {
				// We are IE8
				
				// Fire the initial
				var hash = History.getHash();
				if ( hash ) {
					History.$window.trigger('hashchange');
				}
			}
			
			// Done
			return true;
		}
	
	}; // We have finished extending/defining our Plugin
	
	// --------------------------------------------------
	// Finish up
	
	// Instantiate
	$.History.construct();

// Finished definition

})(jQuery); // We are done with our plugin, so lets call it with jQuery as the argument
;
/* 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);;
/* 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 86 2009-08-30 21:45:11Z kelvin.luck@gmail.com $
 */

/**
 * 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
 * @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;
			
			if ($(this).parent().is('.jScrollPaneContainer')) {
				currentScrollPosition = settings.maintainPosition ? $this.position().top : 0;
				var $c = $(this).parent();
				paneWidth = $c.innerWidth();
				paneHeight = $c.outerHeight();
				$('>.jScrollPaneTrack, >.jScrollArrowUp, >.jScrollArrowDown, >.jScollCap', $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();
				var $container = $('<div></div>')
					.attr({'className':'jScrollPaneContainer'})
					.css(
						{
							'height':paneHeight+'px', 
							'width':paneWidth+'px'
						}
					);
				if (settings.enableKeyboardNavigation) {
					$container.attr(
						'tabindex', 
						settings.tabIndex
					);
				}
				$this.wrap($container);
				// 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;

			if (percentInView < .99) {
				var $container = $this.parent();
				$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") {
						$e = $(pos, $this);
						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 (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 : 17,
	scrollbarMargin : 0,
	wheelSpeed : 50,
	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
};

// 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);;
$(function(){
	$("form").forms();
});

$.fn.forms = function(){
	$(this).each(function(){
		$.forms( $(this) );
	});
};

$.forms = function( form ){


	form.find("[href$='#submit']").bind("click", function( ev ){
		ev.preventDefault();
		form.submit();
	});

	form.find("input").bind("keypress", function(e){
		var code = e.keyCode ? e.keyCode : e.which;
		if( code == 13 ){
			form.find("[href$='#submit']").trigger("click");
		};
	}).each(function(){
		var obj = $(this);
		var label = obj.attr("label");
		var val = obj.val();

		if( label ){

			if( val == "" ){
				obj.val( label );
			};

			obj.bind("focus", function(){
				if( obj.val() == label ){ obj.val(""); }
			});

			obj.bind("blur", function(){
				if( obj.val() == "" ){ obj.val( label ); }
			});


		};
	});

	form.bind("submit", function( ev ){

		if( $.forms.check( form ) == false ){
			return false;
		};

		if( form.attr("ajax") == "true" ){
			ev.preventDefault();
			/* Kogume vormilt info kokku, action, method, väljade väärtused */
			var url = form.attr("action");
			var type = form.attr("method");
			var data = form.serialize();

			$.ajax({

				url: url,
				type: type,
				data: data,
				success: function( answer ){

					/*Õnnestunud vastuse kuvamine, kui tahad serverist kuvada kasuta muutujat "answer" */





				},
				error: function( answer ){

					/*Ebaõnnestunud vastuse kuvamine, kui tahad serverist kuvada kasuta muutujat "answer" */


				}

			});
		};

	});

};

$.forms.check = function( form ){

	form.data("flag", "0");

	form.find("[custom_validate], [custom_required]").each(function(){

		var input = $(this);

		/*Error class lisamine nii inputile, kui tema parentile "label" */
		if( input.attr("type") == "radio") {
			if( $.forms.radios( input ) == false ){
				input.addClass("error")
				.parent(".label").addClass("error").end()
				.parent("label").addClass("error");
			}
			else{
				input.removeClass("error")
				.parent(".label").removeClass("error").end()
				.parent("label").removeClass("error");
			};
		}
		else if( input.attr("type") == "checkbox") {
			if( $.forms.checkboxes( input ) == false ){
				input.addClass("error")
				.parent(".label").addClass("error").end()
				.parent("label").addClass("error");
			}
			else{
				input.removeClass("error")
				.parent(".label").removeClass("error").end()
				.parent("label").removeClass("error");
			};
		}
		else{

			if( $.forms.cases( input ) == false ){
				input.addClass("error")
				.parent(".label").addClass("error").end()
				.parent("label").addClass("error");
			}
			else{
				input.removeClass("error")
				.parent(".label").removeClass("error").end()
				.parent("label").removeClass("error");
			};
		};

	});


	if( form.data("flag") == "1" ){return false;}
	else{ return true; };
};

$.forms.radios = function( input ){
	var form = input.parents("form:first");
	var inputs = form.find("input[name='"+input.attr("name")+"']");
	var flag = 0;

	inputs.each(function(){
		if( $(this).is(":checked") ){
			flag = 1;
		};
	});

	if( flag == 1 ){
		return true;
	}else{
		form.data("flag", "1");
		return false;
	};

};

$.forms.checkboxes = function( input ){
	var form = input.parents("form");
	if( input.is(":checked") ){
		return true;
	}
	else{
		form.data("flag", "1");
		return false;
	};

};

$.forms.cases = function( input ){

	var type = input.attr("custom_validate");
	var value = input.attr("value");
	var form = input.parents("form");
	var required = input.attr("custom_required");
	var minimum = input.attr("minimum") || 1;
	var maximum = input.attr("maximum") || 999999999;
	var reg_exp = false;

	/*RegeExpide tegemine, siin olev "case" PEAB vastama inputi küljes oleva validate väärtusega*/
	switch( type ){

		case "default" : {
			reg_exp = '';
			break;
		}
		case "email" : {
			reg_exp = new RegExp(/^(("[\w-\s]+")|([\w-]+(?:\.[\w-]+)*)|("[\w-\s]+")([\w-]+(?:\.[\w-]+)*))(@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i);
			break;
		}
		case "numbers" : {
			reg_exp = new RegExp(/^[0-9]+$/);
			break;
		}
		case "decimal" : {
			reg_exp = new RegExp(/^\d+([\.\,]\d+)?$/);
			break;
		}
		case "letters" : {
			reg_exp = new RegExp(/^[A-Z]+$/i);
			break;
		}
		case "alphanum" : {
			reg_exp = new RegExp(/^\w+$/i);
			break;
		}
		case "date" : {
			reg_exp = new RegExp(/^\d{2}\.\d{2}\.\d{4}$/);
			break;
		}

	};

	if( required ){
		if(!value.match(reg_exp) ||
			value.length < minimum ||
			value.length > maximum ||
			value == input.attr("label")
		){  form.data("flag", "1"); return false;}
		else{ return true; }
	}
	else if( value.length > 0 ){
		if(!value.match(reg_exp) ||
			value.length < minimum ||
			value.length > maximum ||
			value == input.attr("label")
		){  form.data("flag", "1"); return false;}
		else{ return true; }
	};



};
;
$(function(){
	$("form").fancy_form();
});

$.fn.fancy_form = function(){
	
	$(this).find("select").each(function(){
		$.fancy_select( $(this) );
	});

	$(this).find("input[type='checkbox']").each(function(){
		$.fancy_checkbox( $(this) );
	});

	$(this).find("input[type='radio']").each(function(){
	
		$.fancy_radio( $(this) );
	});
	
};

$.fancy_select = function( obj ){
			
	if( obj.data("fancy") == "1" ){ return; }
	obj.data("fancy", "1");
	
	action( obj );
	
	function action( obj ){
		
		var label = obj.parent();
		var addons = obj.attr("class");
		var form = obj.parents("form:first");
		var value = obj.find("[selected]").html() || obj.find("[value='"+obj.attr('value')+"']").html() || obj.find("option:first").html();
		value = value.split("[").join("<").split("]").join(">");
		
		var output =	'<div class="select '+addons+'">'+
								'<div class="active"><div>'+ value +'</div></div>'+
								'<div class="more">';
		
		
		
		obj.find("optgroup, option").each(function(){

			var option = $(this);
			
			if( option.is("option") ){
				var addon;
				if( option.parent().is("optgroup") ){
					addon = 'level2';
				};
				output+= '<a linked="'+option.attr("value")+'" class="option '+addon+'">'+option.text().split("[").join("<").split("]").join(">")+'</a>';
			}else{
				output+= '<div class="optgroup">'+option.attr("label")+'</div>';
			};
			
		});
		
		output+=	'</div>'+
					'</div>';
		
		obj.hide().parent().append( output );
		
		var id = obj.attr("id");
		var rels = label.parent().find(".label[rel='"+id+"']");
		var rel = rels.eq(0).find("select").attr("rel");
		var new_select = obj.parent().find(".select");
		var shop_list = $(".shop_list");
		
		var flag = 0;
		new_select.click(function(e){
			
			if( $(this).is(".open") ){
				new_select.removeClass("open");
			}
			
			else{
				
				$(".select").removeClass("open");
				new_select.addClass("open");
								
				$(document).unbind("click");
					
				$(document).bind("click", function(){
					$(document).click(function(e){
						
						if( flag == 1 ){
							
							flag = 0;
						
						}
						else{
							$(".select").removeClass("open");
							$(document).unbind();
						}
						
					});
				});
					
				
		
			}
			
		}).end().find(".more a").click(function(e){
			
			
			obj.attr("value", $(this).attr("linked") );
			new_select.find(".clicked").removeClass("clicked");
			$(this).addClass("clicked");
			new_select.find(".active div").html( $(this).html() );
			
			if( obj.attr("rel") == "link" ){
				
				var location = window.location.toString();
				
				var linked = $(this).attr("linked");
								
				if( location.indexOf( linked ) == -1 ){
					window.location = linked;
				}
				
			};
			
			if( obj.attr("auto_post") == "true") {
				new_select.parents("form").submit();
			}
			
			
			if( obj.attr("id").indexOf("smartpost") !== -1 ){
				var text = obj.find("option[value='"+ obj.val() +"']").text();
				obj.parents(".label:first").find("input:first").val( text );
			};

			if( obj.is("#countySwitch") ){

				var value = obj.val();
								
				rels.removeAttr("rel").find("select");
				
				rels.each(function(){
					var elem = $(this);
					if( elem.attr("filter") == value ){
						elem.removeClass("hide").find("select").attr("rel", rel);
					}else{
						elem.addClass("hide").find("select").removeAttr("rel");	
					};
				});
					
				
			};
			form.find("input[rel]").eq(0).trigger("change");
		});
		
		if( obj.find("[selected") ){
			new_select.find(".more a[linked='"+ obj.find("[selected]").attr("value") +"']").trigger("click").trigger("click");
		};
		
		if( obj.is("#countySwitch") ){

				var value = obj.val();
								
				
				rels.each(function(){
					var elem = $(this);
					if( elem.attr("filter") == value ){
						elem.removeClass("hide").attr("rel", rel);
					}else{
						elem.addClass("hide").removeAttr("rel");	
					};
				});
					
				form.find("input[rel]").eq(0).trigger("change");
			};
			

		
		obj.find("option").click(function(){
			if( obj.attr("auto_post") == "true") {
				new_select.parents("form").submit();
			}
		});		
		
	};

	
};

$.fancy_checkbox = function( checkboxes ){

		
	if( checkboxes.data("fancy") == "1" ){ return; }
	checkboxes.data("fancy", "1");
	
	action( checkboxes );
		
	
	function action( checkbox ){
		
		var label = checkbox.parent();
		label.addClass("add_cursor");
		checkbox.css({
			
			position: "absolute",
			top: "0",
			left: "0",
			opacity: "0"
			
		});
		
		label.prepend('<span class="checkbox">&nbsp;</span>');
		
		var container = label.parent();
		
		container.keyup(function(){
			active();
			if( label.find("input").attr("auto_post") == "true" ){
				$(this).parents("form").submit();
			};
		});
		
		label.click(function(){
			active();
			if( label.find("input").attr("auto_post") == "true" ){
				$(this).parents("form").submit();
			};
		});
		
		active();
		
		function active(){
			container.find(".active").removeClass("active");
			container.find("input:checked").parent().addClass("active");
		};
		
		
	};

};

$.fancy_radio = function( radios ){
	
		
	if( radios.data("fancy") == "1" ){ return; }
	radios.data("fancy", "1");
	
	action( radios );
		
	
	function action( radio ){
		
		var label = radio.parent();
		label.addClass("add_cursor");
		radio.css({
			
			position: "absolute",
			top: "0",
			left: "0",
			opacity: "0"
			
		});
		
		if( radio.is(":checked") ){
			label.addClass("active");	
		};
		
		label.prepend('<span class="radio">&nbsp;</span>');
		
		var container = label.parents("form:first");
		
		container.keyup(function(){
			active();
			if( label.find("input").attr("auto_post") == "true" ){
				$(this).parents("form").submit();
			};
		});
		
		label.click(function(){
			active();
			if( label.find("input").attr("auto_post") == "true" ){
				$(this).parents("form").submit();
			};
		});
		
		active();
		
		
		function active(){
			
			container.find("label.active").removeClass("active");
			container.find("input:checked").parent().addClass("active");
			
		};
		
		
	};
		
};


;
$.fn.notification = function ( option ){
	
	option.fadeOutSpeed = 500;
	
	var inject = $("body");
	
	inject.children(".notificationPopup, .notificationOpaque").remove();
	
	var output = '<div class="notificationOpaque opacity_85">&nbsp;</div>';
	
	if( option.iframe ){
		output+='<div class="notificationPopup"><iframe width="'+option.width+'" height="'+option.height+'" src="'+option.url+'" /></div>';
	};
	
	inject.append( output );
	
	$("body, html").addClass("overflowHidden");
	
	option.layer = inject.children(".notificationPopup:first");
	option.opaque = inject.children(".notificationOpaque:first");
	
	positionElements();
	
	function positionElements(){
		
		var docHeight = $(document).height();
		var docWidth = $(document).width();
		var winHeight = $(window).height();
		var winWidth = $(window).width();
		
		option.opaque.removeAttr("style").css({
			left:0,
			top:0,
			width: docWidth,
			height: docHeight,
			visibility: "visible"
		});
		
		option.layer.removeAttr("style").css({
			left: (winWidth - option.layer.outerWidth()) / 2,
			top: (winHeight - option.layer.outerHeight()) / 2,
			visibility: "visible"
		});
		
	};
	
	option.layer.css({
		visibility: "visible",
		display: "none"
	}).fadeIn();
	option.opaque.css({
		visibility: "visible",
		display: "none"
	}).fadeIn();
	
	$(window).bind("resize", positionElements);
		
	function closeNotifications(){
		
		option.opaque.fadeOut(option.fadeOutSpeed);
		option.layer.fadeOut(option.fadeOutSpeed, function(){
			option.opaque.remove();
			option.layer.remove();
			$("body, html").removeClass("overflowHidden");
		});
		
		window.location.hash = "";
		
	};
	
	option.opaque.bind("click", function(e){
		e.preventDefault();
		closeNotifications();
	});
	
};

function closeNotification(){
	$("body").children(".notificationOpaque:first").trigger("click");
};
;
$(function(){
	
	$.topMenu();
	//$.mainMenu();
	if( $("body").height() < $(window).height() && self==parent ){
		$("body, html").css("height", "100%");
	};
	
	$("#smartpost").smartpost();
	$("a[rel='popup']").popups();
	$(".slideShowNavigation").slideShow();
	$("#frontPageProducts").productButtons();
	$("#shoppingCart").shoppingCart();
	
	$("#leftPane .subMenu").subMenu();
	$("#rightPane .banner").banner();
	$(".notification").notifications();
	$(".productHolder").productHolder();
	
	$("body.iframe").iframe();
	$("#basketRight form").noLeave();
	$("#product").product();
	
	$(".productSlide").productSlide();
	
	$("#paymentForm, #deliveryForm").changeAddress();
	
	var $state = $('#state'), $custom = $('#custom'), $overloading = $('#overloading');	

	$.History.bind(function(state){

		$state.text(state);

		if( state.match("goTo=") ){
			var existingPopup = $("body > .notificationPopup");
			if( existingPopup.size() > 0 ){
				var url = window.location.hash.split("#goTo=")[1];
			
				if( url.match("\\?") ){
					url+="&frame=if";
				}else{
					url+="?frame=if";
				};
				existingPopup.find("iframe").attr("src", url);
				return false;
			};
			
			var url = window.location.hash.split("#goTo=")[1];
			
			if( url.match("\\?") ){
				url+="&frame=if";
			}else{
				url+="?frame=if";
			};

			
			$("body").notification({
				url: url,
				iframe: true,
				width:940,
				height:539
			});
		};
		
		
		
	});
	
});


$.fn.smartpost = function(){
	var checkStatus;
	var main = $(this);
	
	checkStatus = setInterval(
		function(){
			if( main.find("select") ){
				
				$("form").fancy_form();
				
				clearInterval( checkStatus );
			};
		}, 1000);
};

$.fn.noLeave = function(){
	var form = $(this);
	var items = form.find("select[rel='noLeave'], input[rel='noLeave']");
	var noLeave = form.find("input[name='noLeave']");
	
	items.bind("change", function(){
		noLeave.val("1");			
		form.submit();
	});
	
};

$.fn.notifications = function(){
	var notification = $(this);
	notification.each(function(){
		var obj = $(this);
		var btn = obj.find(".close");
		
		btn.bind("click", function(e){
			e.preventDefault();
			obj.fadeOut(500, function(){
				obj.remove();
			});
		});
		
	});
};

$.fn.changeAddress = function(){
	
	var instance = $(this).find("input, select");
	var flag = 0;
	var payment, delivery;
	var button = $("#changeLocation");
	var check = $(this).parents("form:first").find("input[name='delivery_address_changed']");
	
	button.bind("click", function(e){
		e.preventDefault();
		if( button.is(".active") ){
			delivery.slideUp();
			button.removeClass("active");
			check.val("0");
			flag = 0;
		}else{
			delivery.slideDown();
			button.addClass("active");
			check.val("1");
			flag = 1;
		};
		makeText();
	});
	
	$(this).each(function(){
		if( $(this).is("#deliveryForm") ){
			delivery = $(this);	
		}
		else{
			payment = $(this);
		};
	});
	
	var main = $("#delivery");
	var orig = main.find("p[rel='orig']");
	var template = main.find("p[rel='template']");
	if( orig.size() == 0 ){
		return false;
	};
	instance.bind("change", function(){
			makeText();
	});
	
	function makeText(){
		var form;
		var tmp = template.html();
		
		if( flag == 0 ){
			form = payment;	
		}else{
			form = delivery;
		};
		
		form.find("input").each(function(){
			var obj = $(this);
			var name = obj.attr("rel");
			if( obj.val() == "" ){
				tmp = tmp.split("?"+name+"?").join("");
			}else{
				tmp = tmp.split("?"+name+"?").join( obj.val() );
			};
		});
		
		form.find("select").each(function(){
			var obj = $(this);
			var val = obj.val();
			var name = obj.attr("rel");
			var label = obj.find("option[value='"+val+"']").text();
			if( label == "" || val == ""){
				//tmp = tmp.split("?"+name+"?").join("");
			}else{
				tmp = tmp.split("?"+name+"?").join( label );
			};
		});
		
		tmp = tmp.split(/\?.*\?/).join("").split(" ,").join("") ;
		
		orig.html( tmp );
		
	};
	
	makeText();
	
};

$.fn.productSlide = function(){
	
	$(this).each(function(){
		
		var main = $(this);
		var template = '<a href="#" rel="?number?" class="radius_20 opacity_25">?number?</a>';
		var slides = main.find(".slide");
		var output = '';
		var pagination = main.find(".pagination");
		var timeout = '';
		var flag = 0;
		var pageLoad = 1;
		
		for( var i = 0; i < slides.size(); i++ ){
			output+= template.split("?number?").join( i );	
		};
		
		pagination.html( output );
		
		var anchors = pagination.find("a");
		
		anchors.bind("click", function(e){
			e.preventDefault();
			
			clearTimeout( timeout );
			if( flag == 1 ){ return false;}
			flag = 1;
			
			var rel = parseInt($(this).attr("rel"));
			var active = slides.eq( pagination.find(".active").attr("rel") );
			var activeRel = pagination.find(".active").attr("rel");
			
			if( slides.size() > 1 ){
				timeout = setTimeout(function(){
					var trigger = pagination.find("a[rel='"+(rel+1)+"']");
					if( trigger.size() == 0 ){
						trigger = pagination.find("a[rel='0']");
					};
					trigger.trigger("click");
				}, 5000);
			};
			
			anchors.removeClass("active").css("opacity", 0.25);
			$(this).addClass("active").css("opacity", 0.7);
			
			if( pageLoad == 1 ){
				pageLoad = 0;
				slides.eq( rel ).css("left", 0);
				flag = 0;
				return false;
			};
			
			
			if( rel == activeRel ){
				flag = 0;
				return false;
			};
			
			active.animate({left:-938}, 1000, function(){
				
			});
			
			slides.eq( rel ).css("left", 938);
			slides.eq( rel ).css("left", 938).animate({left:0}, 1000, function(){
				flag = 0;
			});
			
			
			
			
		}).eq(0).trigger("click");
		
		
	});
	
};

$.fn.product = function(){
	
	var main = $(this);
	var readMore = main.find("#readMore");
	var more = readMore.prev(".more");
	
	readMore.bind("click", function(e){
		e.preventDefault();
		var obj = $(this);
		var altText = obj.attr("alternateText");
		var altImg = obj.attr("alternateImg");
		var origText = obj.text();
		var origImg = obj.find("img").attr("src");
		var output = '<img src="'+altImg+'">'+altText;
		
		obj.attr({
			alternateText: origText,
			alternateImg: origImg
		}).html( output );
		
		
		if( !obj.is(".active") ){
			more.slideDown();		
			obj.addClass("active");
		}
		else{
			more.slideUp();
			obj.removeClass("active");
		};
		
	}).each(function(){
		var obj = $(this);
		var src = obj.attr("alternateImg");
		var tmp = new Image();
		tmp.src = src;
	});
	
};

$.fn.popups = function(){
	
	var anchors = $(this);
	
	anchors.bind("click", function(e){
		e.preventDefault();
		window.location.hash = "goTo="+$(this).attr("href");
	});
	
};

$.fn.iframe = function(){
	
	var main = $(this);
	var content = main.find("#iframeContent");
	content.find(".holder").jScrollPane({animateTo:true});

	
	
	main.find("#closeNotification, [rel='closePopup']").bind("click", function(e){
		e.preventDefault();
		parent.closeNotification();
	});
	
	main.find("a[href]").not("[href='#submit'], [target], [href='#toggleText']").bind("click", function(e){
		e.preventDefault();
		parent.location.hash = "goTo="+$(this).attr("href");
	});
	
	main.find("a[href='#toggleText']").bind("click", function(e){
		e.preventDefault();
		
		var obj = $(this);
		var rel = obj.attr("rel");
		var toggle = main.find("#"+rel );
		
		if( obj.data("toggle") == "1" ){
			toggle.slideUp(500, function(){
				content.find(".holder").jScrollPane();
				content.find(".holder")[0].scrollTo( "#"+rel  );
			});	
			obj.data("toggle", 0);
		}else{
			toggle.slideDown(500, function(){
				content.find(".holder").jScrollPane();
				content.find(".holder")[0].scrollTo( "#"+rel  );
			});
			obj.data("toggle", 1);
		};
		
		
	});
	
};


$.fn.productHolder = function(){
	
	$(this).each(function(){
		
		var main = $(this);
		var products = main.find(".productList .item");
		var productGroup = main.find(".productGroup");
		var images = main.find(".item img");
		
		images.each(function(){
			var obj = $(this);
			var src = obj.attr("src");
			obj.removeAttr("src");
			obj.attr("src2", src);
		});
		
		products.hover(function(){
			$(this).find(".buttons").stop().removeAttr("style").fadeIn(200);
		}, function(){
			$(this).find(".buttons").hide();
		});
		
		var anchors = main.find(".productNavi a");
		
		anchors.bind("click", function(e){
			e.preventDefault();
			anchors.removeClass("active");
			$(this).addClass("active");
			
			var active = main.find(".productGroup.active");
			var next = main.find(".productGroup[rel='"+$(this).attr("href").split("#")[1]+"']");
			active.removeClass("active");
			next.addClass("active");
			centerPages( next );
		});
		
		anchors.each(function(){
			$(this).css({
				width: $(this).width()+50
			});
		});
		
		centerPages(  main.find(".productGroup.active:first") );
		
		function centerPages( group ){

			var inlineWidth = 0;
			var productPages = group.find(".productPages:last");
			var pagesAnchors = productPages.find("a");
			pagesAnchors.each(function(){
				var obj = $(this);
				inlineWidth+= obj.outerWidth();	
				inlineWidth+= parseInt(obj.css("marginLeft"));	
				inlineWidth+= parseInt( obj.css("marginRight"));	
			});
			
			productPages.find(".inline").css({
				marginLeft : (702-inlineWidth)/2
			});
			
			inlineWidth = 0;
			
			var productPagination = group.find(".productPagination");
			var paginationAnchors = productPagination.find("a");
			
			paginationAnchors.each(function(){
				var obj = $(this);
				inlineWidth+= obj.outerWidth();	
				inlineWidth+= parseInt(obj.css("marginLeft"));	
				inlineWidth+= parseInt( obj.css("marginRight"));	
			});
			
			productPagination.find(".inline").css({
				marginLeft : (386-inlineWidth)/2
			});
			
			loadImages( group );
		};
		
		function loadImages( container ){
			var images = container.find(".item img");
			images.each(function(){
				var obj = $(this);
				var src = obj.attr("src2");
				if(!obj.attr("src") ){
					var tmp = new Image();
					
					tmp.onload = function(){
						obj.hide();
						obj.attr("src", src );
						obj.fadeIn();	
					};
					tmp.src = src;
				};
			});
			
		};
		
	});
	
	
};


$.fn.banner = function(){
	
	var main = $(this);
	var showMore = main.find(".showMore");
	var more = showMore.prev(".more");
	var alt = showMore.attr("alternate");
	
	var text = showMore.text();
	
	showMore.bind("click", function(e){
		e.preventDefault();
		var obj = $(this);
		
		if( !obj.is(".active") ){
			more.slideDown();
			obj.addClass("active").text( alt );
		}
		else{
			more.slideUp();
			obj.removeClass("active").text( text );
		};
		
		
	});
	
};


$.fn.subMenu = function(){
	
	var main = $(this);
	
	main.each(function(){
		
		var obj = $(this);
		var holder = obj.find(".holder");
		var active = obj.find(".holder.active");
		var anchors = obj.find(".categories a");
		var flag = 0;
				
		if( active.height() > 282 ){
			flag = 1;
			active.css("height", 282);
		};
		
		
		active.jScrollPane();
		
		//anchors.bind("click", function(e){
		//	e.preventDefault();
		//	flag = 0;
			
		//	anchors.removeClass("active");
		//	$(this).addClass("active");
		//	var href = $(this).attr("href");
			
			//main.find(".categories a[href='"+href+"']").not($(this)).each(function(){
			//	if( !$(this).is(".active") ){
			//		$(this).trigger("click");
			//	};
			//});
			
		//	holder.removeClass("active").jScrollPaneRemove();
		//	holder.css("height", "auto");
		//	active = obj.find(".holder[rel='"+$(this).attr("href").split("#")[1]+"']:first");
		//	active.addClass("active");
			
		//	if( active.height() > 282 ){
		//		flag = 1;
		//		active.css("height", 282);
		//	};
			
			
		//	if( active.find(".active").size() > 0 && flag == 1 ){
		//		active[0].scrollTo(active.find(".active").position().top);	
		//	};
		//});
		
		//if( active.find(".active").size() > 0 && flag == 1 ){
		//	active[0].scrollTo(active.find(".active").position().top);	
		//};
		
	});
	
};

$.fn.shoppingCart = function(){
	
	var main = $(this);
	
	var sum = main.find(".sum");
	var holder = main.find(".holder");
	var more = main.find(".more");
	var timeout;
	var state;
	more.append('<div class="shaddow">&nbsp;</div>');
	
	main.hover(function(){
		if( main.is(".full") ){
			clearTimeout( timeout );
			if( state == "open" ){
				return false;
			};
			state = "open";
			toggleMore("open");
		};
	}, function(){
		if( main.is(".full") ){
			timeout = setTimeout( function(){
				toggleMore("close");
				state = "close";
			}, 200);
		};
	});
	
	
	function toggleMore( state){
		
		if( state == "close" ){
			main.removeClass("open");
			holder.jScrollPaneRemove();
		}
		else{
			main.addClass("open");
			checkHeight();
		};
	};
	
	function checkHeight(){
		
		holder.removeAttr("style");
		var moreH = more.outerHeight();
		var offset = main.offset().top;
		var height = holder.outerHeight();
		var winH = $(window).height();
		var holderH = holder.outerHeight();
		var defaultH = moreH - holderH;
		
		if( moreH + offset > winH ){
			var newH = winH - defaultH - offset-20;
			holder.css("height", newH).jScrollPane();
		};
	};
	
	
	
	
};

$.fn.productButtons = function(){
	
	var main = $(this);
	var anchors = main.find(".item");
	
	anchors.hover(function(){
		$(this).find(".buttons").stop().removeAttr("style").fadeIn(200);
	}, function(){
		$(this).find(".buttons").hide();
	});
	
};

$.fn.slideShow = function(){
	
	$(this).each(function(){
		ignite($(this).parent());
	});

	function ignite( main ){
		main.append("<div class='shaddow'>");
		main.find(".shaddow:first").css({
			opacity: 0.1,
			display: "block"
		});
		var images = main.find("img");
		var navi = main.find(".slideShowNavigation");
		var option = {};
		option.state = -1;
		option.speed = 500;
		option.delay = 5000;
		option.flag = 0;
		
		option.callback = function(){
			clearTimeout( option.timeout );
			option.timeout = setTimeout(function(){
				nextImage();
			}, option.delay);
		};
		
		var output = '';
		images.each(function(e, val){
			output+='<span href="#'+e+'" class="radius_20 opacity_25 bulletin">'+e+'</span>';
		});
		
		navi.html( output );
		
		var anchors = navi.find(".bulletin");
		
		anchors.bind("click", function(e){
			e.preventDefault();
			clearTimeout( option.timeout );
			
			if( option.flag == 1 ){
				option.callback();
				return false;
			};
			option.flag = 1;
			
			option.obj = $(this);
			option.href = option.obj.attr("href").split("#")[1];
			option.state = option.href;
			option.active = navi.find(".active");
			loadImage();
				
		});
		
		function loadImage(){
			
			option.img = images.eq(option.state);
			var src = option.img.attr("src");
			var tmp = new Image();
			
			tmp.onload = function(){
				showImage();
			};
			
			tmp.src = src;
			
		};
		
		function showImage(){
			
			images.eq( option.state ).parent("a").css("left", 938);
			images.eq( option.state ).parent("a").animate({left: 1}, option.speed, "linear", function(){
				option.flag = 0;
				option.callback();	
			});
			
			var rel = option.active.attr("href");
			if( rel ){
				rel = rel.split("#")[1];
				
				if( option.state == rel ){
					option.flag = 0;
					option.callback();
					return false;
				};
				images.eq( rel ).parent("a").animate({left: -938}, option.speed, "linear", function(){
					
				});
				
				
			};
			
			anchors.css("opacity", 0.25).removeClass("active");
			option.obj.css("opacity", 0.7).addClass("active");
			
			
			
		};
		
		function nextImage(){
			
			option.state++;
			if( option.state > images.size()-1 ){
				option.state = 0;
			};
			
			anchors.eq(option.state).trigger("click");
			
			
			
		};
		
		nextImage();
		
	};
	
};

$.mainMenu = function(){
	
	var main = $("#mainMenu");
	var anchors = main.find("a");
	var maxWidth = 940;
	var width = 0;
	
	anchors.each(function(){
		width+= $(this).outerWidth()+24;	
	});
	
	var marginWidth = maxWidth - width;
	marginWidth = marginWidth/2;
	
	main.css("left", marginWidth);
	
};

$.topMenu = function(){
	
	var main = $("#topMenu");
	var items = main.find(".item");
	
	items.each(function(){
		var obj = $(this);
		var timeout;
		var more = obj.find(".more");
			
			
		obj.bind("mouseover", function(){
			obj.data("open", "true");
			
			obj.addClass("active").find(".more").slideDown(500, function(){
				if( obj.data("open") == "false" ){
					more.hide();
				};
			});
			clearTimeout( timeout );
		});
		
		obj.bind("mouseout", function(){
			obj.data("open", "false");
			if( obj.find("input:focus").size() > 0 ){
				obj.find("input:focus").bind("blur", function(){
					if( obj.data("open") == "false" ){
						obj.trigger("mouseout");
					};
				});
				return false;
			};
			
			timeout = setTimeout(function(){
				obj.removeClass("active");
				more.hide();
			}, 0);
		});
		
	});
};;

