$(document).ready(function(){
			var $doc = $(document);
			var $win = $(window);
			var isTouch = 'ontouchstart' in window;


			// dimensions
			var windowHeight, windowWidth;
			var fullHeight, scrollHeight;
			var bgImgWidth = 1024, bgImgHeight = 576;
			calculateDimensions();

			// states
			var currentPosition = getScrollTop() / scrollHeight;
			var targetPosition = currentPosition;

			// collect timeline elements
			var $videoImage = $('.shopimg > img');
			var $allNavAnchors = $('#main .navigation a');

			var $timeElements = $('[data]');
			var timeElements = [];
			var hotspots = {};
			$timeElements.each(function(){
				var $view = $(this);
				var id = $view.attr('id');
				var elem = new TimeElement(this);
				timeElements.push( elem );
				if ( id ) hotspots[id] = elem;
				var offset = $view.offset();
				$view.css({position: 'fixed' , top: offset.top });
			});


			function setScrollTop(value) {
				$win.scrollTop(value);
			}
			
			function getScrollTop() {
				return $win.scrollTop() || (document.documentElement && document.documentElement.scrollTop);
			}
			
			function calculateDimensions() {
				windowWidth = $win.width();
				windowHeight = $win.height();
				fullHeight = $('#main').height();
				scrollHeight = fullHeight - windowHeight;
			}
			function setTargetPosition( position , immediate ) {
				targetPosition = position;
				if ( immediate ) currentPosition = targetPosition;
			}
			function handleResize() {
				calculateDimensions();
				renderBackgroundImage();
				renderTimeline( currentPosition );
				handleScroll();
			}
			function handleScroll() {
				setTargetPosition( getScrollTop() / scrollHeight );
				activateElement( $('.navigation') , targetPosition < 0.001 );
				
				}




			// rendering

			var scrollActivateTimeout;

			function renderTimeline( position ) {
				var minY = -500, maxY = windowHeight + 500;
				// element position
				$.each(timeElements,function(index,element){
					var elemPosition = element.getPosition();
					var elemY = windowHeight/2 + element.speed * (elemPosition-position) * scrollHeight;
					var active = false;
					if ( elemY < minY || elemY > maxY ) {
						element.view.css({'visiblity':'none', top: '-1000px','webkitTransform':'none'});
					} else {
						element.view.css('visiblity','visible');
						positionElement(element.view,null,elemY);
						active = Math.abs(windowHeight/2 - elemY) < Math.max(windowHeight/5,100);
					}
					
					if ( getElementActive(element.view) != active ) {
						clearTimeout( element.scrollActivateTimeout );
						setElementActive(element.view,active);
						function doit() {
							activateElement( element.view , active );
						}
						if ( active ) {
							element.scrollActivateTimeout = setTimeout( doit , 1000 );
						} else {
							doit();
						}
						activateElement( element.anchor , active );
					}
				});

				// video
				showImage( currentPosition );
			}

			

			function positionElement( elem , x , y ) {
				if ( $.browser.safari && !isTouch ) {
					var xpos = ( x === null ? $.data(elem,'x') : x ) || 0;
					var ypos = ( y === null ? $.data(elem,'y') : y ) || 0;
					$.data(elem,'x',xpos);
					$.data(elem,'y',ypos);
					elem.css({top:-1000,webkitTransform:'translate3d('+(xpos)+'px,'+(ypos+1000)+'px,0px)'});
				} else {
					if ( x !== null ) {
						elem.css('left',x);
					}
					if ( y !== null ) {
						elem.css('top',y);
					}
				}
			}
			function activateElement( elem , active ) {
				$.data( elem , 'active' , active );
				active ? elem.addClass('active') : elem.removeClass('active');
			}
			function setElementActive( elem , active ) {
				$.data( elem , 'active' , active );
			}
			function getElementActive( elem ) {
				return $.data( elem , 'active' );
			}

			function renderBackgroundImage(){
				// get image container size
				var scale = Math.max( windowHeight/bgImgHeight , windowWidth/bgImgWidth );
				var width = scale * bgImgWidth , height = scale * bgImgHeight;
				var left = (windowWidth-width)/2, top = (windowHeight-height)/2;
				$videoImage
						  .width(width).height(height)
						  .css('position','fixed')
						  .css('left',left+'px')
						  .css('top',top+'px');
			}


			// main render loop
			window.requestAnimFrame = (function(){
			  return  window.requestAnimationFrame       ||
			          window.webkitRequestAnimationFrame ||
			          window.mozRequestAnimationFrame    ||
			          window.oRequestAnimationFrame      ||
			          window.msRequestAnimationFrame     ||
			          function(/* function */ callback, /* DOMElement */ element){
			            window.setTimeout(callback, 1000 / 60);
			          };
			})();


			function animloop(){
				if ( Math.floor(currentPosition*5000) != Math.floor(targetPosition*5000) ) {
					var deaccelerate = Math.max( Math.min( Math.abs(targetPosition-currentPosition)*5000 , 10 ) , 2 );
					currentPosition += (targetPosition - currentPosition) / deaccelerate;
					renderTimeline(currentPosition);
				}
			  requestAnimFrame(animloop);
			}
			animloop();




			// video handling

			var imageSeqLoader = new ProgressiveImageSequence( "v/xs/code7_{index}.jpg" , 1355 , {
				indexSize: 4,
				onProgress: handleLoadProgress,
				onComplete: handleLoadComplete,
				stopAt: isSlowBrowser() ? 8 : 1
			} );

			var loadCounterForIE = 0; // there seems to be a problem with ie calling the callback several times
			imageSeqLoader.loadPosition(currentPosition,function(){
				loadCounterForIE++;
				if ( loadCounterForIE == 1 ) {
					showImage(currentPosition);
					imageSeqLoader.load();
					imageSeqLoader.load();
					imageSeqLoader.load();
					imageSeqLoader.load();
				}
			});

			



			var currentSrc, currentIndex;
			var highresTimeout;

			function showImage(position) {
				var index = Math.round( currentPosition * (imageSeqLoader.length-1) );
				var img = imageSeqLoader.getNearest( index );
				var nearestIndex = imageSeqLoader.nearestIndex;
				if ( nearestIndex < 0 ) nearestIndex = 0;
				var $img = $(img);
				var src;
				if ( !!img ) {
					src = img.src;
					if ( src != currentSrc ) {
						$videoImage[0].src = src;
						currentSrc = src;
					}
				}
				clearTimeout(highresTimeout);
				highresTimeout = setTimeout(function(){
					if ( !!src ) {
						var highSrc = src.split('/xs/').join('/l/');
						loadHighres(highSrc);
					}
				},isSlowBrowser()?500:150);
			}

			

			var loadHighresCounter = 0;

			function loadHighres(src) {
				var videoImage = $videoImage[0];
				videoImage.src = src;
			}


			$('body').append('<div id="loading-bar" style="position:fixed; bottom:0; left:0; background-color: #DF0012; background-color: rgba(223,0,18,0.5); height: 1px;"></div>');
			function handleLoadProgress() {
				var progress = imageSeqLoader.getLoadProgress() * 100;
				$('#loading-bar').css({width:progress+'%',opacity:1});
			}

			function handleLoadComplete() {
				$('#loading-bar').css({width:'100%',opacity:0});
			}




			$win.resize( handleResize );
			$win.scroll( handleScroll );

			handleResize();





			function TimeElement( view , options ) {
				options = options || {};
				var $view = $(view);
				this.id = $view.attr('id');
				this.view = $view;
				this.anchor = $allNavAnchors.filter('[href="#'+$view.attr('id')+'"]');
				this.anchor = this.anchor.closest('li');
				this.getPosition =function() { return  options.Position || Number( $view.attr('data')/100 ) };
				this.speed = options.speed || Number( $view.attr('data-speed') ) || 1;
				this.align = options.align || $view.attr('data-align') || 'left';
			}


			function easeCos(t) {
				return Math.cos( (x*Math.PI+Math.PI)+1 ) / 2;
			}


			function isSlowBrowser() {
				return isTouch || ($.browser.msie && Number($.browser.version) <= 8) ? true : false;
			}




			// touch override

			if ( isTouch ) {

				(function(){

					$('#main').css('height',1);

					var scrollPos = 0;
					var MAXSCROLL = 10000;

					var oldCalculateDimensions = calculateDimensions;
					calculateDimensions = function() {
						oldCalculateDimensions();
						scrollHeight = MAXSCROLL;
					};

					var oldGetScrollTop = getScrollTop;
					getScrollTop = function() {
						return scrollPos;
					};

					var oldSetScrollTop = setScrollTop;
					setScrollTop = function(value) {
						scrollPos = value;
						dispatchScroll();
					};

					function dispatchScroll() {
						targetPosition = scrollPos / MAXSCROLL;
					}

					var d = document;
					var touchMoved, touchDown, touchBeginPosition;

					function onTouchStart(event) {
						event.preventDefault();
						touchDown = true;
						var touch = event.touches[0];
						touchX = touch.clientX;
						touchY = touch.clientY;
						touchBeginPosition = { x: touchX , y: touchY , scroll: scrollPos };
						d.addEventListener('touchmove', onTouchMove, false);
						d.addEventListener('touchend', onTouchEnd, false);
					}
					function onTouchMove(event) {
					    event.preventDefault();
					    touchMoved = true;
						var touch = event.touches[0];
						touchX = touch.clientX;
						touchY = touch.clientY;
						scrollPos = touchBeginPosition.scroll - (touchY-touchBeginPosition.y) * 2;
						scrollPos = Math.min( MAXSCROLL , Math.max( 0 , scrollPos ) );
						dispatchScroll();
					}
					function onTouchEnd(event) {
						if ( touchMoved ) {
							event.preventDefault();
						}

						d.removeEventListener('touchmove', onTouchMove, false);
						d.removeEventListener('touchend', onTouchEnd, false);
						touchDown = false;
					}

					d.getElementsByClassName('shopimg')[0].addEventListener('touchstart', onTouchStart, false);
				})();

			}

		});

