//////////////////////////////////////// START THUMBNAILS: TN ///////////////////////////////////////

function ThumbNails() {

	// Preload graphical controls
	var arrowLeftSsTnOn = new Image(); arrowLeftSsTnOn.src = "images/arrowLeftSsTnOn.gif";
	var arrowRightSsTnOn = new Image(); arrowRightSsTnOn.src = "images/arrowRightSsTnOn.gif";

	initImagesArr();

	this.ImagesOriginal = Images;
	this.folderOriginal = Settings.folder;
	this.defaultCaption = Settings.defaultCaption;

	this.nImages = Images.length;
	this.maxIndex = this.nImages - 1;

	// Methods
	this.initTN = initTN;
	this.checkTnDim = checkTnDim;
	this.dissolve = true;
	this.showDownloadProgress = showDownloadProgress;
	this.getCount = getCount;
	this.getNewIndex = getNewIndex;
	this.nextImage = nextImage;
	this.preloadNext = preloadNext;
	this.enlarge = enlarge;
	this.imgBorder = imgBorder;
	this.kill = kill;
	this.showNumImages = showNumImages;
	this.writeConsole = writeConsole;
	this.updateProgressBar = updateProgressBar;
	this.reportImgName = reportImgName;
	this.writeThumbnails = writeThumbnails;
	this.setEnlargementProperties = setEnlargementProperties;

	// Variables
	this.NextLgImage = null;
	this.OldImage = null;
	this.nextImgTimer = 0;
	this.progressBarTimer = 0;
	this.curIndex = -1;
	this.tnRemainingTN = 0;
	this.TheBody = null;
	this.TopImage = null;

	//------------------------------------- METHOD TN -------------------------------------
	// Called onLoad of TN page

	function initTN() {
		this.showNumImages();
		this.checkTnDim();
	}
	//------------------------------------- METHOD TN -------------------------------------
	// Returns newIndex: This next image value is based on value of global TN.curIndex
	function getNewIndex( movingForward ) {

		if( movingForward )
			return ( this.curIndex < this.maxIndex ) ? this.curIndex + 1 : 0;
		else
			return ( this.curIndex > 0 ) ? this.curIndex - 1 : this.maxIndex;

	}

	//------------------------------------- METHOD TN -------------------------------------
	// Called onLoad of large Image

	function preloadNext() {
		var newIndex = this.getNewIndex( 1 );
		var PreLoadImage = new Image();
		PreLoadImage.src = Settings.folder + Images[ newIndex ][ 0 ];
		var nOldImg = ( newIndex == 0 ) ? Images.length - 1 : newIndex - 1;
		this.OldImage = new Image();
		this.OldImage.src = Settings.folder + Images[ nOldImg ][ 0 ];
	}

	//------------------------------------- METHOD TN -------------------------------------
	function imgBorder( Img, color ) { if( Img.complete ) Img.style.borderColor = color; }

	//------------------------------------- METHOD TN -------------------------------------
	// Called onLoad of TN page by TN.initTN

	function showNumImages() {
		if( this.nImages > -1 ) {
			if( Settings.TN.ProgressBar.hideOnSuccess )
				document.getElementById( "consoleTN" ).style.visibility = "hidden";
		}
	}
	//------------------------------------- METHOD TN -------------------------------------

	function writeConsole() {
		document.write( "<div id='consoleTN' style='line-height:14px;' align='" + Settings.TN.align + "'><div>&nbsp; </div><br/></div>" );
	}
	//------------------------------------- METHOD TN -------------------------------------


	function updateProgressBar() {

		var Console = document.getElementById( "consoleTN" );

		try {
			if( this.tnRemainingTN >= 0 ) {
				var dBarWid = ( this.nImages - this.tnRemainingTN ) * ( Settings.TN.ProgressBar.width / this.nImages );
				var percentLoaded = parseInt( ( ( this.nImages - this.tnRemainingTN ) / this.nImages ) * 100 );

				if( !Settings.TN.ProgressBar.hideOnSuccess ) {
					dBarWid = this.nImages / 2 * ( Settings.TN.ProgressBar.width / this.nImages );
					percentLoaded = 50;
				}

				var Pbar = new Array( 21 );
				Pbar.push( "<div style='width:" );
				Pbar.push( Settings.TN.ProgressBar.width );
				Pbar.push( "px; background-color:" );
				Pbar.push( Settings.TN.ProgressBar.bgColor );
				Pbar.push( "; text-align:left; z-index:0;'>" );
				Pbar.push( "<div style='width:" );
				Pbar.push( dBarWid );
				Pbar.push( "px; background-color:" );
				Pbar.push( Settings.TN.ProgressBar.progressColor );
				Pbar.push( ";'>" );
				Pbar.push( "&nbsp;" );
				Pbar.push( "</div>" );
				Pbar.push( "</div>" );
				Pbar.push( "<div style='position:relative; top:-14px; left:0px; width:" );
				Pbar.push( Settings.TN.ProgressBar.width );
				Pbar.push( "px; text-align:center; z-index:1; font-family:arial,helvetica; font-size:8pt; color:" );
				Pbar.push( Settings.TN.ProgressBar.fontColor );
				Pbar.push( "; font-weight:bold;'>" );
				Pbar.push( percentLoaded );
				Pbar.push( "%" );
				Pbar.push( "</div>" );
				Console.innerHTML = Pbar.join( "" );
				if( !Settings.TN.ProgressBar.hideOnSuccess )
					clearTimeout( TN.progressBarTimer );
				else if( this.tnRemainingTN > 0 ) TN.progressBarTimer = setTimeout( "TN.updateProgressBar()", 200 );
				else if( Settings.TN.ProgressBar.hideOnSuccess ) Console.style.visibility = "hidden";
			}
		}
		catch( Err ) {
			TN.progressBarTimer = setTimeout( "TN.updateProgressBar()", 250 );
		}
	}

	//------------------------------------- METHOD TN -------------------------------------
	// Returns photo-caption as a string (ex: 2/24)

	function getCount( newIndex ) { return ( newIndex + 1 ) + "/" + ( this.maxIndex + 1 ); }

	//------------------------------------ METHOD TN ------------------------------------

	function kill() {
		this.NextLgImage = null;
		clearInterval( this.nextImgTimer );
		this.nextImgTimer = 0;
		if( this.TopImage ) {
			document.body.removeChild( this.TopImage );
			this.TopImage = null;
		}
	}

	//------------------------------------- METHOD TN -------------------------------------
	// Called only when user clicks back "<<" & forward ">>" links on enlargement

	function nextImage( movingForward, evt ) {

		var ImageDW = document.getElementById( "ImageDW" );
		if( ImageDW ) {

			var newIndex = this.getNewIndex( movingForward );
			if( !this.NextLgImage ) {
				this.NextLgImage = new Image();
				this.NextLgImage.src = Settings.folder + Images[ newIndex ][ 0 ];
			}

			if( this.NextLgImage.complete && this.OldImage.complete ) {

				if( !evt ) evt = window.event;

				if( userWithWritePrivileges || ( evt && evt.shiftKey ) ) this.dissolve = false;

				if( !document.getElementById( "dwOverlay" ) )
					DW.addOverlay( 0, "TN" );

				ImageDW.onload = null;

				// Get dimensions of new images
				var imgWidNew = this.NextLgImage.width;
				var imgHgtNew = this.NextLgImage.height;

				// If image doesn't fit get new scaled down dimensions
				var WinDim = DW.getScaledSize( imgWidNew, imgHgtNew, Images[ newIndex ][ 1 ] );
				imgWidNew = WinDim[ 0 ];
				imgHgtNew = WinDim[ 1 ];

				// Create top div tag that will contain new image
				if( !TN.TopImage ) {
					TN.TopImage = document.createElement( "IMG" );
					TN.TopImage.id = "TopImage";
					TN.TopImage.style.top = ( imgHgtNew * -2 ) + "px";
					TN.TopImage.style.left = ( imgWidNew * -2 ) + "px";
					TN.TopImage.style.zIndex = 10001;
					TN.TopImage.style.position = "absolute";
					TN.TopImage.style.cursor = "pointer";
					TN.TopImage.oncontextmenu = function( event ) { return window.rightClickImg( this, event, this.width, this.height ); }
					TN.TopImage.onclick = function( event ) { TN.nextImage( 1, event ); this.title = ""; document.getElementById( "ImageDW" ).title = ""; }
					document.body.appendChild( TN.TopImage );
				}

				// Make top div transparent
				if( IE ) TN.TopImage.style.visibility = "hidden";
				else if( MZ ) TN.TopImage.style.opacity = 0;
				else TN.TopImage.style.opacity = 0;

				// Apply src & dimensions to top image
				TN.TopImage.src = this.NextLgImage.src;
				TN.TopImage.style.height = imgHgtNew + "px";
				TN.TopImage.style.width = imgWidNew + "px";

				// Top image is prepared and ready to be faded into view, so prep bottom image & DW...
				var Win = document.getElementById( "dWinID" );

				// Update title-bar
				document.getElementById( "SsTnCount" ).innerHTML = this.getCount( newIndex );
				document.getElementById( "SsTnTitle" ).innerHTML = Images[ newIndex ][ 1 ];

				var imgWidOld = this.OldImage.width;
				var imgHgtOld = this.OldImage.height;

				// Set styles & src of bottom DW & Image
				var marLeft = Math.round( ( imgWidNew - imgWidOld ) / 2 );
				var marTop = Math.round( ( imgHgtNew - imgHgtOld ) / 2 );
				ImageDW.parentNode.style.marginLeft = marLeft + "px";
				ImageDW.parentNode.style.marginTop = marTop + "px";
				ImageDW.parentNode.parentNode.style.overflow = "hidden";
				ImageDW.src = this.OldImage.src;
				ImageDW.style.width =  imgWidOld + "px";
				ImageDW.style.height = imgHgtOld + "px";

				// Set window size to match image size
				// Set height of div class="dwBodyParentImg" to that of its image
				ImageDW.parentNode.parentNode.style.height = imgHgtNew + "px";
				Win.style.width = imgWidNew + "px";

				// Re-center DW
				DW.reCenter( Win );

				// Move top div with image into position - place exactly above old image
				DW.moveTopImage();

				this.NextLgImage = null;
				clearInterval( this.nextImgTimer );
				this.nextImgTimer = 0;

				// curIndex is initially established onClick of any thumbnail, and then incremented/decremented here only
				// All other occurences of this variable are for "read-only" access to it's value
				this.curIndex = ( movingForward ) ? this.curIndex + 1 : this.curIndex - 1;
				if( this.curIndex > this.maxIndex )
					this.curIndex = 0;
				else if( this.curIndex < 0 )
					this.curIndex = this.maxIndex;

				this.preloadNext();

				if( this.dissolve )
					startFade( TN.TopImage, Settings.IeTransNum, Settings.transDur, 0 );
				else {
					if( IE ) TN.TopImage.style.visibility = "visible";
					else if( MZ ) TN.TopImage.style.opacity = 0.9999;
					else TN.TopImage.style.opacity = 0.9999;
					TN.TopImage.style.visibility = "visible";
				}
				this.dissolve = true;
			}
			else { // Next image still loading

				// If stmt prevents multiple threads running this method concurrently, which setInterval would allow
				if( this.nextImgTimer == 0 ) {
					eval( "this.nextImgTimer = setInterval( 'TN.nextImage( " + movingForward + " )', 250 );" ); // 250
					document.getElementById( "SsTnTitle" ).innerHTML = "Downloading Image<span id='dot1'>.</span><span id='dot2'>.</span><span id='dot3'>.</span><span id='dot4'>.</span>";
					this.showDownloadProgress();
				}
			}
		}
		else // Image not present, like when user closes photo, if thread is running this kills it
			this.kill();
	}

	//--------------------------------------------------------------------------------------
	// Called when user requests next image and it is still loading

	var nDotsVisible = 4;

	function showDownloadProgress() {

		var Dot1 = document.getElementById( "dot1" );
		var Dot2 = document.getElementById( "dot2" );
		var Dot3 = document.getElementById( "dot3" );
		var Dot4 = document.getElementById( "dot4" );

		// Make sure dots are visible, as they get replaced by caption when image loads
		if( Dot1 && Dot2 && Dot3 && Dot4 ) {

			for( var i = 1; i <= 4; i++ )
				document.getElementById( "dot" + i ).style.visibility = ( i <= nDotsVisible ) ?  "visible" : "hidden";

			nDotsVisible++;
			if( nDotsVisible == 5 ) nDotsVisible = 0;

			setTimeout( "TN.showDownloadProgress();", 500 );
		}
	}


	//--------------------------------------------------------------------------------------
	// Called when user clicks on thumbnail

	function enlarge( cap, imageNum ) {

		if( window.SS ) SS.kill();

		this.TheBody = ( document.compatMode && document.compatMode != "BackCompat" ) ? document.documentElement : document.body;

		// Images array could be referencing the wrong data. Happens if user plays a different SS while on this TN page
		// Closing SS sets window.Images to null and here's the chance to reset settings

		if( window.Images == null ) {
			window.Images = this.ImagesOriginal;
			Settings.folder = this.folderOriginal;
			Settings.defaultCaption = this.defaultCaption;
		}

		DW.photoCaption = Images[ imageNum ][ 1 ];
		DW.photoCount = TN.getCount( imageNum );

		DW.createEnlargement( "TN", Settings.folder + Images[ imageNum ][ 0 ] );

		return false;
	}
	//------------------------------------- METHOD TN -------------------------------------

	function writeThumbnails() {

		this.tnRemainingTN = this.nImages;

		var Htm = new Array();

		var tnNum = 0;

		thePageTitle = Settings.TN.pageTitle;
		thePageTitle = thePageTitle.replace( /\^\^/g, "&#39;" );
		thePageTitle = thePageTitle.replace( /\^/g, "&#34;" );

		if( thePageTitle ) {
			Htm.push( "<div class='tnTitle' align='center'>" );
			Htm.push( thePageTitle );
			Htm.push( "</div>" );
		}

		Htm.push( "<table align='center'>" );

		var nRows = Math.floor( this.nImages / Settings.TN.nImagesRow ) + 1;

		///////////////// START ROWS /////////////////
		for( var row = 0; row < nRows; row++ ) {

			Htm.push( "<tr align='" ); Htm.push( Settings.TN.align ); Htm.push( "' valign='middle'><td align='center' style='white-space:nowrap;'>" );
			Htm.push( "<table align='center'>" );
			Htm.push( "<tr>" );

			///////////////// START TNs /////////////////
			for( var i = 0; i < Settings.TN.nImagesRow; i++ ) {

				var thisTnImgData = '';
				var writeTN = ( tnNum < this.nImages ) ? true : false;

				if( writeTN ) {

					// Create tnImageName from large image name
					var lgImageName = Images[ tnNum ][ 0 ], tnImageName = "";
					lastDotPos = lgImageName.lastIndexOf( "." );
					var fileExt = "TN" + lgImageName.substring( lastDotPos, lgImageName.length );
					// If optional 2nd member dictating other TN to use is present then use that instead...
					tnImageName = ( Images[ tnNum ][ 2 ] ) ? Images[ tnNum ][ 2 ] : lgImageName.split( "." )[ 0 ] + fileExt;

					var imgTitle = Images[ tnNum ][ 1 ];

					// Remove HTML tags
					var toolTip = imgTitle.replace( /<.*?>/g, " " );

					var tn = Settings.folder + tnImageName;
					tnNum++;
				}

				var imageNum = row * Settings.TN.nImagesRow + i + 1;

				if( writeTN ) {

					var lgImgName = Images[ tnNum - 1 ][ 0 ];

					var toolTipColon = ( toolTip ) ? ": " : "";
					toolTip = imageNum + "/" + this.nImages + toolTipColon + toolTip;

					Htm.push( "<td class='" );
					var cls = ( fileName == "thumbnails.aspx" ) ? "tn" : "tnPage";
					Htm.push( cls );
					Htm.push( "'>" );
					Htm.push( "<a href='javascript:void(0);' title=\"" );
					Htm.push( toolTip );
					Htm.push( "\" onClick='if( window.DW ) { TN.curIndex = " );
					Htm.push( imageNum - 1 );
					Htm.push( "; this.blur(); return TN.enlarge( \"" );
					Htm.push( imgTitle );
					Htm.push( "\", " );
					Htm.push( imageNum - 1 );
					Htm.push( " ); }' onContextMenu='return TN.reportImgName( this, " );
					Htm.push( imageNum );
					Htm.push( ", event );'>" );

					Htm.push( "<img src='" );
					Htm.push( tn );
					Htm.push( "'" );
					Htm.push( " title=\"" );
					Htm.push( toolTip );
					Htm.push( "\" " );
					Htm.push( "style='" );
					Htm.push( "border:1px solid " ); Htm.push( Settings.TN.bordColOff ); Htm.push( ";" );
					Htm.push( " width:" ); Htm.push( Settings.TN.width ); Htm.push( "px;" );
					Htm.push( " height:" ); Htm.push( Settings.TN.height ); Htm.push( "px;" );
					Htm.push( "'" );
					Htm.push( " onMouseover='if( window.TN ) TN.imgBorder(this,Settings.TN.bordColOn);' onMouseout='if( window.TN ) TN.imgBorder(this,Settings.TN.bordColOff);' onAbort='this.src=this.src;' onLoad='TN.tnRemainingTN--;' onContextMenu='" );
					Htm.push( ( ( Settings.disableContextImgMenu ) ? "return false;" : "return true;" ) );
					Htm.push( "' id='TN_" );
					Htm.push( imageNum );
					Htm.push( "'>" );

					Htm.push( "</a>" );
					Htm.push( "</td>" );
				}

			}
			///////////////// END TNs /////////////////

			Htm.push( "</tr>" );
			Htm.push( "</table>" );
			Htm.push( "</td></tr>" );


		///////////////// END ROWS /////////////////

		}

		Htm.push( "</table>" );
		var htm = Htm.join( "" );
		//alert( htm );
		document.write( htm );

	}

	// Begin admin-only methods
	//------------------------------------- METHOD TN -------------------------------------
	// Admin only

	function reportImgName( Link, imageNum, evt ) {
		if( userWithWritePrivileges ) {

			if( window.Images == null )
				window.Images = this.ImagesOriginal;

			var Img = Images[ imageNum - 1 ];
			var ImgTN = Link.firstChild;

			var Htm = new Array();

			Htm.push( "<table align='left'>" );
			Htm.push( "<tr>" );
			Htm.push( "<td align=center valign=top>" );
			Htm.push( "<img src='" );
			Htm.push( ImgTN.src );
			Htm.push( "' width='" );
			Htm.push( ImgTN.width );
			Htm.push( "' height='" );
			Htm.push( ImgTN.height );
			Htm.push( "'>" );
			Htm.push( "</td>" );
			Htm.push( "<td align=center valign=top style='padding:4px;'>" );
			Htm.push( "<table align='center' class='dwText'>" );
			Htm.push( "<tr><td align=right>Name:&nbsp;</td><td align=left>" );
			Htm.push( Img[ 0 ] );
			Htm.push( "</td></tr>" );
			Htm.push( "<tr><td align=right>Number:&nbsp;</td><td align=left>" );
			Htm.push( imageNum );
			Htm.push( " of " );
			Htm.push( TN.nImages );
			Htm.push( "</td></tr>" );
			Htm.push( "<tr><td align=right>Dimensions:&nbsp;</td><td align=left id='DimTN'> <br/></td></tr>" );
			Htm.push( "<tr><td align=right>File Size:&nbsp;</td><td align=left id='fileSizeTN'> <br/></td></tr>" );
			Htm.push( "<tr><td align=right valign=top>Caption:&nbsp;</td><td align=left>" );
			Htm.push( Img[ 1 ] );
			Htm.push( "</td></tr>" );
			Htm.push( "</table>" );
			Htm.push( "</td>" );
			Htm.push( "</table>" );

			if( window.DW ) {
				DW.createWindow( [ "Enlargement", Htm.join( "" ) ], [ 0, 500, 0 ], Link, evt );
				this.setEnlargementProperties( imageNum );
			}

			return false;
		}
	}

	//------------------------------------- METHOD TN -------------------------------------
	// Admin only

	function setEnlargementProperties( imageNum ) {

		this.Request = getAjaxRequest();

		if( this.Request ) {

			this.Request.onreadystatechange = function() {
				try {
					if( TN.Request.readyState == 4 ) {
						if( TN.Request.status == 200 || TN.Request.status == 304 ) {

							//alert( TN.Request.getAllResponseHeaders() );
							var fileSize = parseInt( TN.Request.getResponseHeader( "Content-Length" ) ) / 1024;
							var FileSizeTN = document.getElementById( "fileSizeTN" );

							if( FileSizeTN ) {
								FileSizeTN.innerHTML = Math.round( fileSize ) + " KB";

								// Start pre-loading off-screen image which we will extract dimensions from
								this.ImgOffscreen = document.getElementById( "ImgOffscreenLg" );
								if( this.ImgOffscreen ) document.body.removeChild( this.ImgOffscreen );

								this.ImgOffscreen = document.createElement( "IMG" );
								this.ImgOffscreen.id = "ImgOffscreen";
								this.ImgOffscreen.style.position = "absolute";
								this.ImgOffscreen.style.top = "-1000000px";
								this.ImgOffscreen.style.left = "-1000000px";
								document.body.appendChild( this.ImgOffscreen );

								// When image loads off-screen show it.
								// To disable (for testing) change to "this.ImgOffscreen.onloadx"
								this.ImgOffscreen.onload = function() {

									var DimTN = document.getElementById( "DimTN" );
									var wid =  this.width, hgt =  this.height;
									var shape = ( wid > hgt ) ? "horizontal" : ( ( wid < hgt ) ? "vertical" : "square" );
									DimTN.innerHTML = wid + " &times; " + hgt + " px; " + shape;

								}

								this.ImgOffscreen.src = Settings.folder + Images[ imageNum - 1 ][ 0 ];
							}
						}
						else
							alert( "Error retrieving photo at method TN.setEnlargementProperties" );

					}
				}
				catch( Err ) {
					var eMsg = "Exception at method TN.setEnlargementProperties\n\n";
					for( var i in Err ) eMsg += i + ": " + Err[ i ] + "\n";
					try{ alert( eMsg ); } catch( Err ) { }
				}
			}
			// IE returns Content-Length when making a head reqeust, so use GET
			this.Request.open( "GET", Settings.folder + Images[ imageNum - 1 ][ 0 ], true );
			this.Request.send( null );

		}
	}

	//------------------------------------- METHOD TN -------------------------------------
	// Check tn dimensions - admin mode only

	this.checkTN = 1; this.checkTnTimer = 0; this.TnReal = null; this.TnSizeErr = "";
	function checkTnDim() {

		if( userWithWritePrivileges || local ) {
			if( this.TnReal == null ) {
				var TN = document.getElementById( "TN_" + this.checkTN );
				if( TN ) {
					TnReal = new Image();
					TnReal.src = TN.src;
				}
				else {
					TnReal = null;
					clearTimeout( this.checkTnTimer );
					if( this.TnSizeErr ) {
						var msgOut = this.TnSizeErr;
						if( IE ) msgOut += "<br/><br/>We see you are using Internet Explorer. It suffers from a peculiar bug such that even if you correct the dimensions, it may continue to report this error! If so, then change the file name too, for example:<br/>1. beachTN.jpg &rArr; beach1TN.jpg<br/>2. beach.jpg &rArr; beach1.jpg";
						DW.createWindow( [ "Thumbnail Dimension Error", "<div style='margin:0px 0px 4px 0px;' class='dwText'>Thumbnails must be " + Settings.TN.width + " x " + Settings.TN.height + " pixels, and:</div>" + msgOut ], [ 1, 450, 300 ], null, null, 6, [ 4, 0, 0 ] );
					}

				}
			}

			if( TnReal && TnReal.complete ) {
				var realWid = TnReal.width, realHgt = TnReal.height;
				if( realWid > 1 && realHgt > 1 && ( realWid != Settings.TN.width || realHgt != Settings.TN.height ) ) {
					var FileComponents = TnReal.src.split( "/" );
					var fileName = FileComponents[ FileComponents.length - 1 ];
					this.TnSizeErr += "<div style='margin:0px 0px 0px 8px;'>#" + this.checkTN + " " + fileName + " is " + realWid + " x " + realHgt + "</div>";
				}
				this.checkTN++;
				this.checkTnTimer = setTimeout( "TN.checkTnDim();", 100 );
			}
		}
	}
} //////////////////////////////////////// END THUMBNAILS: TN ///////////////////////////////////////

