$( document ).ready( function() {
	$( "body" ).append( 
		'<div id="blockerFilm"></div>' +
		'<div id="large" style="display: none;"></div>' +
		'<div id="close_me" style="display: none;">click <b>anywhere</b> on the page to <b>close</b></div>'
	 );
	(function() {
		var pgWidth = 0;
		var pgHeight = 0;
		var viewWidth = 0;
		var viewHeight = 0;
		var scrollLeft = 0;
		var scrollTop = 0;
		var xScroll = 0;
		var yScroll = 0;
		var large_div = $( '#large' );
		var film = $( '#blockerFilm' );
		var film_start_opacity = 0;
		var film_end_opacity = 75;
		var transition_ms = 300;
		var transition_start = null;
		var scale; // transition scalar
		var scalePosition;
		var scaleSize;
		var replace_large;
		var close_film = true; // should clicking on the film close it?
		var Ctx, Cty, Clx, Cly;  // center thumbnail x, center thumbnail y, center large x, center large y
		var Tdx, Tdy; // thumb width and height
		var Ldx, Ldy; // large width and height
		var Cdx, Cdy; // differences between the center of the thumb and the center of the large image
		var large_image = null;
		var thumb_image = null;
		var img_transition_top = 0;
		var img_transition_left = 0;
		var delayed_close = false;  // if they click on the large_div before the transition is complete close when it's done
		var in_transition = false;
		var reload_image = false;
		var last_step = 0;
		var large_images = [];  // contains the large images once they are loaded
		film.hide();
		window.Viewer = {};
		function prepare_transition( e )
		{
			var position = $( e.target ).position();
			
			large_div.css('top', position.top + 'px').css( 'left', position.left + 'px' ).show();

			Tdx = thumb_image.width;
			Tdy = thumb_image.height;
			// get the center of the thumbnail ( Ct ) and the center of the large ( Cl )
			getPageDimensions();
			Clx = parseInt( viewWidth / 2 ) + scrollLeft;
			Cly = parseInt( viewHeight / 2 ) + scrollTop;
			Ctx = parseInt( position.left + Tdx / 2 );
			Cty = parseInt( position.top + Tdy / 2 );
			// center deltas
			Cdx = Clx - Ctx;
			Cdy = Cly - Cty;
/*/
			var large_info = e.target.parentNode.rel.split( '|' );
			Ldx = large_info[1];
			Ldy = large_info[2];
/**/
			var maxLen = 600;
			if( Tdx > Tdy ) {
				var perc = Tdy / Tdx;
				Ldx = maxLen;
				Ldy = Math.floor( maxLen * perc );
			} else if( Tdy > Tdx ) {
				var perc = Tdx / Tdy;
				Ldy = maxLen;
				Ldx = Math.floor( maxLen * perc );
			} else {
				Ldx = maxLen;
				Ldy = maxLen;
			}
			set_film_opacity( film_end_opacity );
			replace_large = true;
			close_film = true;
		}

		function load_large_image( href )
		{
			if( large_images[href] ) {
				large_image = large_images[href];
			} else {
				large_image = new Image();
				large_image.src = href;
				if( large_image.complete ) {
					large_images[href] = large_image;
				} else {
					$( large_image ).bind( 'load', replace_with_large );
				}
			}
			return large_images[href] ? large_image : null;
		}
		window.load_large_image = load_large_image;
		function display_photo( e, mode )
		{
			if( in_transition )
				return;

			displayMode		= mode;
			in_transition	= true;
			// starting film settings
			film.show();

			set_film_opacity( film_start_opacity );
			redraw();
			thumb_image = new Image();
			with( thumb_image ) {
				src = e.target.src;
				style.position = 'absolute';
			}

			switch( displayMode ) {
				case "panel":
					$( large_div ).prepend( '<iframe src="' + e.target.parentNode.href + '" scrolling="no" frameborder="0"></iframe>' );
				break;
				default:
					var which_image = load_large_image( e.target.parentNode.href );
					if( !which_image ) which_image = thumb_image;
					$( large_div ).prepend( which_image );
				break;
			}

			$( large_div ).show();

			large_div.show();
			prepare_transition( e );
			transition_start = new Date();
			transition();
		}

		function set_film_opacity( o )
		{
			film.css('opacity', o / 100).css('filter', 'alpha( opacity='+o+' )' );
		}

		function redraw( no_resize )
		{
			if( !no_resize )
				getPageDimensions();
		}
		window.Viewer.redraw = redraw;
		function getPageDimensions()
		{
			var IEBody = document.compatMode && document.compatMode != "BackCompat" ? document.documentElement : document.body;
			if( window.innerWidth && window.scrollMaxX ) {
				xScroll = window.innerWidth + window.scrollMaxX;
				yScroll = window.innerHeight + window.scrollMaxY;
			} else {
				xScroll = Math.max( document.body.scrollWidth, document.body.offsetWidth );
				yScroll = Math.max( document.body.scrollHeight, document.body.offsetHeight );
			}
			if( document.all && !window.opera ) {
				// IE
				viewHeight	= IEBody.clientHeight;
				viewWidth	= IEBody.clientWidth;
				pgHeight	= Math.max( IEBody.scrollHeight, IEBody.clientHeight );
				pgWidth		= IEBody.scrollWidth;
				scrollLeft	= IEBody.scrollLeft;
				scrollTop	= IEBody.scrollTop;
			} else {
				// DOM
				pgHeight	= document.documentElement.clientHeight || self.innerHeight;
				viewWidth	= pgWidth = document.documentElement.clientWidth || self.innerWidth;
				viewHeight	= self.innerHeight;
				scrollLeft	= window.scrollX;
				scrollTop	= window.scrollY;
			}
			pgWidth		= Math.max( pgWidth, xScroll );
			pgHeight	= Math.max( pgHeight, yScroll );
			pgHeight	= viewHeight + scrollTop;
			// doesn't work in strict mode
			//pgHeight = document.body.scrollHeight?document.body.scrollHeight:document.body.offsetHeight;
			//pgWidth = document.body.scrollWidth?document.body.scrollWidth:document.body.offsetWidth;
		}

		function calc_scale( t, b, c, d )
		{
			// linear
			//return c*t/d + b;
			// quadratic ease in out
			t /= d/2;
			if( t<1 ) return c/2*t*t + b;
			t--;
			return -c/2 * ( t*( t-2 )-1 )+b;
			// quintic ease in/out
			// t /= d/2;
			// if( t<1 ) return c/2*t*t + b;
			// t -= 2;
			// return c/2*( t*t*t + 2 ) + b;
			// quintic ease in
			//t /= d;
			//return c*t*t*t*t*t + b;
			// quintic ease out
			// t /= d;
			// t--;
			// return c*( t*t*t + 1 ) + b;
			// sinusoidal ease in/out
			//return -c/2 * ( Math.cos( Math.PI*t/d )-1 )+b;
		}

		function transition()
		{
			if( !in_transition ) return;
			var elapsed;
			var d_opacity = film_end_opacity - film_start_opacity;
			elapsed = new Date() - transition_start;
			// don't do anything if we go over the transition time
			if( elapsed <= transition_ms ) {
				scaleSize = calc_scale( elapsed, 0, Ldy, transition_ms );
				scaleSize /= Ldy;
				scalePosition = calc_scale( elapsed, 0, 1, transition_ms );
				transition_step( scalePosition, scalePosition );
				setTimeout( 'Viewer.transition()', 1 );
			} else {
				transition_end();
			}
		}
		window.Viewer.transition = transition;
		function transition_step( scaleSize, scalePosition )
		{
			if( !in_transition ) return;
			if( last_step > scale ) return;
			var dx = Cdx * scalePosition;
			var dy = Cdy * scalePosition;
			var temp_dx = parseInt( Ldx * scaleSize );
			var temp_dy = parseInt( Ldy * scaleSize );
			// don't start any smaller than the thumbnail
			temp_dx = temp_dx < Tdx ? Tdx : temp_dx;
			temp_dy = temp_dy < Tdy ? Tdy : temp_dy;
			var temp_Cx = parseInt( Ctx + dx - temp_dx/2 );
			var temp_Cy = parseInt( Cty + dy - temp_dy/2 );
			// make sure the top of the image doesn't go negative
			if( temp_Cy<2 ) temp_Cy = 2;
			if( temp_Cx<2 ) temp_Cx = 2;
			var img = $( '#large > img:first' );
			if( img[0] ) {
				with( img[0].style) {
					width	= temp_dx + "px";
					height	= temp_dy + "px";
				}
			}
			with( large_div[0].style ) {
				left	= temp_Cx + "px";
				top		= temp_Cy + "px";
			}
			redraw();
			last_step = scale;
		}

		function transition_end()
		{
			transition_step( 1, 1 );

			if( delayed_close )
				transition_back();

			switch( displayMode ) {
				case "img":
					large_images[large_image.src] = large_image;
					in_transition = false;
					$( '#large > :first-child' ).css( 'padding', 0 ).css( 'margin', 0 );
					var nav_div = document.createElement( 'div' );
					var dx = Cdx * scalePosition;
					var dy = Cdy * scalePosition;
					var temp_dx = parseInt( Ldx*scaleSize );
					var temp_dy = parseInt( Ldy*scaleSize );
					// don't start any smaller than the thumbnail
					temp_dx = temp_dx < Tdx ? Tdx : temp_dx;
					temp_dy = temp_dy < Tdy ? Tdy : temp_dy;
					var temp_Cx = parseInt( Ctx + dx - temp_dx / 2 );
					var temp_Cy = parseInt( Cty + dy - temp_dy / 2 );
					large_div.addClass('end');
					with( large_div[0].style ) {
						width	= parseInt( Ldx ) + 4 + "px";
						height	= parseInt( Ldy ) + 34 +  "px";
					}
				break;
				case "panel":
				break;
			}

			var d = document.createElement( 'div' );
			d.innerHTML = '<center style="padding-bottom: 9px">click <b>anywhere</b> on the page to <b>close</b></center>';
			large_div.append( d );
			var a = $( '#close_me' )[0].style;
			a.left = parseInt( Clx - Ldx/2 +2 ) + 'px';
			var _top = parseInt( Cly - Ldy/2 ) + 2;
			a._top = _top < scrollTop + 2 ? scrollTop + 2 : _top;
			a.top = _top + 'px';
			a.width = Ldx-8+'px';

			setTimeout( "$( '#close_me' ).hide();", 1200 );
			if( window.photoZoomEnd ) {
				window.photoZoomEnd();
			}
		}
		window.Viewer.transition_end = transition_end;
		function replace_with_large()
		{
			//replace_large = in_transition;;
			if( replace_large ) {
				$( thumb_image ).replaceWith( large_image );
				transition();
				if( !in_transition ) {
					scaleSize = scalePosition = 1;
				}
				replace_large = false;
			} else {
				large_images[large_image.src] = large_image;
				replace_large = true;
			}
		}

		function transition_back( e )
		{
			if( !close_film ) return;
			set_film_opacity( film_start_opacity );
			film.hide();
			large_div.hide();

			$( '#large' ).text( "" );

			large_div.removeClass('end');

			in_transition = false;
			replace_large = false;
			last_step = 0;
			large_div.html( "" );
			$( '#close_me' ).hide();
			if( window.photoZoomClose ) {
				window.photoZoomClose( e.target );
			}
		}
		window.transition_back = transition_back;
		film.bind( 'click', transition_back );
		large_div.bind( 'click', transition_back );
		$( 'div#photoThumbs a' ).bind( 'click', function( e ) {
			$( this ).find( 'img' ).bind( 'click',function( e ) {
				$( e ).stop();
				display_photo( e, this.parentNode.rel.split( "\n" )[0] );
				window.photoZoomCurImg = e.target;
			});
			$( e ).stop();
			return false;
		});
		$( '#close_me' ).bind( 'click', transition_back );
		window.onresize = function( e ) { setTimeout( 'Viewer.redraw()', 50 )};
		window.onscroll = function( e ) { setTimeout( 'Viewer.redraw()', 50 )};
	})();
});

