
/******************************************************************************************************************************************************************************************
                                                                                      SLIDESHOW.JS

Copyright © 2007 Illusionator, Inc.

JavaScript code that implements a slideshow, with fade-in/fade-out capabilities.

******************************************************************************************************************************************************************************************/


// IlsSetOpacity(sImageId, nOpacity)
//		sImageId:		HTML ID of the image object whose opacity is to be set.
//		nOpacity:		An opacity percentage, where 0 is completely transparent, and 100 is completely opaque.
//	returns:			Nothing.
//
// Sets the opacity of the image corresponding to "sImageId" according to the amount indicated by "nOpacity."

function IlsSetOpacity(id, nOpacity)
{ 
	var objStyle = IlsGetStyle(id);

	// Per discussions on the Internet, on some versions of Mozilla and Firefox, changing the value of the opacity from less than 1.0 to be 1.0 causes flicker.  The workaround is
	// to never set the opacity to 1.0, but instead be content with an opacity of 0.99, which actually displays the same as an opacity of 1.0.  To achieve this, we divide the specified
	// opacity (which is in the range [0..100]) by 101 on these browsers, rather than 100.  Note that 100/101 is slightly more than 0.9901.  Various versions of Mozilla and Firefox use
	// the CSS properties "opacity" and/or "MozOpacity," so we divide both of these by 101, rather than 100.
	// ALSO: Rather than test for a property before setting it, we just set all of the properties, even though most browsers will only pay attention to one of these properties.
	objStyle.opacity = (nOpacity / 101);					// Safari 1.2 and higher, newer Firefox and Mozilla, CSS3
	objStyle.MozOpacity = (nOpacity / 101);					// Older Mozilla and Firefox
	objStyle.KhtmlOpacity = (nOpacity / 100);				// Safari <1.2, Konqueror
	objStyle.filter = "alpha(opacity=" + nOpacity + ")";	// Internet Explorer
} // IlsSetOpacity


// IlsImageBlend(sDivId, sImageId, sImage, nDuration)
//		sDivId			HTML ID of the "DIV" element that contains the image object, used for blending.
//		sImageId:		HTML ID of the image object, inside the "DIV" element, that displays the new image.
//		sImage:			Path of the image to be displayed in the image object.
//		nDuration:		Length of time, in milliseconds, during which the images are to be blended.
//	returns:			Nothing.
//
// Fades in the image for "sImage" over the top of the image displayed in the image object "sImageId" by setting the background image of the "sDivId" object to the current contents of
// "sImageId", replacing the image of "sImageId" with a completely transparent version of "sImage", and then increasing the opacity of "sImageId" until it is fully opaque.

function IlsImageBlend(sDivId, sImageId, sImage, nDuration) 
{ 
	// We are going to blend the images in 100 discrete steps from 1 to 100 percent, so divide the number of milliseconds of the duration by 100, to compute the duration of each step
	var nSpeed = Math.round(nDuration / 100);

	// Cache the object corresponding to "sImageId"
	var objImage = IlsGetObj(sImageId);

	// Set the background image of the "sDivId" object to be the same as the image contained within that HTML element
	IlsGetStyle(sDivId).backgroundImage = "url(" + objImage.src + ")";
	
	// Make the image, inside the "sDivId" element, completely transparent
	IlsSetOpacity(sImageId, 0);
	
	// Change the image displayed in the image object to be "sImage"
	objImage.src = sImage;
	
	// Increase the opacity of the contained image in 100 discrete steps.  We do this by scheduling 100 separate invocations of IlsSetOpacity(), rather than wait in real time to
	// change the opacity at the appropriate time, so that this function can return to the caller right away.  This allows the user to click on links, fill in forms, etc., while
	// the images are blending.
	for (nPercent = 1; nPercent <= 100; nPercent++) { 
		setTimeout('IlsSetOpacity("' + sImageId + '", ' + nPercent + ')', (nPercent * nSpeed));
	}
} // IlsImageBlend


// IlsSlideshow(sDivId, sImageId, sImagePrefix, sImageList, nDurationBlend, nDurationShow)
//		sDivId			HTML ID of the "DIV" element that contains the image object, used for blending.
//		sImageId:		HTML ID of the image object, inside the "DIV" element, that displays each new image.
//		sImagePrefix:	Directory path prefix to be used in front of each image file name in "sIamgeList".  For example, "images/".  If none required, this should be the empty string.
//		sImageList:		List of image file names to be displayed, separated by commas.  Must have at least two images in the list, there should be no trailing comma, and there should
//						be no spaces after commas.  (These restrictions are imposed, rather than checking for these error conditions, because this function invokes itself, and the
//						additional overhead of checking for these error cases on each invocation isn't worth it.)
//		nDurationBlend:	Length of time, in milliseconds, during which each image blends into the next.
//		nDurationShow:	Length of time, in milliseconds, during which each image is displayed, not including blending time.
//	returns:			Nothing.
//
// Blends each image in "sImageList", one into the other, like a slideshow.  It then repeats the cycle, in an infinite loop.  Schedules this processing to occur in the background,
// however, so that the user can click on links, fill in forms, etc., while the slideshow progresses.  Requires that the page contain an HTML IMG element inside of an HTML DIV element
// (or other element that has a CSS "backgroundImage" property).  The CSS "background-repeat" property of the DIV element should be set to "no-repeat", the IMG element should have its
// "width" and "height" properties set to the width and height of each image that will be displayed (all images must be the same size), the IMG element should have a "src" property that
// specifies the static image to be displayed if JavaScript is not enabled (the slideshow effect requires JavaScript -- this "src" should be the same as the first image in "sImageList",
// so that the first image will be displayed sufficient time), and both the DIV and the IMG element should have "id" properties that are unique in the entire page.  In addition, the DIV
// and IMG elements should be all together on one line, to avoid an odd formatting problem (at least in IE 7) that adds a little extra unwanted whitespace below the image, if the IMG
// element is on a line by itself in the HTML file.  Here is an example line with DIV and IMG elements that will work:
//
//		<div id="SlideshowDiv" style="background-repeat: no-repeat;"><img id="SlideshowImage" width="400" height="320" src="images/sunset.jpg"></img></div>

function IlsSlideshow(sDivId, sImageId, sImagePrefix, sImageList, nDurationBlend, nDurationShow) 
{ 
	// Find the first comma in the list of images.  There should always be one, because we require, above, that there be at least two images in the list.
	var nPosSeparator = sImageList.indexOf(",");

	// Parse the first image file name from the front of the list, excluding the trailing comma
	var sImage = sImageList.substring(0, nPosSeparator);

	// Blend the currently-displayed image and the newly-displayed image, until the new image replaces the old
	IlsImageBlend(sDivId, sImageId, sImagePrefix + sImage, nDurationBlend);

	// Parse the remainder of the list of images, after the first comma.  There should be no spaces after that comma, because we disallow that in the documentation, above.
	var sFutureImages = sImageList.substring(nPosSeparator + 1, sImageList.length)+ "," + sImage;

	// Schedule this function to be invoked again, on the next image, after sufficient time has passed for the two images to blend ("nDurationBlend"), and the new image has been
	// displayed for the requested amount of time ("nDurationShow").  The reason we schedule the next invocation, rather than wait in real time to display the next image, so that this
	// function can return to the caller right away.  This allows the user to click on links, fill in forms, etc., while the slideshow progresses.
	setTimeout("IlsSlideshow('" + sDivId + "', '" + sImageId + "', '" + sImagePrefix + "', '" + sFutureImages + "', " + nDurationBlend + ", " + nDurationShow + ")", nDurationBlend + nDurationShow); 

	IlsPreloadImageDupes(sImagePrefix + sFutureImages.substring(0, sFutureImages.indexOf(",")));
} // IlsSlideshow