var slideDebugCount = 0;

function zinSlideShowImage(parentInstance, parentArrayIndex, parameters) {
	
	this.parameters = parameters;
	var isPreloaded = false;
	var imgObject = new Image();
	
	/**
	 * The parent array index is used for the object's references in the zinSlideShow object. It is used for
	 * setting the fadeOut timeout. 
	 */
	var parentArrayIndex = parentArrayIndex;
	
	var parentInstance = parentInstance;
	
	/**
	 * Current parameters:
	 *  - filePath
	 *  - duration
	 *  - altText
	 *  - title
	 */
	//var parameters;
	
	this.write = function(msg) {
		parentInstance.debug(msg);
	}
	
	this.preload = function() {
		if (!isPreloaded) {
			parentInstance.debug('preloading #' + parentArrayIndex);
			imgObject.src = parameters.filePath;
		}
	}
	

	this.fadeIn = function(id) {
		// this.write('instance #' + parentArrayIndex + ", img src '" + imgObject.src + "', fading in... on id '" + id + "'<br>");
		
		// IE FIX:
		// - the onload function is not called this way, so let's try creating a new <img> node
		//   every time...
		var target = document.getElementById(id);
		var otherId = id.substring(0, id.length - 1) + 
			Math.abs(1 - id.substring(id.length - 1));
		
		var parent = target.parentNode;
		var alternateParent = document.getElementById(otherId).parentNode;
		
		/// EXPERIMENTAL: 

		// - The IE seems irritated when the 1st <div> should be faded in, so we ensure that
		//   it's always the last element that's faded in (experimental...)
		
		var grandparent = parent.parentNode;
		
		// remove target's parent
		grandparent.removeChild(parent);
		
		// create a new parent 
		parent = document.createElement('div');
		parent.setAttribute('class', 'pic');
		
		// IE FIX:
		parent.setAttribute('className', 'pic');
		grandparent.insertBefore(parent, alternateParent);
		//*/ // END OF EXPERIMENTAL FIX
		
		// remove target
		// parent.removeChild(target);

		// create a new node
		var imgNode = document.createElement('img');
		imgNode.setAttribute('class', 'zinSlideShowImage');
		// IE-Style:
		imgNode.setAttribute('className', 'zinSlideShowImage');
		imgNode.setAttribute('id', id);
		
		imgNode.style.position = 'absolute';
		parentInstance.imageZIndex--;
		imgNode.style.zIndex = parentInstance.imageZIndex;
		
		// add the node to the document
		parent.appendChild(imgNode);
		
		// set onload handler
		var instanceName = parentInstance.getInstanceName();
		// imgNode.onload = instanceName + '.getFadeIn().play()';
		
		// load the image
		if(imgObject.complete) {
			imgNode.src = imgObject.src;
			// parentInstance.getFadeIn().play();
			// parentInstance.debug('imgObject #' + parentArrayIndex + ' already loaded, fading in!');
		} else {
			// parentInstance.debug('setting onload event...');
			imgNode.setAttribute(
					'onload',
					instanceName + ".debug('triggered fadeIn for #" + parentArrayIndex + "');" + '' 
					// instanceName + ".getFadeIn().play()"
			);
			imgNode.src = imgObject.src;
		}
		
		// set a timeout to fade out the image
		var fadeOutTime = parameters.duration;
		if (fadeOutTime < 1) fadeOutTime = 5000;
		
		if (!parentInstance.isPaused()) {
			parentInstance.setFadeOutId(setTimeout(parentInstance.instanceName + ".initiateFadeOut(" + parentArrayIndex + ")", fadeOutTime));
		}
	}
	
	
	this.fireLink = function() {
		if(this.parameters.link) {
			location.href = this.parameters.link;
		}
	}
	
	
	this.getSrc = function() {
		return imgObject.src;
	}
		
}



function zinSlideShow(instanceName) {
	
	// attribute to store zinSlideShowImage objects
	var images = new Array();
	
	// iterator for images attribute
	var imageIterator = -1;
	
	// this var is flipped internally to store the target images' ID
	var flipper = 0;
	
	// array of two img elements
	var img;
	
	// the variable name of the instance, used for setting the timeout in 
	// zinSlideShowImage
	this.instanceName = instanceName;
	
	// an internal flag used to store whether pause has been activated. In this case, 
	// the next image button should only cause a single change of the displayed image
	var isPaused = false;
	
	this.fadeOutId = -1;
	this.fadeInId = -1;
	
	// incrementing z-index of the active picture
	this.imageZIndex = 9900;
	
	// stores the dojo transition objects
	this.fadeIn;
	this.fadeOut;
	
	/******************************************************************/
	
	this.addImage = function(parameters) {
		images.push(new zinSlideShowImage(this, getImageCount(), parameters));
	}
	
	/******************************************************************/
	
	debug = function(msg) {
		var bla = document.getElementById('debugElement');
		if (bla) {
			bla.innerHTML += msg + "\n";
		}
	}
	
	this.debug = function(msg) {
		var bla = document.getElementById('debugElement');
		if (bla) {
			bla.innerHTML += msg + "\n";
		}
	}
	
	/******************************************************************/
	
	this.getFadeIn = function() { 
		return fadeIn;
	}
	
	/******************************************************************/
	
	this.getFadeOutId = function() {
		return this.fadeOutId;
	}
		
	/******************************************************************/
	
	this.getInstanceName = function() {
		return this.instanceName;
	}
	
	/******************************************************************/
	
	this.hotlink = function() {
		images[imageIterator].fireLink();
	}
	
	/******************************************************************/
	
	this.initiateFadeOut = function(imgId) {
		if (images.length < 2) return;
		fadeOut('zinSlideShowImg' + flipper);
		triggerNextImage();
	}
	
	/******************************************************************/
	
	this.isPaused = function() {
		this.debug("isPaused() returns: " + isPaused);
		return isPaused == true;
	}
	
	/******************************************************************/
	
	this.start = function(id) {
		build(id + "_pics");
		triggerNextImage();
		setTimeout(instanceName + ".preload()", 2500);
	}
	
	/******************************************************************/
	
	this.pause = function() {
		this.debug('pause triggered!');
		isPaused = true;
		clearTimeout(this.getFadeOutId());
	}
	
	/******************************************************************/
	
	this.play = function() {
		isPaused = false;
		this.initiateFadeOut(imageIterator);
	}
	
	/******************************************************************/
	
	this.preload = function() {
		for (var i = 0; i < images.length; i++) {
			images[i].preload();
		}
	}
	
	/******************************************************************/
	
	this.previous = function() {
		// clear the timeout, will be set by fadeIn which is called by 
		// triggerNextImage
		clearTimeout(this.getFadeOutId());
		// decrease by two, since triggerNextImage will increase it by 1
		imageIterator -= 2;
		if (imageIterator < 0) {
			imageIterator = images.length + imageIterator;
		}
		// call fade effects
		fadeOut('zinSlideShowImg' + flipper);
		triggerNextImage();
	}
	
	/******************************************************************/
	
	this.next = function() {
		clearTimeout(this.getFadeOutId());
		fadeOut('zinSlideShowImg' + flipper);
		triggerNextImage();
	}
	
	/******************************************************************/
	
	this.setFadeOutId = function(id) {
		this.fadeOutId = id;
	}
	
	/******************************************************************/
	
	build = function(targetId) {
		var tmpHtml = '<div class="pic"><img id="zinSlideShowImg1" class="zinSlideShowImage" src="clear.gif" /></div>'
		+	'<div class="pic"><img id="zinSlideShowImg0" class="zinSlideShowImage" src="clear.gif" /></div>';
		document.getElementById(targetId).innerHTML = tmpHtml;
		if(images.length > 0) {
			images[0].preload();
		}
	}
	
	/******************************************************************/
	
	fadeOut = function(targetId) {
		this.debug('fading out #' + imageIterator + ' on id: ' + targetId);
		// document.getElementById('debugImg').innerHTML += '<img id="debImg' + slideDebugCount + '" width="64" height="48" />';
		// document.getElementById('debImg' + slideDebugCount).src = images[imageIterator].getSrc();
		slideDebugCount++;
		var fadeOut = dojo.fadeOut(
				{	node:		targetId,
					duration:	1000
				}
		);
		fadeOut.play();
	}
	
	/******************************************************************/
	
	getNextImageId = function() {
		return imageIterator < images.length
		?	imageIterator
		:	0
		;
	}
	
	/******************************************************************/
	
	getImageCount = function() {
		return images.length == undefined || images.length == 'undefined' 
		?
			0
		:
			images.length;
	}
	
	/******************************************************************/
	
	this.preloadNext = function() {
		preloadNext();
	}
	preloadNext = function() {
		images[getNextImageId()].preload();
	}
	
	/******************************************************************/
	
	triggerNextImage = function() {
		
		flipper = Math.abs(1 - flipper);
		imageIterator++;
		
		if (imageIterator >= images.length) {
			imageIterator = 0;
		} 
		//console.log('image iterator is now: ' + imageIterator + ", flipper is now: " + flipper);
		
		// images[imageIterator].preload();
		
		var targetId = 'zinSlideShowImg' + flipper;
		var img = images[imageIterator];
		
		// document.getElementById(targetId).src = images[imageIterator].imgObject.src;

		/*/
		this.fadeIn = new dojo.fadeIn(
			{	node:		targetId,
				duration:	1000
			}
		);
		/*
		this.fadeIn = dojo.fx.chain(
				dojo.fadeOut ({
						node:		targetId,
						duration:	1
				}),
				dojo.fadeIn ({
						node:		targetId,
						duration:	1000
				})
		);
		//*/
		
		images[imageIterator].fadeIn(targetId);
		
		if (typeof img.parameters.title != 'undefined') {
			var tmpTitle = document.getElementById(instanceName + "_title");
			if (tmpTitle) {
				tmpTitle.innerHTML = img.parameters.title;
			}
		}
		if (typeof img.parameters.details != 'undefined') {
			var tmpDetails = document.getElementById(instanceName + "_details");
			if (tmpDetails) {
				tmpDetails.innerHTML = img.parameters.details;
			}
		}
		
	}
	
}
