/*
	name			: ClassBehaviours, the javascript framework based on class-name parsing
	update			: 9.11.9
	author			: Maurice van Creij
	dependencies	: jquery.classbehaviours.js
	info			: http://www.classbehaviours.com/

    This file is part of jQuery.classBehaviours.

    ClassBehaviours is a javascript framework based on class-name parsing.
    Copyright (C) 2008  Maurice van Creij

    ClassBehaviours is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    ClassBehaviours is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with ClassBehaviours. If not, see http://www.gnu.org/licenses/gpl.html.
*/

	// create the jQuery object if it doesn't already exist
	if(typeof(jQuery)=='undefined') jQuery = function(){};

	// create the root classbehaviours object if it doesn't already exist
	if(typeof(jQuery.classBehaviours)=='undefined') jQuery.classBehaviours = function(){};

	// create the handlers child object if it doesn't already exist
	if(typeof(jQuery.classBehaviours.handlers)=='undefined') jQuery.classBehaviours.handlers = function(){}

	// we don't want this running twice
	if(typeof(jQuery.classBehaviours.handlers.animatedClassName)=='undefined'){
		// runs through a sequence of class names
		jQuery.classBehaviours.handlers.animatedClassName = {
			// properties
			name: 'animatedClassName',
			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
				jQuery.classBehaviours.utilities.setClassParameter(node, 'busy', 'no');
				// see if mouse interaction is required
				playOnLoad = jQuery.classBehaviours.utilities.getClassParameter(node, 'load', null);
				playOnFocus = jQuery.classBehaviours.utilities.getClassParameter(node, 'focus', null);
				playOnBlur = jQuery.classBehaviours.utilities.getClassParameter(node, 'blur', null);
				playOnClick = jQuery.classBehaviours.utilities.getClassParameter(node, 'click', null);
				// set the default parameters
				jQuery.classBehaviours.utilities.setClassParameter(node, 'start', 0);
				jQuery.classBehaviours.utilities.setClassParameter(node, 'step', 0);
				jQuery.classBehaviours.utilities.setClassParameter(node, 'end', 0);
				jQuery.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 = jQuery.classBehaviours.handlers.animatedClassName;
				// get the target node
				animNode = document.getElementById(animId);
				// get the animation properties
				animationStart = parseInt(jQuery.classBehaviours.utilities.getClassParameter(animNode, 'start', '0'));
				animationStep = parseInt(jQuery.classBehaviours.utilities.getClassParameter(animNode, 'step', '0'));
				animationEnd = parseInt(jQuery.classBehaviours.utilities.getClassParameter(animNode, 'end', '3'));
				animationLoop = parseInt(jQuery.classBehaviours.utilities.getClassParameter(animNode, 'loop', animationEnd));
				animationDelay = parseInt(jQuery.classBehaviours.utilities.getClassParameter(animNode, 'delay', '50'));
				animationTimeout = parseInt(jQuery.classBehaviours.utilities.getClassParameter(animNode, 'timeout', '0'));
				animationId = jQuery.classBehaviours.utilities.getClassParameter(animNode, 'id', null);
				animationName = jQuery.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) : jQuery.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 && animNode.className.indexOf('load_0,59,0')<0) nextAnimationStep = animationEnd;
				// set the animation name in the target
				if(animationName!=null){
					jQuery.classBehaviours.utilities.setClassParameter(animationTarget, 'name', animationName);
				}
				// set the next animation step
				if(animationStep!=nextAnimationStep){
					// update the step count
					jQuery.classBehaviours.utilities.setClassParameter(animationTarget, 'step', nextAnimationStep);
					// store the current step
					if(animationTarget!=animNode) jQuery.classBehaviours.utilities.setClassParameter(animNode, 'step', nextAnimationStep);
					// order the next update
					animationTimeout = (nextAnimationStep!=animationStep) ? setTimeout('jQuery.classBehaviours.handlers.animatedClassName.loop("'+animId+'")', animationDelay) : null ;
					// store the timeout
					jQuery.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 = jQuery.classBehaviours.handlers.animatedClassName;
				// get the animation settings
				currentSettings = jQuery.classBehaviours.utilities.getClassParameter(objNode, 'start', '0') + ',';
				currentSettings += jQuery.classBehaviours.utilities.getClassParameter(objNode, 'end', '0') + ',';
				currentSettings += jQuery.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
					jQuery.classBehaviours.utilities.setClassParameter(objNode, 'start', animationSettings[0]);
					jQuery.classBehaviours.utilities.setClassParameter(objNode, 'step', animationSettings[0]);
					jQuery.classBehaviours.utilities.setClassParameter(objNode, 'end', animationSettings[1]);
					jQuery.classBehaviours.utilities.setClassParameter(objNode, 'loop', animationSettings[2]);
					// start the animation
					jQuery.classBehaviours.handlers.animatedClassName.loop(objNode.id);
				}
			},
			// events
			loadToPlay: function(that){
				var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
				// get the animation settings
				animationSettings = jQuery.classBehaviours.utilities.getClassParameter(objNode, 'load', '0,0,0').split(',');
				// if there isn't already interaction, reset the animation
				jQuery.classBehaviours.handlers.animatedClassName.reset(objNode, animationSettings);
			},
			clickToPlay: function(that){
				var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
				// get the animation settings
				animationSettings = jQuery.classBehaviours.utilities.getClassParameter(objNode, 'click', '0,0,0').split(',');
				// if there isn't already interaction, reset the animation
				jQuery.classBehaviours.handlers.animatedClassName.reset(objNode, animationSettings);
				// if the click needs to be canceled
				return !(jQuery.classBehaviours.utilities.getClassParameter(objNode, 'cancel', 'no')=='yes');
			},
			focusToPlay: function(that){
				var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
				// get the animation settings
				animationSettings = jQuery.classBehaviours.utilities.getClassParameter(objNode, 'focus', '0,0,0').split(',');
				animationTimeout = jQuery.classBehaviours.utilities.getClassParameter(objNode, 'mousefilter', '0');
				animationDelay = parseInt(jQuery.classBehaviours.utilities.getClassParameter(objNode, 'delay', '50'));
				// reset the animation
				clearTimeout(parseInt(animationTimeout));
				// order a new animation
				animationTimeout = setTimeout('jQuery.classBehaviours.handlers.animatedClassName.reset(document.getElementById("' + objNode.id + '"), new Array(' + animationSettings.join() + '));', animationDelay);
				// store its timeout
				jQuery.classBehaviours.utilities.setClassParameter(objNode, 'mousefilter', animationTimeout);
			},
			blurToPlay: function(that){
				var objNode = (typeof(this.nodeName)=='undefined') ? that : this ;
				// get the animation settings
				animationSettings = jQuery.classBehaviours.utilities.getClassParameter(objNode, 'blur', '0,0,0').split(',');
				animationTimeout = jQuery.classBehaviours.utilities.getClassParameter(objNode, 'mousefilter', '0');
				animationDelay = jQuery.classBehaviours.utilities.getClassParameter(objNode, 'delay', '50');
				// reset the animation
				clearTimeout(parseInt(animationTimeout));
				// order a new animation
				animationTimeout = setTimeout('jQuery.classBehaviours.handlers.animatedClassName.reset(document.getElementById("' + objNode.id + '"), new Array(' + animationSettings.join() + '));', animationDelay);
				// store its timeout
				jQuery.classBehaviours.utilities.setClassParameter(objNode, 'mousefilter', animationTimeout);
			}
		}

		// runs through a sequence of class names
		jQuery.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 = jQuery.classBehaviours.handlers.animatedClassName;
				// where do we want this click defered to
				targetId = jQuery.classBehaviours.utilities.getClassParameter(objNode, 'id', null);
				targetNode = document.getElementById(targetId);
				// triger the click event
				acn.clickToPlay(targetNode);
				// cancel the clicked link
				return false;
			}
		}

		// add this addon to the jQuery object
		if(typeof(jQuery.fn)!='undefined'){
			// extend jQuery with this method
			jQuery.fn.animatedClassName = function(){
				return this.each(
					function(){
						jQuery.classBehaviours.handlers.animatedClassName.start(this);
					}
				);
			};
			jQuery.fn.deferClick = function(){
				return this.each(
					function(){
						jQuery.classBehaviours.handlers.deferClick.start(this);
					}
				);
			};
			// set the event handler for this jQuery method
			$(document).ready(
				function(){
					$(".animatedClassName").animatedClassName();
					$(".deferClick").deferClick();
				}
			);
		}
	}


