/*
	FILENAME: jsweld.rotator.js
	AUTHOR: Philip Siedow-Thompson (psiedow@co.weld.co.us)
	WRITTEN: 6/3/2009
	REVISIONS: caption no longer required - psiedow 12/18/2009
	DEPENDENCIES: prototype.js v.1.6.0 - (DO NOT USE ANY OTHER VERSION UNTIL TESTED!)
				  jsweld.wcDOM
				  jsweld.ajax
				  jsweld.animation;
*/


		/* 
			FUNCTION:
			DESCRIPTION:
			ARGUMENTS:
			RETURNS:
		*/

var jsweld;
	jsweld = (jsweld)?jsweld:{};
	jsweld.rotator = {};
	
	/*------------------------------------------------------------------------------------
		JSWELD.rotator.baseRotator - base class of all rotators
	--------------------------------------------------------------------------------------*/
	jsweld.rotator.baseRotator = Class.create(
	{
		/* 
			FUNCTION: constructor
			DESCRIPTION: base constructor
			ARGUMENTS: a_node - the rotator will be built in this node clearing any nodes.
						a_time - the time |b| rotations IN SEC!
		*/
		initialize: function(a_node, a_sec)
		{
			this.panes = new Array();
			this.index = 0;
			this.timer = null;
			
			this.node = a_node;
			this.time = (a_sec)?(1000*a_sec):null;
			this.changeMethod = function(a_max,a_current,a_delta)
			{
				var cNum = a_current + a_delta;
				
				if(cNum>a_max)cNum = 0;
				if(cNum<0)cNum = a_max;
				
				return cNum;
			}
		},
		
		/* 
			FUNCTION: setChangeMethod
			DESCRIPTION: Sets the change function (used to calculate what pane is displayed next)
			ARGUMENTS: a_function - a function
			RETURNS: the function has three numeric arguments max, current, delta.
						it should return an integer between 0 and max-1.
		*/
		setChangeMethod: function(a_function) {this.changeMethod = a_function;},
		
		/* 
			FUNCTION: addPane
			DESCRIPTION: pushes an object in the pane stack. The object should have string values for 'image' and 'caption'
			ARGUMENTS: a_obj -  an object
		*/
		addPane: function(a_obj) {this.panes.push(a_obj);},
		
		/* 
			FUNCTION: next
			DESCRIPTION: incraments and displays the rotator.
		*/
		next: function()
		{
			this.index = this.changeMethod(this.panes.length-1,this.index,1);
			this.draw();
		},
		
		/* 
			FUNCTION: previous
			DESCRIPTION: decraments and displays the rotator.
		*/
		previous: function()
		{
			this.index = this.changeMethod(this.panes.length-1,this.index,-1);
			this.draw();
		},
		
		/* 
			FUNCTION: draw
			DESCRIPTION: THIS IS AN ABSTRACT FUNCTION, subclasses should implement this function but not
							call the super class. This function should update the display of the rotator.
		*/
		draw: function(){throw new Error('draw is an abstract function and should not be called directly.')},
		
		/* 
			FUNCTION: start
			DESCRIPTION: starts the auto rotator. Must be called manually by the super class.
		*/
		start: function()
		{
			var thisRef = this;
			
			if(this.time)
			{
				if(this.timer!=null)
				{
					window.clearInterval(this.timer);
					this.timer = null;	
				}
			
				this.timer = window.setInterval(function(){thisRef.next();},this.time);	
			}
		}
	});
	
	/*------------------------------------------------------------------------------------
		JSWELD.rotator.imageAndText - a rotator that displays both an image and a description
	--------------------------------------------------------------------------------------*/
	jsweld.rotator.imageAndText = Class.create(jsweld.rotator.baseRotator,
	{
		/* 
			FUNCTION: constructor
			DESCRIPTION: base constructor
			ARGUMENTS: a_node - the rotator will be built in this node clearing any nodes.
						a_time - the time |b| rotations IN SEC!
						a_url - url to the xml file
		*/
		initialize: function($super,a_node, a_sec, a_url)
		{
			$super(a_node,a_sec);
			
			this.url = a_url;
			this.buildHTML();
			this.loadXML();
		},
		
		/* 
			FUNCTION: buildHTML (private-ish)
			DESCRIPTION: replaces the contents of the node with the rotators HTML.
		*/
		buildHTML: function()
		{
			var thisRef = this;
			jsweld.wcDOM.clearNode(this.node);
			
			this.imageNode = $(jsweld.wcDOM.createFromObject({element:'div', attributes:{className:'wiImageDisplay'}}));
			this.descriptionNode = $(jsweld.wcDOM.createFromObject({element:'div', attributes:{className:'wiImageDescription'}}));
			this.nextButtonNode = jsweld.wcDOM.createFromObject({element:'a', text:'next >', attributes:{className:'wiImageNextButton', href:'#', onclick:function(){thisRef.next(); return false;}}});
			this.prevButtonNode = jsweld.wcDOM.createFromObject({element:'a', text:'< previous', attributes:{className:'wiImagePrevButton', href:'#', onclick:function(){thisRef.previous(); return false;}}});
			
			this.tableNode = jsweld.wcDOM.createFromObject({element:'table', children:[
										 	{element:'tbody', children:[
												{element:'tr', children:[{element:'td', children:[{node:this.imageNode}]},{element:'td', children:[{node:this.descriptionNode}]}]},
												{element:'tr', children:[{element:'td', children:[{node:this.prevButtonNode}]},{element:'td', children:[{node:this.nextButtonNode}]}]}
											]}
										 ]});
			
			this.node.appendChild(this.tableNode);
		},
		
		/* 
			FUNCTION: loadXML (private-ish)
			DESCRIPTION: loads and parses the xml doc. If sucessfull, it initiates drawing.
		*/
		loadXML: function()
		{
			var thisRef = this;
			
			var xmlLoader = new jsweld.ajax.xmlDownload(this.url, function(a_document)
			{
				if(a_document!=null)
				{
					var imagesNode = a_document.firstChild;
					if(imagesNode.nodeName.toLowerCase()=="xml")imagesNode = imagesNode.nextSibling;
					
					for(var i=0; i<imagesNode.childNodes.length; i++)
					{
						var picNode = imagesNode.childNodes[i];
						if(picNode.nodeType==1 && picNode.nodeName.toLowerCase()=='pic')
						{
							var picObj = {};
							
							for(var j=0; j<picNode.childNodes.length; j++)
							{
								var nodeRef = picNode.childNodes[j];
								if(nodeRef.nodeType==1 && nodeRef.nodeName.toLowerCase()=='image')
								{
									picObj.image = (nodeRef.firstChild)?nodeRef.firstChild.nodeValue:'';
								}
								if(nodeRef.nodeType==1 && nodeRef.nodeName.toLowerCase()=='caption')
								{
									picObj.caption = (nodeRef.firstChild)?nodeRef.firstChild.nodeValue:'';
								}
								if(nodeRef.nodeType==1 && nodeRef.nodeName.toLowerCase()=='url')
								{
									picObj.url = (nodeRef.firstChild)?nodeRef.firstChild.nodeValue:'';
								}
							}
							
							if(picObj.image)thisRef.addPane(picObj);
						}
					}
					
					thisRef.draw();
					thisRef.start();
				}
				else throw new Error("The server did not return valid XML.");
			});
			
			xmlLoader.send();
		},
		
		/* 
			FUNCTION: draw (override)
			DESCRIPTION: updates the display.
		*/
		draw: function()
		{
			if(this.panes && this.panes.length>0)
			{
				var displayWidth = this.imageNode.getWidth();
				var imgNode = null;
				var displayRef = this.imageNode;
				var paneRef = this.panes[this.index];
				
				var onLoadCallback = function()
				{
					var animate = new jsweld.animation.animate(imgNode,jsweld.animation.interpolate.exponential,30);
						animate.animate({opacity:0},{opacity:1},1);
					if(!paneRef.url)displayRef.appendChild(imgNode);
					else displayRef.appendChild(jsweld.wcDOM.createFromObject({element:'a', attributes:{href:paneRef.url, target:'_blank'}, children:[{node:imgNode}]}));
				}
				jsweld.wcDOM.clearNode(this.imageNode);
				var imgNode = jsweld.wcDOM.createFromObject({element:'img', attributes:{onload:onLoadCallback}});
					imgNode.src = paneRef.image;	
					
				if(this.descriptionNode)
				{
					var caption = (paneRef.caption)?paneRef.caption:'';
					
					jsweld.wcDOM.clearNode(this.descriptionNode);
					this.descriptionNode.appendChild(document.createTextNode(caption));
					
					if(paneRef.url)
					{
						//this.descriptionNode.appendChild(jsweld.wcDOM.createFromObject({element:'br'}));
						this.descriptionNode.appendChild(jsweld.wcDOM.createFromObject({element:'a', attributes:{href:paneRef.url, target:'_blank'}, text:' More...'}));
					}
				}
			}
		}
	});
		
		
		
		
		
		
		
		
		
