/* JS OOP
http://javascript.crockford.com/inheritance.html
http://javascript.crockford.com/private.html
*/


// Slideshow object (Slideshow(imgid [, slidetimeout [, fadesteptimeout [,fadestep]]]))
function Slideshow(imgid, slidetimeout, fadesteptimeout, fadestep)
{
	// public vars
	this.imgid = imgid;
	this.slidetimeout = slidetimeout || 2000; // ms
	this.fadesteptimeout = fadesteptimeout || 100; // ms
	this.fadestep = fadestep || 10; // %


	// private vars
	var that = this;
	var preload = new Object();
	var showstate = 'stopped';
	var slidecount = 1; // slide to second image
	var slidestate = 'fadeout';
	var slideopacity = 100;
	var imgobj;
	var imgchck = 0;
	var imgchk_max = 50; // target image object has 5 seconds to load


	// run check
	checkImg();


	// privileged functions
	this.addImages = function ()
	{
		// preload all supplied images
		for (var i = 0, al = arguments.length; i< al; i++)
		{
			preload[i] = document.createElement('img');
			preload[i].setAttribute('src', arguments[i]);
		}
	}

	this.start = function ()
	{
		if (typeof(imgobj) == 'undefined')
		{	// checkImg() still running
			if (imgchck > imgchk_max)
			{	// never mind
				return false;
			}
			else
			{	// try again
				setTimeout(that.start, 50);
			}
		}
		else
		{	// (re)start slide show
			showstate = 'running';

			// to stop
			imgobj.onclick = that.stop;
			imgobj.title = 'Click to stop slideshow.';
			imgobj.alt = 'Click to stop slideshow.';

			// start loop
			window.setTimeout(that.next, slidetimeout);
		}
	}

	this.next = function ()
	{
		if (showstate == 'stopped') return false; // test

		var timeout = that.fadesteptimeout; // default

		// apply effect
		if (slidestate == 'fadeout')
		{	// fade out
			slideopacity -= that.fadestep;
			setOpacity(imgobj, slideopacity);

			// switch state
			if (slideopacity <= 0) slidestate = 'switch';
		}
		else if (slidestate == 'switch')
		{	// switch source file
			imgobj.setAttribute('src', preload[slidecount].getAttribute('src'));

			// add counter
			slidecount++;
			if (!preload[slidecount]) slidecount = 0; // reset

			// switch state
			slidestate = 'fadein';
		}
		else if (slidestate == 'fadein')
		{	// fade in
			slideopacity += that.fadestep;
			setOpacity(imgobj, slideopacity);

			if (slideopacity >= 100 && showstate == 'running')
			{	// end fade in
				slidestate = 'fadeout';

				if (showstate == 'running')
				{	// start wait till next slidechange
					timeout = that.slidetimeout;
				}

				if (showstate == 'stopping')
				{	// slideshow stopped
					showstate == 'stopped'

					// stop function
					return false;
				}
			}
		}

		// next loop
		window.setTimeout(that.next, timeout);
	}

	this.stop = function ()
	{
		// prepare to stop
		//showstate = 'stopping';

		// ??? stop immediately
		showstate = 'stopped';
		slidestate = 'fadeout';
		slideopacity = 100;
		setOpacity(imgobj, slideopacity);

		// to start again
		imgobj.onclick = that.start;
		imgobj.title = 'Click to start slideshow.';
		imgobj.alt = 'Click to start slideshow.';
	}


	// private function
	function checkImg()
	{	// check if target image exists and has loaded
		if (imgchck > imgchk_max)
		{	// really can't find it
			alert('Image: '+that.imgid+' not found!');
			return false;
		}
		else if (!document.getElementById(that.imgid))
		{	// try again
			imgchck++;
			window.setTimeout(checkImg, 100);
		}
		else
		{	// load complete
			imgobj = document.getElementById(that.imgid);

			// to start
			imgobj.onclick = that.start;
			imgobj.title = 'Click to start slideshow.';
			imgobj.alt = 'Click to start slideshow.';
		}
	}

	function setOpacity(obj, opacity)
	{	// cross-browser opacity setter
		// source: http://clagnut.com/sandbox/imagefades/
		opacity = (opacity == 100)?99.999:opacity;

		// IE/Win
		obj.style.filter = 'alpha(opacity:'+opacity+')';

		// Safari<1.2, Konqueror
		obj.style.KHTMLOpacity = opacity/100;

		// Older Mozilla and Firefox
		obj.style.MozOpacity = opacity/100;

		// Safari 1.2, newer Firefox and Mozilla, CSS3
		obj.style.opacity = opacity/100;
	}
} // end Slideshow()

