/*
	Source: classbehaviours.handlers.spriteAnimation.js
	ClassBehaviours is a javascript framework based on class-name parsing.
	Copyright 2011 by Maurice van Creij and published on http://www.woollymittens.nl/
	This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
*/

	// CLASSBEHAVIOURS CLASS
	// create the root classbehaviours object if it doesn't already exist
	if(typeof(classBehaviours)=='undefined') classBehaviours = {};

		// CLASSNAME BEHAVIOUR FUNCTIONS
		// create the handlers child object if it doesn't already exist
		if(typeof(classBehaviours.handlers)=='undefined') classBehaviours.handlers = {}

			// we don't want this running twice
			if(typeof(classBehaviours.handlers.spriteAnimation)=='undefined'){

				// runs through a sequence of class names
				classBehaviours.handlers.spriteAnimation = {
					// properties
					name: 'spriteAnimation',
					index: 0,
					timeout: null,
					msie6: (navigator.userAgent.indexOf('MSIE 6')>-1),
					// methods
					start: function(node){
						// give an id if the item has none
						node.id = (node.id) ? node.id : this.name + this.index++ ;
						// add a default classname
						classBehaviours.utilities.setClassParameter(node, 'busy', 'no');
						// see if mouse interaction is required
						playOnLoad = classBehaviours.utilities.getClassParameter(node, 'load', null);
						playOnFocus = classBehaviours.utilities.getClassParameter(node, 'focus', null);
						playOnBlur = classBehaviours.utilities.getClassParameter(node, 'blur', null);
						playOnClick = classBehaviours.utilities.getClassParameter(node, 'click', null);
						// set the default parameters
						classBehaviours.utilities.setClassParameter(node, 'start', 0);
						classBehaviours.utilities.setClassParameter(node, 'step', 0);
						classBehaviours.utilities.setClassParameter(node, 'end', 0);
						classBehaviours.utilities.setClassParameter(node, 'loop', 0);
						// set the event handlers
						if(playOnClick) node.onclick = this.clickToPlay;
						if(playOnFocus){
							node.onmouseover = this.focusToPlay;
							node.onfocus = this.focusToPlay;
						}
						if(playOnBlur){
							node.onmouseout = this.blurToPlay;
							node.onblur = this.blurToPlay;
						}
						if(playOnLoad) this.loadToPlay(node);
					},
					loop: function(animId){
						var acn = classBehaviours.handlers.spriteAnimation;
						// get the target node
						animNode = document.getElementById(animId);
						// get the animation properties
						animationStart = parseInt(classBehaviours.utilities.getClassParameter(animNode, 'start', '0'));
						animationStep = parseInt(classBehaviours.utilities.getClassParameter(animNode, 'step', '0'));
						animationEnd = parseInt(classBehaviours.utilities.getClassParameter(animNode, 'end', '3'));
						animationLoop = parseInt(classBehaviours.utilities.getClassParameter(animNode, 'loop', animationEnd));
						animationRate = parseInt(classBehaviours.utilities.getClassParameter(animNode, 'rate', '50'));
						animationTimeout = parseInt(classBehaviours.utilities.getClassParameter(animNode, 'timeout', '0'));
						animationId = classBehaviours.utilities.getClassParameter(animNode, 'id', null);
						animationName = classBehaviours.utilities.getClassParameter(animNode, 'name', null);
						// cancel any remaining timeouts
						clearTimeout(animationTimeout);
						// get an alternate target of the animation if required
						animationTarget = (animationId!=null) ? (animationId!='next') ? document.getElementById(animationId) : classBehaviours.utilities.nextNode(animNode) : animNode;
						// get the next animation step
						nextAnimationStep = (animationStep<animationEnd) ? animationStep+1 : animationLoop ;
						// particularly slow browers get to skip the whole animation
						if(acn.msie6) nextAnimationStep = animationEnd;
						// set the animation name in the target
						if(animationName!=null){
							classBehaviours.utilities.setClassParameter(animationTarget, 'name', animationName);
						}
						// set the next animation step
						if(animationStep!=nextAnimationStep){
							// update the step count
							classBehaviours.utilities.setClassParameter(animationTarget, 'step', nextAnimationStep);
							// store the current step
							if(animationTarget!=animNode) classBehaviours.utilities.setClassParameter(animNode, 'step', nextAnimationStep);
							// order the next update
							animationTimeout = (nextAnimationStep!=animationStep) ? setTimeout('classBehaviours.handlers.spriteAnimation.loop("'+animId+'")', animationRate) : null ;
							// store the timeout
							classBehaviours.utilities.setClassParameter(animNode, 'timeout', animationTimeout);
						}
						// if there is no next step do some end housekeeping
						else{
							// swap around the click and reclick animations
							if(animNode.className.indexOf(' reclick_')>-1){
								animNode.className = animNode.className.replace(' click_', ' splurn_');
								animNode.className = animNode.className.replace(' reclick_', ' click_');
								animNode.className = animNode.className.replace(' splurn_', ' reclick_');
							}
						}
					},
					reset: function(objNode, animationSettings){
						var acn = classBehaviours.handlers.spriteAnimation;
						// get the animation settings
						currentSettings = classBehaviours.utilities.getClassParameter(objNode, 'start', '0') + ',';
						currentSettings += classBehaviours.utilities.getClassParameter(objNode, 'end', '0') + ',';
						currentSettings += classBehaviours.utilities.getClassParameter(objNode, 'loop', '0');
						// if this isn't a double
						if(currentSettings != animationSettings.join() || objNode.className.indexOf('click_')>-1){
							// set the animation settings
							classBehaviours.utilities.setClassParameter(objNode, 'start', animationSettings[0]);
							classBehaviours.utilities.setClassParameter(objNode, 'step', animationSettings[0]);
							classBehaviours.utilities.setClassParameter(objNode, 'end', animationSettings[1]);
							classBehaviours.utilities.setClassParameter(objNode, 'loop', animationSettings[2]);
							// start the animation
							classBehaviours.handlers.spriteAnimation.loop(objNode.id);
						}
					},
					// events
					loadToPlay: function(that){
						var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
						// get the animation settings
						animationSettings = classBehaviours.utilities.getClassParameter(objNode, 'load', '0_0_0').split('_');
						// if there isn't already interaction, reset the animation
						classBehaviours.handlers.spriteAnimation.reset(objNode, animationSettings);
					},
					clickToPlay: function(that){
						var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
						// get the animation settings
						animationSettings = classBehaviours.utilities.getClassParameter(objNode, 'click', '0_0_0').split('_');
						// if there isn't already interaction, reset the animation
						classBehaviours.handlers.spriteAnimation.reset(objNode, animationSettings);
						// if the click needs to be canceled
						return !(classBehaviours.utilities.getClassParameter(objNode, 'cancel', 'no')=='yes');
					},
					focusToPlay: function(that){
						var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
						// get the animation settings
						animationSettings = classBehaviours.utilities.getClassParameter(objNode, 'focus', '0_0_0').split('_');
						animationTimeout = classBehaviours.utilities.getClassParameter(objNode, 'mousefilter', '0');
						animationRate = parseInt(classBehaviours.utilities.getClassParameter(objNode, 'rate', '50'));
						// reset the animation
						clearTimeout(parseInt(animationTimeout));
						// order a new animation
						animationTimeout = setTimeout('classBehaviours.handlers.spriteAnimation.reset(document.getElementById("' + objNode.id + '"), new Array(' + animationSettings.join() + '));', animationRate);
						// store its timeout
						classBehaviours.utilities.setClassParameter(objNode, 'mousefilter', animationTimeout);
					},
					blurToPlay: function(that){
						var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
						// get the animation settings
						animationSettings = classBehaviours.utilities.getClassParameter(objNode, 'blur', '0_0_0').split('_');
						animationTimeout = classBehaviours.utilities.getClassParameter(objNode, 'mousefilter', '0');
						animationRate = classBehaviours.utilities.getClassParameter(objNode, 'rate', '50');
						// reset the animation
						clearTimeout(parseInt(animationTimeout));
						// order a new animation
						animationTimeout = setTimeout('classBehaviours.handlers.spriteAnimation.reset(document.getElementById("' + objNode.id + '"), new Array(' + animationSettings.join() + '));', animationRate);
						// store its timeout
						classBehaviours.utilities.setClassParameter(objNode, 'mousefilter', animationTimeout);
					}
				}

				// sets an alternative target for the click event
				classBehaviours.handlers.deferClick = {
					// properties
					name: 'deferClick',
					// methods
					start: function(node){
						node.onclick = this.clicked;
					},
					// events
					clicked: function(that){
						var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
						var acn = classBehaviours.handlers.spriteAnimation;
						// where do we want this click defered to
						targetId = classBehaviours.utilities.getClassParameter(objNode, 'id', null);
						targetNode = document.getElementById(targetId);
						// triger the click event
						acn.clickToPlay(targetNode);
						// cancel the clicked link
						return false;
					}
				}

			}

	// JQUERY WRAPPER
	if(typeof(jQuery)!='undefined'){
		(function($){
			var methods = {
				init : function(options) {
					return this.each(function(){
						classBehaviours.handlers.spriteAnimation.start($(this).context);
					});
				},
				deferClick : function(){
					return this.each(function(){
						classBehaviours.handlers.deferClick.start($(this).context);
					});
				}
			};
			$.fn.spriteAnimation = function(method){
				if(methods[method]) {
					return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
				}else if(typeof method === 'object' || !method){
					return methods.init.apply(this, arguments);
				}else{
					$.error('Method ' +  method + ' does not exist on jQuery.spriteAnimation');
				}
			};
		})(jQuery);

		// JQUERY EVENTS
		$(document).ready(function() {
			$(".spriteAnimation").spriteAnimation();
			$(".deferClick").spriteAnimation('deferClick');
		});

		/* DIRECT APPLICATION
		$(".linkButton").addClass('spriteAnimation focus_0_5_5 blur_6_9_9');
		$(".linkButton").spriteAnimation();
		*/
	}

