( function ( ) {

	CES ( {
		"div#content ul.thumbs li a" : {
			"click" : function ( e ) {
				var page = getPageId ( this.href );
				showPage ( page );
				this.blur();
				return false;
			}
		},
		"window" : {
			"keypress" : function ( e ) {
				if ( ( e.keyCode == 37 ) || ( e.keyCode == 39 ) ) {
					switchPage ( e.keyCode - 38 );
					return false;
				}
			}
		}
	} );

	var currentPage = null;
	var pages = {};
	var showControls = true;

	var previous = StS.utils.DOM.create ( "a", {
		'class' : "previous",
		href : "#previous",
		innerHTML : "<span>Previous Page</span>",
		title : "Previous Page",
		onclick : function ( ) { switchPage ( -1 ); this.blur(); return false; }
	} );
	var next = StS.utils.DOM.create ( "a", {
		'class' : "next",
		href : "#next",
		innerHTML : "<span>Next Page</span>",
		title : "Next Page",
		onclick : function ( ) { switchPage ( 1 ); this.blur(); return false; }
	} );

	var frame;

	function checkSwitchHandles ( ) {
		StS.utils.DOM[(currentPage==0?"add":"remove")+"Class"](previous,"disabled");
		previous.title = ( currentPage == 0 ) ? "" : "Previous Page";
		StS.utils.DOM[(currentPage==10?"add":"remove")+"Class"](next,"disabled");
		next.title = ( currentPage == 10 ) ? "" : "Next Page";
	}

	function switchPage ( dir ) {
		var dir = parseInt ( dir ) / Math.abs ( parseInt ( dir ) );
		if ( isNaN ( dir ) || dir == 0 ) return;
		var page = currentPage + dir;
		if ( isNaN ( page ) || ( page < 0 ) || ( page > 10 ) ) return;
		showPage ( page );
	}

	function fetchPage ( pageId, cb, maxTime ) {
		if ( pageId > 10 ) return;

		var timer = ( function ( ) {
			if ( isNaN ( parseFloat ( maxTime ) ) )
				return null;
			return setTimeout ( function ( ) {
				_cb();
			}, parseFloat ( maxTime ) * 1000 );
		} )();

		var _cb = function ( ) {
			clearTimeout ( timer );
			if ( typeof cb == "function" ) cb ( pageId );
		}

		var imgSrc = createPageLocation(pageId);
		if ( pages[imgSrc] ) {
			_cb();
		} else {
			var container = (CES.find("div#content ul.pages" ))[0];
			StS.utils.DOM.addClass ( container, "loading" );
			var page = StS.utils.DOM.create ( "li", {
				parent : container
			} );
			var img = StS.utils.DOM.create ( "img", {
				parent : page,
				onload : function ( ) {
					_cb();
				},
				src : imgSrc
			} );
			/*
			var caption = StS.utils.DOM.create ( "p", {
				parent : page,
				innerHTML : getCaption ( pageId, "&nbsp;" )
			} );
			*/
			if ( showControls ) {
				var zoom = StS.utils.DOM.create ( "a", {
					parent : page,
					'class' : "zoom",
					target : "_blank",
					href : createPageLocation(pageId,true),
					title : "Get the large version of this page",
					innerHTML : "Get the large version of this page"
				} );
			}
			pages[imgSrc] = page;
		}
	}
	
	function preloadPages ( ) {
		var nodes = CES.find ( "div#content ul.thumbs li a" );
		var f = function ( id ) {
			fetchPage ( id, function ( id ) {
				f ( id + 1 )
			} )
		}
		f ( 0 );
	}

	var getTween = ( function ( ) {
		var f = function ( step, begin, delta, steps ) {
			return f['default'] ( step, begin, delta, steps );
		}
		f['default'] = function ( step, begin, delta, steps ) {
			if ( ( step /= steps / 2 ) < 1 ) 
				return delta / 2 * Math.pow ( step, 3 ) + begin; 
			return delta / 2 * ( Math.pow ( step - 2, 3 ) + 2 ) + begin;
		}
		f['slide'] = function ( step, begin, delta, steps ) {
			return delta / 2 * ( 1 - Math.cos ( Math.PI * step / steps ) ) + begin;
		}
		return f;
	} )();

	function fadeTo ( elem, to, cb ) {
		clearTimeout ( elem._fader_ );
		var initialOpacity = ( elem.opacity === undefined ) ? 100 : elem.opacity;
		var steps = 20;
		var diff = to - initialOpacity;
		var f = function ( step ) {
			StS.utils.DOM.setOpacity ( elem, getTween ( step, initialOpacity, diff, steps ) );
			if ( step < steps ) {
				elem._fader_ = setTimeout ( function ( ) {
					f ( step + 1 );
				}, 5 );
			} else {
				if ( typeof cb == "function" )
					cb(elem);
			}
		}
		f ( 0 );
	}

	function slideFrameTo ( thumb, cb ) {
		clearTimeout ( frame._slider_ );
		var pos = thumb.offsetLeft;
		var initial = frame.offsetLeft;
		var steps = 10;
		var diff = pos - initial;
		var f = function ( step ) {
			frame.style.left = getTween.slide ( step, initial, diff, steps ) + "px";
			if ( step < steps ) {
				frame._slider_ = setTimeout ( function ( ) {
					f ( step + 1 );
				}, 1 )
			} else {
				if ( typeof cb == "function" ) cb();
			}
		}
		f ( 0 );
	}

	function getPageId ( str ) {
		return parseInt ( ( str.toString().match(/page0*(\d+)/) || [] )[1] || 0 );
	}

	function createPageLocation ( pageId, large ) {
		var type = ( large ? "full" : "med" );
		return "http://wetellstories.co.uk/public/week5/" + type + "/" + (""+pageId).lpad(2,"0") + "_" + type + ".jpg";
	}

	function showPage ( pageId ) {
		if ( pageId == currentPage ) return;
		
		var nodes = CES.find ( "div#content ul.thumbs li" );
		var currentThumb = null;
		frame.style.display = "block";
		for ( var i = 0; i < nodes.length; i ++ ) {
			var selected = ( i == pageId );
			if ( selected ) {
				currentThumb = nodes[i];
			} else {
				StS.utils.DOM.removeClass ( nodes[i], "selected" );
			}
		}
		var location = ( pageId == 0 ) ? "#cover" : "#page" + (""+pageId).lpad(2,"0");
		window.location = location;
		var curPage = pages[createPageLocation(currentPage)];
		
		for ( p in pages ) {
			pages[p].style.zIndex = ( curPage.style.zIndex || 100 ) - 1;
		}
		
		( function ( fn ) {
			if ( basicMode ) {
				fn()
			} else {
				fadeTo ( curPage, 0, fn );
			}
		} )( function ( ) {
			StS.utils.DOM.removeClass ( curPage, "current" );
		} );
		fetchPage ( pageId, function ( id ) {
			slideFrameTo ( currentThumb, function ( ) {
				frame.style.display = "none";
				StS.utils.DOM.addClass ( currentThumb, "selected" );
			} );
			var page = pages[createPageLocation(id)];
			page.style.zIndex = 100;
			StS.utils.DOM.addClass ( page, "current" );
			( function ( fn ) {
				if ( basicMode ) {
					fn()
				} else {
					StS.utils.DOM.setOpacity ( page, 0 );
					fadeTo ( page, 100, fn );
				}
			} )( function ( ) {
				StS.utils.DOM.removeClass ( (CES.find("div#content ul.pages" ))[0], "loading" );
				if ( showControls ) {
					page.appendChild ( previous );
					page.appendChild ( next );
				}
			} );
			page.style.display = "none";
			page.style.display = "block";
		}, 5 );
		currentPage = pageId;
		checkSwitchHandles();
		
		currentHash = location;
	}

	var currentHash = window.location.hash || "#cover";

	document.whenReady ( function ( ) {
		showControls = !!(CES.find("div#content a.zoom"))[0];

		frame = StS.utils.DOM.create ( "div", {
			id : "frame",
			parent : (CES.find("div#content ul.thumbs"))[0].parentNode
		} );
		frame.parentNode.style.position = "relative";
		var img = CES.find ( "div#content img.main" )[0];
		pages[img.src] = img.parentNode;
		//preloadPages();
		var page = getPageId ( window.location.hash );
		currentPage = getPageId ( window.location.pathname );
		if ( window.location.hash.length && ( page != currentPage ) ) {
			showPage ( page );
		} else {
			currentHash = ( currentPage == 0 ? "#cover" : "#page" + (""+currentPage).lpad(2,"0") );
			StS.utils.DOM.addClass ( img.parentNode, "current" );
			if ( showControls ) {
				img.parentNode.appendChild ( previous );
				img.parentNode.appendChild ( next );
			}
			checkSwitchHandles();
			if ( window.location.hash != currentHash ) {
				window.location.replace ( currentHash );
			}
		}
		
		setInterval ( function ( ) {
			var newHash = document.location.hash || "#cover";
			if ( newHash != currentHash ) {
				currentHash = newHash;
				showPage ( getPageId ( currentHash ) );
			}
		}, 500 );
	} );
	
} )()