Ext.namespace('Ext.ux');
Ext.ux.FaderInstances = [];
Ext.ux.Fader = Ext.extend(Ext.util.Observable, {
	constructor: function(settings){
		//Apply Settings
		Ext.apply(this, settings);
		
		//Register events
		this.addEvents(
			'init'
			,'beforechange'
			,'change'
		);
		
		//Call super
		Ext.ux.Fader.superclass.constructor.apply(this, arguments);
		
		//Init this component
		this.init();
		
		Ext.ux.FaderInstances.push(this);
	}
	
	//Private
	,items:[]
	,currentIndex: 0
	,interval: null
	
	//Elements
	,nextButton: null
	,previousButton: null
	,itemContainer: null
	
	//Variables
	,container: null
	,width: 500
	,height: 500
	,selector: ''
	,autoStart: true
	,slideshow: true
	,easing: 'easeNone'
	,animationDuration: .5
	,wait: 5
	,overlay:false
	
	,init: function(){
		this.initElements();
		if(this.container != null){
			this.initContainer();
			this.initItems();
			
			//Check if empty
			if(!this.items.length){
				return false;
			}
			
			this.initButtons();
			
			//Auto start
			if(this.items.length > 1 && this.autoStart){
				this.start();
			}
			
			//Show container if hidden
			this.container.show();
			
			//Fire Event
			this.fireEvent('init');
		}
	}
	,initElements: function(){
		this.container = Ext.get(this.container);
		if(this.container != null){
			this.nextButton = Ext.get(this.container.select('.next').elements[0]);
			this.previousButton = Ext.get(this.container.select('.previous').elements[0]);
		}
	}
	,initContainer: function(){
		this.container.setWidth(this.width);
		this.container.setHeight(this.height);
		this.container.set({
			style:{
				overflow: 'hidden'
			}
		});
	}
	,initItems: function(){
		//Create the item container
		this.itemContainer = Ext.get(Ext.DomHelper.append(this.container, {
			tag: 'div'
			,style: {
				position: 'relative'
				,width: this.width + 'px'
				,height: this.height + 'px'
			}
		}));
		
		this.items = this.container.select(this.selector).elements;
		for(var i=0; i < this.items.length; i++){
			var el = Ext.get(this.items[i]);
			el.hide();
			el.dom.style.position = 'absolute';
			el.setLeft(0 + 'px');
			el.setTop(0 + 'px');
			
			if(!i){
				el.show();
			}

			
			//Append to the itemContainer
			this.itemContainer.appendChild(el);
		}
	}
	,initButtons: function(){
		if(this.nextButton != null){
			this.itemContainer.appendChild(this.nextButton);
			this.nextButton.on('click', this.next, this);
		}
		
		if(this.previousButton != null){
			this.itemContainer.appendChild(this.previousButton);
			this.previousButton.on('click', this.previous, this);
		}
		
		this.setOverlay(this.overlay);
	}
	
	,setOverlay: function(id) {
		this.overlay = Ext.get(id);
		if (this.overlay) {
			this.overlay.on('mouseover', function(){
				this.stop();
			}, this);
			this.overlay.on('mouseout', function(){
				this.start();
			}, this);
			this.overlay.on('mousedown', function(){
				var currentItem = Ext.get(this.items[this.currentIndex]).child('a');
				if (currentItem) {
					var href = currentItem.dom.href;
					if (href.length && href != '#') {
						location.href = href;
					}
				}
			}, this);
		}
	}
	
	,alignItems: function(lastIndex, currentIndex){
		var currentItem = Ext.get(this.items[lastIndex]);
		var nextItem = Ext.get(this.items[currentIndex]);
		
		currentItem.dom.style.zIndex = 0;
		nextItem.dom.style.zIndex = 1;
		
		currentItem.setStyle({
			visibility:'visible'
		});
		nextItem.setStyle({
			visibility:'visible'
		});
		
	}
	
	,next: function(){
		//Increment the current item
		var index = this.currentIndex+1;
		
		//Check the doundaries
		if(index > this.items.length-1){
			index = 0;
		}
		
		//Load index
		this.showIndex(index);
	}
	
	,previous: function(){
		//Decrement the currentIndex
		var index = this.currentIndex-1;
		
		//Check boundaries
		if(index < 0){
			index = this.items.length-1;
		}
		
		//Load index
		this.showIndex(index);
	}
	
	,showIndex: function(index){
		if(!this.animating){
			
			//get the old index
			var lastIndex = this.currentIndex;
			
			//set new index
			this.currentIndex = index;
			
			if(lastIndex != this.currentIndex){
				
				//Align the items
				this.alignItems(lastIndex, this.currentIndex);
				
				//animate the container
				Ext.get(this.items[this.currentIndex]).fadeIn({
					scope: this,
				    endOpacity: 1,
				    easing: this.easing,
				    duration: this.animationDuration,
				    callback: this.animationComplete,
				    useDisplay: true
				});
				
				//Is animating
				this.animating = true;
				
				//restart interval
				this.stop();
				this.start();
			}
		}
	}
	
	,animationComplete: function(){
		//hide all but the current
		for(var i=0; i < this.items.length; i++){
			if(i != this.currentIndex){
				Ext.get(this.items[i]).hide();
			}
		}
		this.animating = false;
	}
	
	,start: function(){
		if(this.slideshow){
			this.interval = setInterval(function(){
				this.next();
			}.createDelegate(this), (this.wait*1000));
		}
	}
	
	,stop: function(){
		clearInterval(this.interval);
	}
	
});
