//** Simple Controls Gallery- (c) Dynamic Drive DHTML code library: http://www.dynamicdrive.com
//** Script created (Requires jquery 1.2.x)
//** Edited by MetroStar systems for use on Marines.mil 


var simpleGallery_navpanel =
{
	panel: {height:'47px', opacity:0.5, paddingTop:'5px', fontStyle:'bold 11px Verdana'}, //customize nav panel container
	
	images: [ '/_layouts/usmc/images/simplegallery/buttons/left.gif', 
			 '/_layouts/usmc/images/simplegallery/buttons/play.gif', 
			 '/_layouts/usmc/images/simplegallery/buttons/right.gif', 
			 '/_layouts/usmc/images/simplegallery/buttons/pause.gif'], //nav panel images (in that order)
	
	imageSpacing: {offsetTop:[-4, 0, -4], spacing:10}, //top offset of left, play, and right images, PLUS spacing between the 3 images
	
	slideduration: 500 //duration of slide up animation to reveal panel
}

function simpleGallery(settingarg)
{
	this.setting = settingarg
	
	settingarg = null
	
	var setting = this.setting
	
	setting.panelheight = (parseInt(setting.navpanelheight)>5)? parseInt(setting.navpanelheight) : parseInt(simpleGallery_navpanel.panel.height)
	
	setting.fadeduration = parseInt(setting.fadeduration)
	
	setting.curimage = (setting.persist) ? simpleGallery.routines.getCookie("gallery-" + setting.wrapperid) : 0
	
	setting.curimage = setting.curimage || 0 //account for curimage being null if cookie is empty
	
	setting.ispaused = !setting.autoplay[0] //ispaused reflects current state of gallery, autoplay[0] indicates whether gallery is set to auto play
	
	setting.currentstep = 0 // keep track of # of slides slideshow has gone through
	
	setting.totalsteps = setting.imagearray.length * setting.autoplay[2] // Total steps limit: # of images x # of user specified cycles
	
	//index of active and background layer (switches after each change of slide)
	setting.fglayer = 0
	setting.bglayer = 1 
	
	// These properties are used to allow pause when hovering over this image.
	setting.isHovering = false; 
	setting.wasPausedOnHover = false;
	
	setting.pageSize = 3; // Set the page size so that it can be used elsewhere. This is used for downloading pages of images.
	
	setting.oninit = setting.oninit || function(){}
	
	setting.onslide = setting.onslide || function(){}
		
	//get longest description of all slides. If no desciptions defined, variable contains ""	
	var longestdesc = null 	
	setting.longestdesc = "" 
	for (var i=0; (i < setting.imagearray.length); i++)
	{
		if (setting.imagearray[i][3] && (setting.imagearray[i][3].length > setting.longestdesc.length))
			setting.longestdesc = setting.imagearray[i][3]
	}
	
	// Prepare to load the images asyncronously.
	var preloadimages = [] 
	// Initialize the array with nulls so we know which are already downloaded
	for (var i=0; (i < setting.imagearray.length); i++)
	{
		preloadimages[i] = null;
	}
	// Save the list of preloaded images so that they can be used later in other functions
	setting.preloadedImages = preloadimages; 
		
	var slideshow = this
	
	jQuery(document).ready(function($)
	{
		var setting = slideshow.setting
				
		// Load the first image imediatelly. 
		simpleGallery.routines.downloadImageAt(0,setting);
		
		var pageSize = setting.pageSize;

		// OLD: Download the images in the forward direction but asynchronously.
		//simpleGallery.routines.loadImagesForwardAllByPagesAsync(setting,2);
		// NEW: Now we only download the images in pages as they are needed.
		
		// Load the first page of images.
		simpleGallery.routines.loadImagesInPageForwardAsync(setting, pageSize, 1);
		
		// Download the last page of images incase they go backwards from the first image.
		var lastPageNo = simpleGallery.routines.getLastPageNumber(setting,pageSize);
		simpleGallery.routines.loadImagesInPageForwardAsync(setting, pageSize, lastPageNo); 
		
		// Find the DIV that wraps this entire slide show's area
		// Then set its CSS so that it is visible and more.
		setting.$wrapperdiv = $('#'+ setting.wrapperid).css({position:'relative', visibility:'visible', overflow:'hidden', width:setting.dimensions[0], height:setting.dimensions[1]}).empty() 
		if (setting.showBackground)
		    setting.$wrapperdiv.css('background',setting.backgroundColor)
		
		if (setting.$wrapperdiv.length == 0)
		{ //if no wrapper DIV found
			//DEBUG ONLY --> alert("Error: DIV with ID \"" + setting.wrapperid + "\" not found on page.")
			// Do nothing in production mode. You don't want users getting alerts.
			return
		}
		
		// Create two stacked DIVs to display the actual slide and to allow the slides to change with animation.
		setting.$gallerylayers = $('<div class="gallerylayer"></div><div class="gallerylayer"></div>')  
			.css({position:'absolute', left:0, top:0})
			.appendTo(setting.$wrapperdiv)
			
		setting.gallerylayers = setting.$gallerylayers.get() //cache stacked DIVs as DOM objects
		
		setting.navbuttons = simpleGallery.routines.addnavpanel(setting) //get 4 nav buttons DIVs as DOM objects
		
		if (setting.longestdesc != "") //if at least one slide contains a description (feature is enabled)
			setting.descdiv = simpleGallery.routines.adddescpanel(setting)
		
		$(setting.navbuttons).filter('img.navimages')
		    .css({opacity:0.8}) // dims the nav buttons by default.
			.bind('mouseover mouseout', function(e) // highlight the nav buttons when mouse over and dim them when mouse out
			{
				$(this).css( { opacity:(e.type == "mouseover") ? 1 : 0.8 } )
			})
			.bind('click', function(e) // navigate to the slide when a nav button is clicked based on the button's title
			{
				var keyword = e.target.title.toLowerCase()
				slideshow.navigate(keyword) //assign behavior to nav images
			})
		
		setting.$wrapperdiv.bind('mouseenter', function()
		{
		    slideshow.showhidenavpanel('show')
		    
		    // Pause if in play mode when hovering, and restart on exit-hover
		    slideshow.doPauseOnHover('hover');
		})
		
		setting.$wrapperdiv.bind('mouseleave', function()
		{
		    slideshow.showhidenavpanel('hide')
		    
		    // Pause if in play mode when hovering, and restart on exit-hover
		    slideshow.doPauseOnHover('exit');
		})
		
		slideshow.showslide(setting.curimage) //show initial slide
		
		setting.oninit.call(slideshow) //trigger oninit() event
		
		$(window).bind('unload', function()
		{ //clean up and persist
			
			$(slideshow.setting.navbuttons).unbind()
			
			if (slideshow.setting.persist) //remember last shown image's index
				simpleGallery.routines.setCookie( "gallery-" + setting.wrapperid, setting.curimage)
			
			jQuery.each(slideshow.setting, function(k)
			{
				if (slideshow.setting[k] instanceof Array)
				{
					for (var i=0; i < slideshow.setting[k].length; i++)
					{
					    if (slideshow.setting[k][i] != null)
					    {
						    if (slideshow.setting[k][i].tagName == "DIV") //catches 2 gallerylayer divs, gallerystatus div
							    slideshow.setting[k][i].innerHTML = ''
						
						    slideshow.setting[k][i] = null
						}
						
					}
				}
				
				if (slideshow.setting[k].innerHTML) //catch gallerydesctext div
					slideshow.setting[k].innerHTML = null
				
				slideshow.setting[k] = null
			})
			slideshow = slideshow.setting = null
		})
	})
}

simpleGallery.prototype =
{
	navigate:function(keyword)
	{
		clearTimeout(this.setting.playtimer)
		
		this.setting.totalsteps = 100000 //if any of the nav buttons are clicked on, set totalsteps limit to an "unreachable" number 
		
		if (!isNaN(parseInt(keyword)))
		{
			this.showslide(parseInt(keyword))
		}
		else if (/(prev)|(next)/i.test(keyword))
		{
			this.showslide(keyword.toLowerCase())
		}
		else
		{ //if play|pause button
			var slideshow = this
			var $playbutton = $(this.setting.navbuttons).eq(1)
			if (!this.setting.ispaused)
			{ //if pause Gallery
				this.setting.autoplay[0] = false
				$playbutton.attr({title:'Play', src:simpleGallery_navpanel.images[1]})
			}
			else if (this.setting.ispaused)
			{ //if play Gallery
				this.setting.autoplay[0] = true
				this.setting.playtimer = setTimeout(function()
				                                    {
					                                    if (slideshow.setting.isHovering)
					                                    {   // Do not move to the next slide when hovering.
					                                        // Signal to the exit-hover event that you need to move to next and restart the timer.
					                                        slideshow.setting.wasPausedOnHover = true;
					                                    }
					                                    else
					                                    {   // Move to the next slide normally.
					                                        slideshow.showslide('next');
					                                    }
					                                }, 
					                                slideshow.setting.autoplay[1])
				
				$playbutton.attr({title:'Pause', src:simpleGallery_navpanel.images[3]})
			}
			slideshow.setting.ispaused = !slideshow.setting.ispaused
		}
	},

	showslide:function(keyword)
	{
		var slideshow = this
		var setting = slideshow.setting
		var totalimages = setting.imagearray.length
		
		// Get the image index for the next slide.
		var imgindex = 0;
		if (keyword=="next")
		{
		    if (setting.curimage < totalimages-1)
		        imgindex = (setting.curimage + 1);
		    else
		        imgindex = 0;
				
			// Download the next page of images in the forward direction.
			simpleGallery.routines.loadImagesForNextPageAsync(setting, setting.pageSize, imgindex, true);
		}
		else
		{
		    if (keyword=="prev")
		    {
		        if (setting.curimage > 0)
		            imgindex = (setting.curimage - 1);
		        else
		            imgindex = (totalimages - 1);
				
				// Download the next page of images in the backward direction.
				simpleGallery.routines.loadImagesForNextPageAsync(setting, setting.pageSize, imgindex, false);
		    }
		    else
		    {
		        imgindex = Math.min(keyword, totalimages-1);
		    }
		}
		
		setting.gallerylayers[setting.bglayer].innerHTML = simpleGallery.routines.getSlideHTML(setting.imagearray[imgindex])
		
		// Center the image horizontally and vertically by using fixed offsets and sizes.
		// Now resize this layer's DIV so that it offsets itself from the parent div.
		//var imageWidthIndex = 4;
		//var imageHeightIndex = 5;
		//var webPartWidth  = setting.dimensions[0];
		//var webPartHeight = setting.dimensions[1]; 
		//var image = setting.preloadedImages[imgindex]; // Requires that this image is pre-loaded.
		//var imageWidth = image.width;
		//var imageHeight = image.height;
		//var leftOffset = (webPartWidth  - imageWidth ) / 2;
		//var topOffset  = (webPartHeight - imageHeight) / 2;
		//if (setting.showBorder)
		//{
		//    leftOffset -= setting.borderWidth;
		//    topOffset  -= setting.borderWidth;
		//}
		//    
		//setting.$gallerylayers.eq(setting.bglayer).css('top',   topOffset.toString(10)   )
		//                                          .css('left',  leftOffset.toString(10)  ) 
		//                                          .css('width', imageWidth.toString(10)  ) 
		//                                          .css('height',imageHeight.toString(10) );
		
		setting.$gallerylayers.eq(setting.bglayer).css({zIndex:1000, opacity:0}) //background layer becomes foreground
			.stop().css({opacity:0}).animate({opacity:1}, setting.fadeduration, function()
			{ //Callback function after fade animation is complete:
			
				clearTimeout(setting.playtimer)
				
				setting.gallerylayers[setting.bglayer].innerHTML = ''  //empty bglayer (previously fglayer before setting.fglayer=setting.bglayer was set below)
				
				try
				{
					setting.onslide.call(slideshow, setting.gallerylayers[setting.fglayer], setting.curimage)
				}
				catch(e)
				{
					//alert("Simple Controls Gallery: An error has occured somwhere in your code attached to the \"onslide\" event: "+e)
				}
				
				setting.currentstep += 1
				
				if (setting.autoplay[0])
				{
					if (setting.currentstep <= setting.totalsteps)
						setting.playtimer = setTimeout(function() 
						                                {   
						                                    if (slideshow.setting.isHovering)
						                                    {   // Do not move to the next slide
						                                        // Signal to the exit-hover event that you need to move to next and restart the timer.
						                                        slideshow.setting.wasPausedOnHover = true;
						                                    }
						                                    else
						                                    {   // Move tot he next slide normally
						                                        slideshow.showslide('next');
						                                    }
						                                }, 
						                                setting.autoplay[1]
						                               )
					else
						slideshow.navigate("play/pause")
				}
				
			}) //end callback function
		
		// Swap the forground and backgroun layers.
		setting.gallerylayers[setting.fglayer].style.zIndex = 999 //foreground layer becomes background
		setting.fglayer = setting.bglayer
		setting.bglayer = (setting.bglayer == 0) ? 1 : 0
		setting.curimage = imgindex
		setting.navbuttons[3].innerHTML = (setting.curimage + 1) + '/' + setting.imagearray.length
		
		// Show the caption panel if there is a caption.
		if (setting.imagearray[imgindex][3])
		{ 
			setting.$descpanel.css( {visibility:'visible'} ) // show the caption panel.
			
			// If there is a hyperlink then we must allow the caption/description frame to be clicked as if it was the image.
			var imageRec = setting.imagearray[imgindex];
			if (imageRec[1].length > 0)
			{   // Yes there is a hyperlink for this image, so the caption must be clickable.
			    
			    // Navigate to the hyperlink when the DIV is clicked.	    
			    var onclickText = '"javascript:window.open(\'' + imageRec[1] + '\',\'' + imageRec[2] + '\');"';

			    var styleText = 'style="LEFT:0px; WIDTH:100%; POSITION:absolute; TOP:0px; HEIGHT:100%; cursor:pointer;"';
			    setting.descdiv.innerHTML = '<div onclick=' + onclickText + ' ' + styleText + ' >' + imageRec[3] + '</div>';                
			}
			else
			{   // The image does not have a place to go, so do not surround with an anchor tag.
			    setting.descdiv.innerHTML = imageRec[3];
			}
			
		}
		else 
		{   // There is no description/caption for this image.
		    // But we still show the caption panel if there is at least one image with a caption.
		    if (setting.longestdesc != "")
		    {   //if at least one slide contains a description (feature is enabled)
			    setting.descdiv.innerHTML = ''; // Show the caption as empty in this case.
			    setting.$descpanel.css( {visibility:'hidden'} )
            }
		}
	},

	showhidenavpanel:function(state)
	{
		var setting = this.setting
		var endpoint = (state=="show") ? setting.dimensions[1] - setting.panelheight : this.setting.dimensions[1]
		setting.$navpanel.stop().animate( {top:endpoint}, simpleGallery_navpanel.slideduration )
		if (setting.longestdesc != "") //if at least one slide contains a description (feature is enabled)
			this.showhidedescpanel(state)
	},

	showhidedescpanel:function(state)
	{
		var setting = this.setting
		var endpoint = (state == "show") ? 0 : -setting.descpanelheight
		setting.$descpanel.stop().animate( {top:endpoint}, simpleGallery_navpanel.slideduration)
	},
	
	// Pause if in play mode when hovering, and restart on exit-hover
	doPauseOnHover:function(state)
	{
		var setting = this.setting
	    if (state == "hover")
	    {   // Signal to the play operation that it should pause because we are hoving.
            this.setting.isHovering = true;
	    }
	    else
	    {   // Stop pausing on hover, and move to the next image if it was paused while hovering.
            this.setting.isHovering = false; // always turn this off.
            if (this.setting.wasPausedOnHover)
            {
			    this.setting.wasPausedOnHover = false;
			    if (!this.setting.ispaused)
			    {   // Then they did not press the Pause button while hovering, so it is OK to go to the next image.
			        this.showslide('next');
			    }
			}
	    }
	    
	}

}

simpleGallery.routines =
{
	getSlideHTML:function(imgelement)
	{
	    var layerHTML = '';
	    		
		if (imgelement[1])
		    layerHTML += '<a href="' + imgelement[1] + '" target="' + imgelement[2] + '">\n';
		    		
		layerHTML += '<img src="' + imgelement[0] + '" style="border-width:0" galleryimg="false" />';
		
		if (imgelement[1])
		    layerHTML += '</a>';
		    		
		return layerHTML; //return HTML for this layer
	},


	addnavpanel:function(setting)
	{
		// Set up the 3 buttons on the nav toolbar.
		var interfaceHTML = '';
		var title = '';
		var imagesrc = '';
		var imgstyle = '';
		
		// Prev
		title = 'Prev';
		imagesrc = simpleGallery_navpanel.images[0]
		imgstyle = 'position:relative; border:0; cursor:hand; cursor:pointer; top:'+ simpleGallery_navpanel.imageSpacing.offsetTop[0] + 'px; margin-right:' + simpleGallery_navpanel.imageSpacing.spacing + 'px'
		interfaceHTML += '<img class="navimages" title="' + title + '" src="'+ imagesrc +'" style="' + imgstyle + '" /> '
		
		// Play/Pause
		var imageIndex = 1;
		if (setting.ispaused)
		{
		    title = 'Play';
		    imageIndex = 1;
		}
		else
		{
		    title = 'Pause';
		    imageIndex = 3;
		}
		imagesrc = simpleGallery_navpanel.images[imageIndex]
		imgstyle = 'position:relative; border:0; cursor:hand; cursor:pointer; top:'+ simpleGallery_navpanel.imageSpacing.offsetTop[1] + 'px; margin-right:' + simpleGallery_navpanel.imageSpacing.spacing + 'px'
		interfaceHTML += '<img class="navimages" title="' + title + '" src="'+ imagesrc +'" style="' + imgstyle + '" /> '
		
		// Next
		title = 'Next';
		imagesrc = simpleGallery_navpanel.images[2]
		imgstyle = 'position:relative; border:0; cursor:hand; cursor:pointer; top:'+ simpleGallery_navpanel.imageSpacing.offsetTop[2] + 'px; margin-right:0px'
		interfaceHTML += '<img class="navimages" title="' + title + '" src="'+ imagesrc +'" style="' + imgstyle + '" /> '
		
		interfaceHTML += '<div class="gallerystatus" style="margin-top:1px">' + (setting.curimage+1) + '/' + setting.imagearray.length + '</div>'
		
		setting.$navpanel = $('<div class="navpanellayer"></div>')
			.css({position:'absolute', width:'100%', height:setting.panelheight, left:0, top:setting.dimensions[1], font:simpleGallery_navpanel.panel.fontStyle, zIndex:'1002'})
			.appendTo(setting.$wrapperdiv)
			
		$('<div class="navpanelbg"></div><div class="navpanelfg"></div>') //create inner nav panel DIVs
			.css({position:'absolute', left:0, top:0, width:'100%', height:'100%'})
			.eq(0).css({background:'black', opacity:simpleGallery_navpanel.panel.opacity}).end() //"navpanelbg" div
			.eq(1).css({paddingTop:simpleGallery_navpanel.panel.paddingTop, textAlign:'center', color:'white'}).html(interfaceHTML).end() //"navpanelfg" div
			.appendTo(setting.$navpanel)
			
		return setting.$navpanel.find('img.navimages, div.gallerystatus').get() //return 4 nav related images and DIVs as DOM objects
	},

	adddescpanel:function(setting)
	{
		setting.$descpanel = $('<div class="gallerydesc"><div class="gallerydescbg"></div><div class="gallerydescfg"><div class="gallerydesctext"></div></div></div>')
			.css({position:'absolute', width:'100%', left:0, top:-1000, zIndex:'1001'})
			.find('div').css({position:'absolute', left:0, top:0, width:'100%'})
			.eq(0).css({background:'black', opacity:simpleGallery_navpanel.panel.opacity}).end() //"gallerydescbg" div
			.eq(1).css({color:'white'}).end() //"gallerydescfg" div
			.eq(2).html(setting.longestdesc).end().end()
			.appendTo(setting.$wrapperdiv)
		
		var $gallerydesctext = setting.$descpanel.find('div.gallerydesctext')
		
		setting.descpanelheight = $gallerydesctext.outerHeight()
		
		setting.$descpanel.css({top:-setting.descpanelheight, height:setting.descpanelheight}).find('div').css({height:'100%'})
		
		return setting.$descpanel.find('div.gallerydesctext').get(0) //return gallery description DIV as a DOM object
	},

	getCookie:function(Name)
	{ 
		var re = new RegExp(Name+"=[^;]+", "i"); //construct RE to search for target name/value pair
		
		if (document.cookie.match(re)) //if cookie found
			return document.cookie.match(re)[0].split("=")[1] //return its value
		
		return null
	},

	setCookie:function(name, value)
	{
		document.cookie = name + "=" + value + ";path=/"
	},

	// Download the image at the given index
	downloadImageAt:function(index, setting)
	{
		try {
			var preloadedImages = setting.preloadedImages;
			preloadedImages[index] = new Image()
			var imageRec = setting.imagearray[index]
			// Note that the first item in the imageRec array is the source URL for the image.
			var sourceUrl = imageRec[0]
			preloadedImages[index].src = sourceUrl 
			
			simpleGallery.routines.logMessage('In downloadImageAt(' + index.toString() + ')')
		}
		catch(e)
		{	// Eat it for now
			simpleGallery.routines.logMessage("Exception in downloadImageAt(" + index.toString() + ")");  // DEBUG MODE
		}
	},
	
	// Load all images in a forward direction
	loadImagesForward:function(startingIndex, count, setting)
	{
		simpleGallery.routines.logMessage('Begin loadImagesForward()')
		
		var preloadedImages = setting.preloadedImages;
		var imagesArray = setting.imagearray;
		var stopingIndex = startingIndex + count - 1; // The index to stop at
		var lastIndex = imagesArray.length - 1; // last possible index in this array
		if (stopingIndex > lastIndex)
			stopingIndex = lastIndex;
		for (var i=startingIndex; (i <= stopingIndex); i++)
		{
			if (preloadedImages[i] == null)
			{	// Then download this image.
				simpleGallery.routines.downloadImageAt(i,setting);
			}
			else
			{
				simpleGallery.routines.logMessage('In loadImagesForward(): The image was already downloaded at i = ' + i.toString() );
			}
		}
		
		simpleGallery.routines.logMessage('Exit loadImagesForward()')
	},

	// Load all images in a forward direction
	loadImagesForwardAll:function(setting)
	{
		simpleGallery.routines.loadImagesForward(0, setting.imagearray.length, setting);
	},

	
	loadImagesForwardAllByPagesAsync:function(setting, pageSize)
	{
		// Start with the first page and continue loading all pages until done.
		setTimeout( function() { simpleGallery.routines.loadImagesPageForwardContinue(setting, pageSize, 1, true); }, 200);
	},

	loadImagesForwardAllByPages:function(setting, pageSize)
	{
		// Start with the first page and continue loading all pages until done.
		simpleGallery.routines.loadImagesPageForwardContinue(setting, pageSize, 1, true);
	},

	// Get the page number for the given index.
	getPageNumberForIndex:function(setting, pageSize, indexIn)
	{
		var count = setting.imagearray.length;
		var index = indexIn;
		
		// If negative index then translate it into a positive index.
		if (index < 0)
			index = count + index;
		
		index += 1; // Turn it into 1 based index.
		
		// if it is larger than the max 1 based index, the size, then get its actual index (one based)
		if (index > count)
			index = index % count;
		
		// Now that we have a good 1 based index, do the math for the page number.
		var times = Math.floor(index / pageSize);
		var remainder = index % pageSize;
		if (remainder > 0)
			return times + 1;
		else
			return times;
	},
		
	// Get the last page number
	getLastPageNumber:function(setting, pageSize)
	{
		var imagesCount = setting.imagearray.length;
		var times = Math.floor(imagesCount / pageSize);
		var remainder = imagesCount % pageSize;
		if (remainder > 0)
			return times + 1;
		else
			return times;
	},
		
	// Loads the images for the given page number and of the given page size.
	loadImagesInPageForward:function(setting, pageSize, pageNumber)
	{
		simpleGallery.routines.logMessage('Begin loadImagesInPageForward(' + pageSize.toString() + ', ' + pageNumber.toString() + ')')
		var startIndex1 = (pageSize * (pageNumber -1));
		var imagesCount = setting.imagearray.length;
		var startIndex = startIndex1 % imagesCount;
		
		if (startIndex < setting.imagearray.length)
		{
			simpleGallery.routines.loadImagesForward(startIndex, pageSize, setting);
		}
		else
		{
			simpleGallery.routines.logMessage('In loadImagesInPageForward(' + pageSize.toString() + ', ' + pageNumber.toString() + ') -- Bad Page Number')
		}
	},

	// Load the given page's images.
	loadImagesInPageForwardAsync:function(setting, pageSize, pageNumber)
	{
		setTimeout( function() { simpleGallery.routines.loadImagesInPageForward(setting, pageSize, pageNumber); }, 100); 
	},
	
	// Used to load a "page" of images async and to start the next page load after this one if the 'loadNextPage' is True
	// otherwise it only loads the one page.
	loadImagesPageForwardContinue:function(setting, pageSize, pageNumber, loadNextPage)
	{
		simpleGallery.routines.logMessage('Begin loadImagesPageForwardContinue(' + pageSize.toString() + ', ' + pageNumber.toString() + ', ' + loadNextPage.toString() + ')')
		var startIndex = (pageSize * (pageNumber -1));
		
		if (startIndex < setting.imagearray.length)
		{
			simpleGallery.routines.loadImagesForward(startIndex, pageSize, setting);
					
			if (loadNextPage)
			{
				setTimeout( function() { simpleGallery.routines.loadImagesPageForwardContinue(setting, pageSize, pageNumber+1, loadNextPage); }, 1000); // TODO: Shorten to 200
			}
		}
		else
		{
			simpleGallery.routines.logMessage('In loadImagesPageForwardContinue(' + pageSize.toString() + ', ' + pageNumber.toString() + ', ' + loadNextPage.toString() + ') -- Last Page Found')
		}
	},

	// Load the image for the next page given the current index and a direction.
	loadImagesForNextPage:function(setting, pageSize, index, forward)
	{
		simpleGallery.routines.logMessage('Start loadImagesForNextPage(' + pageSize.toString() + ', ' + index.toString() + ', ' + forward.toString() + ')')
		
		var pageNo1 = simpleGallery.routines.getPageNumberForIndex(setting,pageSize,index);
		var pageNo2 = 0;
		if (forward)
		{
			pageNo2 = pageNo1 + 1;
			
			// Make sure it is not larger than the last page. If so then translate it to a valid page number.
			// Note that this only happens when going forward from the last page to the first.
			var lastPageNo = simpleGallery.routines.getLastPageNumber(setting,pageSize);
			if (pageNo2 > lastPageNo)
				pageNo2 = (pageNo2 - lastPageNo);
		}
		else
		{
			pageNo2 = pageNo1 - 1;
			if (pageNo2 <= 0)
			{
				var lastPageNo = simpleGallery.routines.getLastPageNumber(setting,pageSize);
				pageNo2 = lastPageNo;
			}
		}
		
		simpleGallery.routines.loadImagesInPageForward(setting,pageSize,pageNo2);
	},

	// Load the image for the next page given the current index and a direction.
	// and do it Asynchronously.
	loadImagesForNextPageAsync:function(setting, pageSize, index, forward)
	{
		setTimeout( function() { simpleGallery.routines.loadImagesForNextPage(setting, pageSize, index, forward); }, 100);
	},
	
	loadImagesBackwards:function(startingIndex, count, setting)
	{
		simpleGallery.routines.logMessage('Begin loadImagesBackwards()')
		
		var preloadedImages = setting.preloadedImages;
		var imagesArray = setting.imagearray;
		var lastIndex = startingIndex - count;
		for (var i=startingIndex; (i > lastIndex); i--)
		{
			if (i < 0)
				i = imagesArray.length + i;
				
			if (preloadedImages[i] == null)
			{	// Then download this image.
				simpleGallery.routines.downloadImageAt(i,setting);
			}
			else
			{
				simpleGallery.routines.logMessage('In loadImagesBackwards(): The image was already downloaded at i = ' + i.toString() );
			}
		}
		
		simpleGallery.routines.logMessage('Exit loadImagesBackwards()')
	},

	// Load all images in a backward direction, skipping those that are already downloaded
	loadImagesBackwardsAll:function(setting)
	{
		simpleGallery.routines.loadImagesBackwards(setting.imagearray.length -1, setting.imagearray.length, setting);
	},
	
	// Log the message into a text box.  Used for debugging only. Removed in production and disabled.
	logMessage:function(message)
	{
		//var originalValue = $('textarea#logTextarea').attr('value') 
		//var newValue = originalValue + ' \n ' + message
		//$('textarea#logTextarea').attr('value', newValue)
	}

	
}




