/**
 * @author Daniel Sommer <d.sommer@zinzius.de>
 * 
 * (c) 2009 Zinzius GmbH, Lizenz siehe http://www.zinzius.de/footer/agb/
 */

var slideDebugCount = 0;

function zinSlideShowImage(parentInstance, parentArrayIndex, parameters) {
	
	this.parameters = parameters;
	var isPreloaded = false;
	this.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) {
			this.imgObject.setAttribute(
				'onload', parentInstance.instanceName + ".imageLoaded(" + parentArrayIndex + ")"
			);
			this.imgObject.src = parameters.filePath;
		}
	};

	this.fadeIn = function(id) {
		// this.write('instance #' + parentArrayIndex + ", img src '" + this.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);
		
		// 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);
		
		dojo.fx.wipeIn(
			{
				node	:	dojo.byId(id),
				duration:	1
			}
		).play();
		
		// set onload handler
		var instanceName = parentInstance.getInstanceName();
		
		// load the image
		if(this.isPreloaded) {
			imgNode.src = this.imgObject.src;
		} else {
			imgNode.setAttribute(
					'onload',
					imgNode.getAttribute('onload') + ';'
					+ instanceName + ".debug('triggered fadeIn for #" + parentArrayIndex + "');" + '' 
					// instanceName + ".getFadeIn().play()"
			);
			imgNode.src = this.imgObject.src;
		}
		
		// set a timeout to fade out the image
		var fadeOutTime = parameters.duration;
		if(fadeOutTime < 1) fadeOutTime = 5000;
		
		// set event links
		if(parameters.eventAttrs) {
			for(var i in parameters.eventAttrs) {
				var titleElement = parentInstance.getTitleElement();
				if(titleElement) {
					titleElement.setAttribute(i, parameters.eventAttrs[i]);
					titleElement.style.cursor = 'pointer';
					// $('zinSlideShow_title').
					Element.addClassName($('zinSlideShow_title'), 'eventLink');
				}
				Element.addClassName($(id),'eventLink');
				imgNode.setAttribute(i, parameters.eventAttrs[i]);
			}
		}
		
		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 this.imgObject.src;
	};
	
	this.isLoaded = function() {
		return isPreloaded;
	};
	
	this.setLoaded = function(val) {
		isPreloaded = val;
	};
		
}



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 = Math.pow(2, 31) - 1;
	
	// 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<br>" + bla.innerHTML;
		}
	};
	
	this.debug = function(msg) {
		debug(msg);
	};
	
	/******************************************************************/
	
	this.getFadeIn = function() { 
		return this.fadeIn;
	};
	
	/******************************************************************/
	
	this.getFadeOutId = function() {
		return this.fadeOutId;
	};
		
	/******************************************************************/
	
	this.getInstanceName = function() {
		return this.instanceName;
	};
	
	/******************************************************************/
	
	this.getTitleElement = function() {
		return document.getElementById(instanceName + "_title");
	};
	
	/******************************************************************/
	
	this.hotlink = function() {
		images[imageIterator].fireLink();
	};
	
	/******************************************************************/
	
	this.imageLoaded = function(imgId) {
		debug("setting to loaded: " + imgId);
		images[imgId].setLoaded(true);
	};
	
	/******************************************************************/
	
	this.initiateFadeOut = function(imgId) {
		if (images.length < 2) return;
		fadeOut('zinSlideShowImg' + flipper);
		triggerNextImage();
	};
	
	/******************************************************************/
	
	this.isPaused = function() {
		return isPaused == true;
	};
	
	/******************************************************************/
	
	this.start = function(id) {
		build(id + "_pics");
		triggerNextImage();
		setTimeout(instanceName + ".preload()", 2500);
	};
	
	/******************************************************************/
	
	this.pause = function() {
		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() {
		
		var tmpIterator = imageIterator - 2;
		if(tmpIterator < 0) {
			tmpIterator = images.length + tmpIterator;
		}
		if(!images[tmpIterator].isLoaded()) {
			return;
		}
		
		// 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() {
		debug('next image id: ' + getNextImageId());
		if(!images[getNextImageId()].isLoaded()) {
			debug('load process for img#' + getNextImageId() + ' incomplete, aborting!');
			return;
		} else {
			debug('load process for img#' + getNextImageId() + ' is marked as complete, showing next');
		}
		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);
		slideDebugCount++;
		var fadeOut = dojo.fx.chain(
			[
				dojo.fadeOut(
				{	node:		targetId,
					duration:	1000
				}),
				dojo.fx.wipeOut(
				{
					node:		targetId,
					duration:	1
				})
			]
		);
		fadeOut.play();
	};
	
	/******************************************************************/
	
	getNextImageId = function() {
		return imageIterator + 1 < images.length
		?	imageIterator + 1
		:	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];
		deb_pic = img;
		
		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;
			}
		}
		
	};
	
}
var deb_pic;
