// 
//  feature_carousel.js
//  /scripts
//  
//  Created by Sean Sullivan
//  Copyright 2008 Sean. All rights reserved.
// 

OP.widget.featureCarousel = (function(){
	var _widget_id = null,
		_till_scroll = 10,
		_total_features = 0,
		_current_id = 1,
		_old_feature = null,
		_current_feature = null,
		_to_scroll = 0,
		_parent = null,
		_scroller = null,
		_animate_type = 'verticalscroll';
		
	var processFeature = function(){
		if(_till_scroll == 0){ // it is time to scroll
			_current_id = parseInt(_current_id)+1 > _total_features ? 1 : parseInt(_current_id)+1; // if we are on the last feature, go back to the first
			updateLinkClasses(document.getElementById('op_feature_carousel_links-'+_widget_id).getElementsByTagName('li'));
			setAndScroll();
			_till_scroll = 10; // reset time left until scroll
		}
		else{ // not time to scroll
			_till_scroll--; // decrease time left until scroll
		}
	}
	
	var updateLinkClasses = function(links){
		for(i=0; i < links.length; i++){
			if(links[i].className.split('-')[1] == _current_id){
				classes = links[i].className.split('\s');
				if(!('selected' in classes)){
					links[i].className += ' selected';	
				}
			}
			else{
				links[i].className = links[i].className.replace(/(\s)*selected/,'');	
			}
		}
	}
	
	var setAndScroll = function(){
		var elems,
			i;
		
		elems = document.getElementById('op_feature_carousel_features-'+_widget_id).getElementsByTagName('li');
		
		if(_current_feature) _old_feature = _current_feature; // Remember what the last feature was
		
		if(elems.length > 1){
			for(i=0; i < elems.length; i++){
				if(!_current_feature && elems[i].className.split('-')[1] == 1)
					_old_feature = elems[i];
				
				if(elems[i].className.split('-')[1] == _current_id){
					_current_feature = elems[i];  // Assign new feature to _current_feature
					if(_animate_type == 'verticalscroll')
						startScroller();
					else
						startFader();
					return;
				}
			}	
			// add class to selector <a> and remove class from others
		}
	}
	
	var startFader = function(){
		_old_feature.style.zIndex = 2;
		
		_current_feature.style.position = 'absolute';
		_current_feature.style.top = 0;
		_current_feature.style.left = 0;
		_current_feature.style.zIndex = 1;
		
		typeof _current_feature.style.opacity == "string" ? _current_feature.style.opacity = 1 : _current_feature.style.filter = 'alpha(opacity=100)';

		_to_scroll = 100;
		_scroller = setInterval(fade, 100);
	}
	
	var fade = function(){
		if(_to_scroll == 0){
			clearInterval(_scroller);
			_scroller = null;
			_current_feature.style.zIndex = 2;
			_old_feature.style.zIndex = 0;
			typeof _old_feature.style.opacity == "string" ? _old_feature.style.opacity = 0 : _old_feature.style.filter = 'alpha(opacity=0)';
		}
		else{
			_to_scroll -= 5;
			typeof _old_feature.style.opacity == "string" ? _old_feature.style.opacity = _to_scroll/100 : _old_feature.style.filter = 'alpha(opacity=' + _to_scroll + ')';
		}
	}
	
	/**
	 * Initialize transition
	 */
	var startScroller = function(){
		var tmpfeatures, toappend=[];

		_parent = _current_feature.offsetParent;
		tmpfeatures = _parent.getElementsByTagName('li');
		
		// Push _current_feature onto the stack cause it needs to be appended first
		toappend.push(_current_feature);
		
		/**
		* Redraw the features with the next feature set as the second in the list
		*/
		for(i=0; i < tmpfeatures.length; i++){
			e = tmpfeatures[i];
			if(e != _current_feature && e != _old_feature){
				toappend.push(e);
			}
		}

		for(var i=0; i < toappend.length; i++){
			_parent.removeChild(toappend[i]); // Remove original
			_parent.appendChild(toappend[i]); // Append new
		}

		_to_scroll = _current_feature.offsetHeight;
		_scroller = setInterval(scroll, 15);
	}
	
	/*
		Do the scroll
	*/
	var scroll = function(){
		if(_to_scroll > 0){
			var diff = Math.abs(_parent.scrollTop - _current_feature.offsetTop); // Calculate how far to scroll	
			_parent.scrollTop += diff > 10 ? 10 : diff;
			_to_scroll -= 10
		}
		else{
			clearScroller();
		}
	}
	
	/**
	 * Done with transition
	 */
	var clearScroller = function(){
		var tmpfeatures = _parent.getElementsByTagName('li'),
			e,
			toappend = [],
			i,
			elem2;
		
		/*
		All features above the current feature need to be appended below it.
		This is necessary since our transition only goes up.
		*/
		_current_feature.style.position = 'relative';
		_current_feature.style.top = '';
		_current_feature.style.zIndex = 0;
		
		for(i=0; i < tmpfeatures.length; i++){
			e = tmpfeatures[i];
			if(e != _current_feature){
				toappend.push(e);
			}
		}
		for(elem2 in toappend){
			_parent.removeChild(toappend[elem2]); // Remove original
			_parent.appendChild(toappend[elem2]); // Append new
		}
	
		_parent.scrollTop = 0; // Reset the parent
		clearInterval(_scroller);
		_scroller = null;
	}
	
	return {
		construct: function(features){
			var elems,
				i;
				
			elems = features.getElementsByTagName('li');
			_total_features = elems.length;
			for(i=0; i < _total_features; i++){
				// call function when feature selector is clicked
				OP.utility.observe(elems[i],'click',this.selectFeature);
			}
			
			_widget_id = features.id.split('-')[1]; // store widget_id for later use
			
			_animate_type = document.getElementById('featurecarousel_animate_'+_widget_id).innerHTML;
			
			// Start a little behind so if there's two they aren't completely in sync, that would just look weird =)
			setTimeout(this.startFeature,Math.random()*10000);

			return _widget_id;
		},
		
		startFeature: function(){
			setInterval(processFeature,500);
		},
		
		selectFeature: function(){
			
			var oldid = _current_id,
				tmp = this.id == undefined ? event.srcElement : this, // get target event
				matched,
				_this,
				i,
				links;
			
			_current_id = (tmp.className.split(' ')[0]).split('-')[1];
			
			if(_current_id == oldid) return false; // don't do anything more if it's the same feature as we were on before.
			
			_till_scroll = 15; // adjust time left until scroll

			// Handling whitespace trick taken from jQuery
			matched = [], current = tmp['parentNode'];
			while ( current && current != document ) {
				if ( current.nodeType == 1 )
					matched.push( current );
				current = current['parentNode'];
			}
					
			_this = OP.widget.collection.getWidgetInstance(matched[1].id.split('-')[1]);
			
			// remove selected class from others
			links = matched[0].getElementsByTagName('li');
			updateLinkClasses(links);
						
			setAndScroll();  // transition
			
			return false;
		}
	}
});

// Init widget
OP.widget.collection.add(OP.widget.featureCarousel,'op_feature_carousel_links');