jQuery.fn.extend({
	scrollpanel: function(scrollPanelParent, submenuArea, childSelector, itemWidth, jumpPixels, alignCentered, includePageGutter, additionalCssClass, landingPage) {
		return this.each(function() {
			
			// These two CSS settings have to be hardcoded
			// IE does not like $.css property when the HTML dom is appended and loaded dynamically
			// when we change the design / images of these two, we might need to change these values as well
			var scrollGutterWidth = 749;
			var scrollHandleWidth = 107;
			var scrollArrowHoldSlideIncrement = 5; // in pixels
			var scrollPanelParentInnerWidth = scrollPanelParent.innerWidth();
			var scrollGutterLeftOffset;
			var scrollHandleLeftOffset;
			var isLeftMouseDown = false;
			var isRightMouseDown = false;
			var slideTimeout = 5;
			var slideDirection;
			
			var scrollPanel = $(this);
			var contentWidth = 0;
			var adjustedContentWidth = 0;
			var menuWidth = 0;
			var pageGutterWidth = 0;
			var animationTimeout = null;
			var animationInterval = 40;
			var target_x;
			var current_x;
			var scrollbar;
			var scrollbarInner
			var scrollbarLeftArrow;
			var scrollbarRightArrow;
			var scrollGutter;
			var scrollHandle;
			var initialScrollHandlePos;
			var initialMousePos;
			var scrollbarCreated = false;
			var scrollbarAdded = false;
			var imageOffset = 450;
			
			$('body').before('<span class="value"></span>');
			$('span.value').css({'position':'fixed', 'top':0, 'left':0});
			
			//Helper functions
			var initialAnimation = function() {				
				if (animationTimeout == null) animationTimeout = setInterval(animatePanelMovement, animationInterval);
				setScrollHandlePos();
			}
			var kickOffAnimation = function() {				
				if (animationTimeout == null) animationTimeout = setInterval(animatePanelMovement, animationInterval);
			}
			var kickOffSlideAnimation = function(direction) {
			    if (animationTimeout == null) animationTimeout = setInterval(slidePanelMovement, slideTimeout);
			}
			var animatePanelMovement = function() {
				current_x = scrollPanel.offset().left;
				var movement_x = Math.round(((target_x + menuWidth) - current_x) / 5);
				
				if (movement_x == 0) {
					current_x = target_x + menuWidth;
					clearInterval(animationTimeout);
					animationTimeout = null;
				} else if (movement_x > 0) {
					current_x += movement_x + 1;
				} else {
					current_x += movement_x - 1;
				}
				
				scrollPanel.css('left', current_x + 'px');
				
				// set cookies to remember scroll position
				$.cookie('scrollPanelPosition', target_x + menuWidth, { path: '/' });
				$.cookie('currentURL', window.location.pathname, { path: '/' });
				$.cookie('scrollTarget', target_x, { path: '/' });	
			}
			var slidePanelMovement = function() {
			    if (isMouseDown) {
			        if (slideDirection == "left") {
			            if (scrollPanel.offset().left + scrollArrowHoldSlideIncrement > menuWidth) {
	                        target_x = 0;
	                        movePanel();
                        } else {
	                        target_x = (scrollPanel.offset().left - menuWidth) + scrollArrowHoldSlideIncrement;
	                        movePanel();
                        }
			        } else {
			            if (adjustedContentWidth + (scrollPanel.offset().left - menuWidth) - scrollArrowHoldSlideIncrement < scrollPanelParentInnerWidth) {
					        target_x = 0 - (adjustedContentWidth - scrollPanelParentInnerWidth);
					        movePanel();
				        } else {
					        target_x = (scrollPanel.offset().left - menuWidth) - scrollArrowHoldSlideIncrement;
					        movePanel();
				        }
			        }
			    } else {
			        clearInterval(animationTimeout);
				    animationTimeout = null;
				
				    // set cookies to remember scroll position
				    $.cookie('scrollPanelPosition', target_x + menuWidth, { path: '/' });
				    $.cookie('currentURL', window.location.pathname, { path: '/' });
				    $.cookie('scrollTarget', target_x, { path: '/' });	
			    }
			}
			var movePanel = function() {
			    current_x = scrollPanel.offset().left;
				var movement_x = target_x + menuWidth - current_x;
				current_x += movement_x;
				scrollPanel.css('left', current_x + 'px');
				setScrollHandlePos();
				
				// set cookies to remember scroll position
				$.cookie('scrollPanelPosition', target_x + menuWidth, { path: '/' });
				$.cookie('currentURL', window.location.pathname, { path: '/' });
				$.cookie('scrollTarget', target_x, { path: '/' });	
			}
			var setScrollHandlePos = function() {			    
			    scrollGutterLeftOffset = scrollGutter.offset().left;			
				var gutterStart = scrollGutter.offset().left - scrollbarInner.offset().left;
				var scrollPos = (0 - target_x) / (adjustedContentWidth - scrollPanelParentInnerWidth);
				scrollHandle.css('left', (gutterStart + Math.round((scrollGutterWidth - scrollHandleWidth) * scrollPos)) + 'px');
				scrollHandleLeftOffset = scrollHandle.offset().left;
				initialScrollHandlePos = scrollHandleLeftOffset - scrollGutterLeftOffset;
			}
			var createScrollbar = function() {				
				if (!scrollbarCreated) {				
					//Create the scrollbar area
					scrollbar = $("<div></div>");
					scrollbar.addClass("scrollbar");
					
					//Add the actual scrollbar to the scroll area
					scrollbarInner = $("<div></div>");
					scrollbarInner.addClass("scrollbarInner");
					scrollbar.append(scrollbarInner);
					
					//Add the left arrow to the scrollbar
					scrollbarLeftArrow = $('<a href="#"></a>');
					scrollbarLeftArrow.addClass("leftScrollArrow");
					
//					scrollbarLeftArrow.click(function(e) {
//						e.preventDefault();
//						if (scrollPanel.offset().left + jumpPixels > menuWidth) {
//							target_x = 0;
//						}
//						else {
//							target_x = (scrollPanel.offset().left - menuWidth) + jumpPixels;
//							kickOffAnimation();
//						}
//						setScrollHandlePos();
//					});
					scrollbarLeftArrow.mousedown(function(e) {
                        isMouseDown = true;
                        slideDirection = "left";
                        kickOffSlideAnimation();
					});
					scrollbarLeftArrow.mouseout(function(e) {
                        isMouseDown = false;
					});
					scrollbarLeftArrow.mouseup(function(e) {
                        isMouseDown = false;
					});
					scrollbarInner.append(scrollbarLeftArrow);
					
					//Add the right arrow to the scrollbar
					scrollbarRightArrow = $('<a href="#"></a>');
					scrollbarRightArrow.addClass("rightScrollArrow");
//					scrollbarRightArrow.click(function(e) {
//						
//						//alert(adjustedContentWidth);
//						
//						e.preventDefault();
//						if (adjustedContentWidth + (scrollPanel.offset().left - menuWidth) - jumpPixels < scrollPanelParentInnerWidth) {
//							target_x = 0 - (adjustedContentWidth - scrollPanelParentInnerWidth);
//							kickOffAnimation();
//						} else {
//							target_x = (scrollPanel.offset().left - menuWidth) - jumpPixels;
//							kickOffAnimation();
//						}
//						setScrollHandlePos();
//					});
                    scrollbarRightArrow.mousedown(function(e) {
                        isMouseDown = true;
		                slideDirection = "right";
		                kickOffSlideAnimation();
					});
					scrollbarRightArrow.mouseout(function(e) {
                        isMouseDown = false;
					});
					scrollbarRightArrow.mouseup(function(e) {
                        isMouseDown = false;
					});
					scrollbarInner.append(scrollbarRightArrow);
					
					//Add the clickable scroll gutter to the scrollbar
					scrollGutter = $("<div></div>");
					scrollGutter.addClass("scrollGutter");
					scrollGutter.click(function(e) {
						var scrollPos = (e.pageX - scrollGutterLeftOffset) / scrollGutterWidth;
						target_x = Math.round((0 - (adjustedContentWidth - scrollPanelParentInnerWidth)) * scrollPos);
						movePanel();
						setScrollHandlePos();
					});
					scrollbarInner.append(scrollGutter);
					
					//Add the scroll handle to the scroll gutter (needs to be done after the scrollbar has been added so the gutter has a width)
					scrollHandle = $('<a href="#"></a>');
					scrollHandle.addClass("scrollHandle");
					var dragStart = function(e) {
						initialMousePos = e.pageX - scrollGutterLeftOffset;
						initialScrollHandlePos = scrollHandle.offset().left - scrollGutterLeftOffset;
						scrollHandle.css('background-position', '0 bottom');
					}
					var dragStop = function(e) {
						scrollHandle.css('background-position', '0 0');
						// set cookies to remember scroll position
						$.cookie('scrollPanelPosition', target_x + menuWidth, { path: '/' });
						$.cookie('currentURL', window.location.pathname, { path: '/' });
						$.cookie('scrollTarget', target_x, { path: '/' });
						scrollHandleLeftOffset = scrollHandle.offset().left;
					}
					var dragMove = function(e) {
						var movementX = ((e.pageX - scrollGutterLeftOffset) - initialMousePos);
						var scrollPos = (initialScrollHandlePos + movementX) / (scrollGutterWidth - scrollHandleWidth);
						if (scrollPos < 0) {
						    scrollPos = 0;
						} else if (scrollPos > 1) {
						    scrollPos = 1;
						}
						target_x = (0 - adjustedContentWidth + scrollPanelParentInnerWidth) * scrollPos;
						target_x = Math.round(target_x);
						scrollPanel.css('left', target_x + menuWidth + 'px');
					}
					scrollHandle.draggable({axis: 'x', containment: scrollGutter, cursor: 'w-resize', start: dragStart, stop: dragStop, drag: dragMove});
					scrollbarInner.append(scrollHandle);
					
					scrollbarCreated = true;
				}
			}
			var addOrRemoveScrollbar = function() {			
				//Get the menu width and add it to the content width
				menuWidth = submenuArea.outerWidth() + submenuArea.offset().left;
				
				if(landingPage){
					menuWidth -= 450;
				}
				
				
				//Also add the right hand gutter width
				if (includePageGutter) pageGutterWidth = menuWidth - 167; //167 is the how far the menu comes into the content area
									
				//Add the menu width and the page gutter width to the content area to be used for scrolling
				adjustedContentWidth = contentWidth + menuWidth + pageGutterWidth;
			
				//Add the scrollbar if the content is wider than the browser window
				if (contentWidth > (scrollPanelParentInnerWidth - menuWidth - pageGutterWidth)) {
					
					//Create the scrollbar if not already created
					if (!scrollbarCreated) createScrollbar();
					
					//Add the scrollbar if not already added
					if (!scrollbarAdded) {
						scrollPanel.after(scrollbar);
						scrollbarAdded = true;
					}
					
					//Set the initial scroll handle and content positions
					if ($.cookie('currentURL') == window.location.pathname) {
						// remember scroll position.
						target_x = $.cookie('scrollTarget');
						scrollPanel.css('left', $.cookie('scrollPanelPosition') + 'px');
					}
					else
					{
						if (alignCentered) {
							if (contentWidth < scrollPanelParentInnerWidth) {
								var gapWidth = scrollPanelParentInnerWidth - contentWidth;
								target_x = 0 - (menuWidth - gapWidth);
								scrollPanel.css('left', gapWidth + 'px');
							} else {
								var centerOffsetWidth = Math.round((contentWidth - scrollPanelParentInnerWidth) / 2);
								target_x = 0 - (menuWidth + centerOffsetWidth);
								scrollPanel.css('left', -centerOffsetWidth + 'px');
							}
						}
					
						// If it's a landing page, set the (1)
						if (landingPage) {
							if (contentWidth < scrollPanelParentInnerWidth) {
								var landingOffsetWidth = menuWidth - imageOffset;
								var gapWidth = scrollPanelParentInnerWidth - contentWidth;
								// if the window is wider than viewable content, remove scrollbar
								if ((scrollPanelParentInnerWidth - menuWidth) > (contentWidth- imageOffset)){
									if (scrollbarAdded) {
										scrollbar.remove();
										scrollbarAdded = false;
									}
								}
								target_x=0;
								scrollPanel.css('left', menuWidth +'px');
							} else {
								var landingOffsetWidth = imageOffset - menuWidth;
								target_x=0;
								scrollPanel.css('left', menuWidth + 'px');
							}
						}		
						
						else { 
							target_x = 0;
							scrollPanel.css('left', menuWidth + 'px');
						}	
					}	
					setScrollHandlePos();
					
				} else {
					
					//Position the content to the left of the menu as no scroll bars are used
					scrollPanel.css('left', menuWidth + 'px');
					
					//Remove the scrollbar if required
					if (scrollbarAdded) {
						scrollbar.remove();
						scrollbarAdded = false;
					}
									
				}
			}
			
			//Add the required CSS class
			scrollPanel.addClass(additionalCssClass);
			
			// If it's FAQ page, calculate contentWidth of faqItem
			if($('.faqItem').length > 0){
				contentWidth = $(".faqItem", scrollPanel).length * itemWidth;
			} // otherwise, it's a product page. Landing page check is above (1).
			else{
				contentWidth = $(".productView", scrollPanel).length * itemWidth;
			}
			
			if ($(".content.productsLanding").length > 0) {
			    contentWidth = itemWidth;
			}

			scrollPanel.css('width', contentWidth + 'px');
			
			//Adjust the width if required (for some reason on first load the above code doesn't always work - i.e. image widths report as 0)
			// var childrenImages = scrollPanel.children("img").length;
			// if (contentWidth < itemWidth * childrenImages) contentWidth = itemWidth * childrenImages;
			
			//Add the scrollbar
			addOrRemoveScrollbar();
			
			//Bind the resize event of the browser to the add or remove scrollbar function
			$(window).resize(function() {
				addOrRemoveScrollbar();
			});
			
		});
	}
});