/**
* The old API calls usually look something like this:
* 	InitCrossFade('crossfade_2',
* 	'<a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewTVSeason?id=200649328&amp;s=143441" class="fader2"><img src="http://a1.phobos.apple.com/r10/Features/c1/4d/e9/dj.qctmxhhq.jpg" alt="Flavor of Love" width="248" height="140" border="0"></a>',
* 	'<a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewMovie?id=201202523&amp;s=143441" class="fader2"><img src="http://a1.phobos.apple.com/r10/Features/a0/d8/c2/dj.uddjpmoe.jpg" alt="25th Hour" width="248" height="140" border="0"><\/a>',
* 	'<a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewAlbum?id=200656424&amp;s=143441" class="fader2"><img src="http://a1.phobos.apple.com/r10/Features/28/77/8f/dj.exsxnhqu.jpg" alt="Lemony Snicket" width="248" height="140" border="0"><\/a>',
* 	'<a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewAlbum?id=201813288&amp;s=143441" class="fader2"><img src="http://a1.phobos.apple.com/r10/Features/55/d7/b2/dj.zfzfvwdz.jpg" alt="Robbie Williams" width="248" height="140" border="0"><\/a>'
* 	);
* 
* we're trying to get away from that format in favor of the blissfully simple:
*
* 	new AC.CrossfadeQueue(nodesArray, container, displayTime, queueName);
*
* where 
* - nodes is an array of HTML to crossfade between	
* - container is a reference to any block element to use as a container in the DOM
* - displayTime is a float specifying how long (in seconds) to hold when displaying each node
* - queueName is a specification for an independent animation queue
*
* 
* AC.CrossfadeQueue wraps this old call (see below) and deals with it but use the new call wherever possible
*
*
* TODO
* - create a generic crossfadable container object that you can make and drop into the queue?
*
* - there is still an occasional BUG on mouse out where the element can re-enter the queue after itself 
*   creating a double fade effect...
*
*/

if (typeof(AC) == "undefined") AC = {};

AC.CrossfadeQueue = Class.create();
AC.CrossfadeQueue.prototype = {
	index: 0, queue: null, container: null, scope: null, safetyDiv: null, delay: 6.0,
	fadeInTime: 0.5, fadeOutTime: 0.5,
	defaultQueueName: "defaultXFadeQueue",
	currentNode: null,
	stopped: false,
	initialize: function(nodes, container, delay, queueName, fadeInTime, fadeOutTime) {
		this.container = $(container);
		this.scope = container;
		this.queue = nodes;
		this.container.innerHTML = "";
		this.safetyDiv = document.createElement("div");
		this.container.appendChild(this.safetyDiv);
		Element.setStyle(this.safetyDiv, { position:"relative" });

		if(Element.getStyle(this.container, 'position') == 'static') {
			Element.setStyle(this.container, { position:"relative" });
		}
		
		if (delay) this.delay = delay;
		if (queueName) this.defaultQueueName = queueName;
		if (fadeInTime) this.fadeInTime = fadeInTime;
		if (fadeOutTime) this.fadeOutTime = fadeOutTime;
		

		this.next();
		
	},
	
	pauseTimeStamp: null,
	pause: function() {
			this.pauseTimeStamp = new Date().getTime();	
			var queue = Effect.Queues.get(this.defaultQueueName);

			// clear the animation's interval to stop it
			if (queue.interval) clearInterval(queue.interval);	
			Element.setOpacity(this.currentNode, 1.0);		
	},

	stop: function() {
		this.stopped = true;
		this.pause();
	},
	
	play: function() {
		this.stopped = false;
		this.resume();
	},

	resume: function() {
		
		if (this.stopped) {
			return;
		}
		
		var queue = Effect.Queues.get(this.defaultQueueName);
		
		// kickstart the queue again, delaying each by however long the user has lingered...
		var delay = new Date().getTime() - this.pauseTimeStamp;
		queue.each(function(e) { 
			e.startOn  += delay;
		    e.finishOn += delay;
		});
		queue.interval = setInterval(queue.loop.bind(queue), 40);
	},
	
	remove: function(element) {
		Element.remove(element);
	},
	
	next: function() {
		if (this.index > this.queue.length-1) this.index = 0; // just to loop back to the start
		
		if (this.currentNode) {
			
			new Effect.Opacity(this.currentNode, { duration: this.fadeOutTime, transition: Effect.Transitions.linear, 
		    	from: 1.0, to: 0.0, // queue: { position:'end', scope: this.defaultQueueName },
				afterFinish: this.remove.bind(this, this.currentNode)
			});

			this.currentNode = this.createNode();

			new Effect.Opacity(this.currentNode, { duration: this.fadeInTime, transition: Effect.Transitions.linear, 
			    from: 0.0, to: 1.0, queue: { position:'end', scope: this.defaultQueueName + "_in" }
			});
			
		}
		else {
			this.currentNode = this.createNode();
			Element.setOpacity(this.currentNode, 1.0);
		}
		
		new Effect.Wait( this.currentNode, { duration: this.delay, 
		    queue: { position:'end', scope: this.defaultQueueName},
			afterFinish: this.next.bind(this)
		});
		
		this.index ++;
	},
	
	createNode: function() {
		var node = this.queue[this.index];
			
		if(typeof(node) == 'string') {
			node = document.createElement('div');
			node.innerHTML = this.queue[this.index];
		} 
		
		Element.setOpacity(node, 0.0);
		
		// i don't want to set too many styles here but
		// if the position isn't absolute it won't render
		// the safetyDiv is a throwaway to make sure we're 
		// in a block element 
		Element.setStyle(node, { position: "absolute" });
		Element.addClassName(node,'ACCrossfadeQueueElement');
		
		Element.observe(node, "mouseover", this.pause.bind(this), true);
		Element.observe(node, "mouseout", this.resume.bind(this), true);
		
		//node.onmouseover = this.pause.bindAsEventListener(this);
		//node.onmouseout = this.resume.bindAsEventListener(this);
		
		this.safetyDiv.appendChild(node);
		
		return node;
	}
}

// maintains the old API, called with a DOM object as the first arg
// then 1 or more HTML snippets as strings
function InitCrossFade() {
	if(arguments.length > 0) {		
		var nodes = $A(InitCrossFade.arguments);
		var objectReference = nodes.shift();
		var holdTime = (typeof(nodes[nodes.length-1]) == "number") ? nodes.pop(): Math.floor(Math.random()*5) + 3;
		
		new AC.CrossfadeQueue(nodes, objectReference, holdTime); // last arg is queue name		
	}
}

