var TransitionChain = function(){
	var stopStates = {};
	var shownItemIndices = {};
	var currentTransitionChain = {};
	var nextTransitionChain = {};
	var maxValues = {};
	var transitioningStates = {};
	
	return {
		
		hideFunc : function(className, itemIndex, options){
			itemIndex = itemIndex % maxValues[className];
			
			options['afterFinish'] = function(){
				nextNum = (( itemIndex + 1) % maxValues[className]);
				TransitionChain.showFunc( className, nextNum, options );
			};
			
			var shown_link = $(className + '_' + itemIndex);
			if(
				currentTransitionChain[className] = className
				&& !stopStates[className]
				&& shown_link && itemIndex >= 0
			){
				transitioningStates[className] = true;
				var effectOptions = options;
				effectOptions['from'] = 1.0;
				effectOptions['to'] = 0.0;
				if(options['hideLink']){
					effectOptions = $H(options).merge(options['hideLink']).toObject();
				}
				new Effect.Fade(shown_link, effectOptions);
			}else if(
				stopStates[className]
				&& nextTransitionChain[className] != className
			){
				nextClassName = nextTransitionChain[className];
				nextIndex = shownItemIndices[nextClassName];
				currentTransitionChain[className] = nextClassName;
				currentTransitionChain[nextClassName] = nextClassName;
				TransitionChain.hideFunc(nextClassName, nextIndex, options );
			}
		},
		
		showFunc : function(className, itemIndex, options){
			itemIndex = itemIndex % maxValues[className];
			
			var nextClassName = nextTransitionChain[className];
			var nextIndex = shownItemIndices[nextClassName];
			
			options['afterFinish'] = function(){
				shownItemIndices[className] = itemIndex;
				transitioningStates[className] = false;
				currentTransitionChain[className] = nextClassName;
				currentTransitionChain[nextClassName] = nextClassName;
				TransitionChain.hideFunc( nextClassName, itemIndex, options );
			};
			
			var shown_link = $(className + '_' + itemIndex);
			if(shown_link && itemIndex >= 0){
				var effectOptions = options;
				effectOptions['from'] = 0.0;
				effectOptions['to'] = 1.0;
				if(options['showLink']){
					effectOptions = $H(options).merge(options['showLink']).toObject();
				}
				new Effect.Appear(shown_link, effectOptions);
			}
		},
		
		/*
		hoverFunc : function(id, className, options){
			
			options = $H({ delay: 0.5 }).merge(options).toObject();
			
			$(id).hover(
				function(){
					stopStates[className] = true;
				},
				function(){
					stopStates[className] = false;
					if( !transitioningStates[className] && nextTransitionChain[className] == className ){
						TransitionChain.hideFunc(className, shownItemIndices[className], options);
					}
				},
				{
					enterDelay: 0,
					leaveDelay: options['delay'] * 1000
				}
			);
		},
		*/
		
		add: function(targets, options){
			
			var defaults = {
				duration: 2.0,
				transition: Effect.Transitions.linear,
				delay: 0.5,
				faderLinkClass: 'fader'
			};
			options = $H(defaults).merge(options).toObject();
			
			for(var i=0; i< targets.length; i++){
				var className = targets[i]['className'];
				var id = targets[i]['id'];
				
				stopStates[className] = false;
				shownItemIndices[className] = 0;
				maxValues[className] = $$('#'+ id + ' span.' + className).length;
				transitioningStates[className] = false;
				
				if( i == (targets.length -1) ){
					nextTransitionChain[className] = targets[0]['className'];
				}else{
					nextTransitionChain[className] = targets[i + 1]['className'];
				}
				
				currentTransitionChain[className]= targets[0]['className'];
				
				if(i == 0 ){
					TransitionChain.hideFunc(className, shownItemIndices[className], options);
				}
				// TransitionChain.hoverFunc(id, className, options);
			}
		}
	}

}();