Ext.ns('ABCS');
ABCS.Carousel = Ext.extend(Ext.util.Observable, {
	initDelay: 4, // initial delay of carousel
	interval: 4, //interval between two slides //time to transit scroller for 1px
	transitionSpeed: 0.5, // only used for slide and fade efect
	transitionType: 'slide-left',// slide-top, slide-right, slide-bottom, slide-left, scroll-top, scroll-right, scroll-bottom, scroll-left, fade, random
	transitionEasing: 'easeNone',
	itemSelector: 'img',
	activeSlide: 0,
	pauseOnHover: false,
	
	// constructor of control
	constructor: function(elId, config) {
		config = config || {};
		Ext.apply(this, config);
		ABCS.Carousel.superclass.constructor.call(this, config); 
		
		this.el = Ext.get(elId);
		this.slides = this.els = [];
		
		this.initMarkup();
        
		this.delayedTask =  new  Ext.util.DelayedTask(function(){
				this.taskData = this.taskData || {
				run: this.changeSlide,
				scope:this,
				interval: (this.interval * 1000)
			};
			 Ext.TaskMgr.start(this.taskData);
		},this);
		
		this.delayedTask.delay(this.initDelay * 1000);
		
		// we have pause on mouse over efect
		if(this.pauseOnHover){
			this.els.container.on('mouseenter', function(ev){
				Ext.TaskMgr.stop(this.taskData);
				this.delayedTask.cancel();
			},this);
			this.els.container.on('mouseleave', function(ev){
				 this.delayedTask.delay(1500);
			},this);
		}
	},
	// create makup of control
	initMarkup: function() {
		var dh = Ext.DomHelper;
		this.carouselSize = 0;
		var items = this.el.select(this.itemSelector);
		this.els.container = dh.append(this.el, {cls: 'carousel-container'}, true);
		this.els.slidesWrap = dh.append(this.els.container, {cls: 'carousel-slides-wrap'}, true);
		// set the dimensions of the container
		this.slideWidth = this.width || this.el.getWidth(true);
		this.slideHeight = this.height || this.el.getHeight(true);
		// set container width and height
		this.els.container.setStyle({
			width: this.slideWidth + 'px',
			height: this.slideHeight + 'px'
		});
		//append items to slides wraper
		var height = 0;
		items.appendTo(this.els.slidesWrap).each(function(item) {
			// wrap each slide with stylized div
			switch(this.transitionType){
				case 'slide-left':
				case 'slide-right':
				case 'fade':
						item = item.wrap({cls: 'carousel-slide-left-right'});
						item.setWidth(this.slideWidth + 'px').setHeight(this.slideHeight + 'px');
					break;
				case 'slide-top':
				case 'slide-bottom':
					break;
				case 'scroll-left':
				case 'scroll-right':
					break;
				case 'scroll-top':
				case 'scroll-bottom':
					height += item.getHeight();
					item.wrap({cls: 'carousel-scroll-top-bottom'}).setWidth(this.slideWidth + 'px');
					break;
			}
			this.slides.push(item);
		}, this);
		
		// how many slides
		this.carouselSize = this.slides.length;
		
		//vertical movement
		if(height > 0){
			this.els.slidesWrap.setHeight(height + 'px');
		}
		//horizontal movement
		else if(this.transitionType != 'scroll-left'){
			if(this.carouselSize > 0){
				this.els.slidesWrap.setWidth((this.carouselSize * this.slideWidth) + 'px');
			}
		}
		// overflow main container
		this.el.clip();
		// control position and mesaures
		this.x = this.els.container.getX();
		this.y = this.els.container.getY();
		this.height = this.els.container.getHeight(true);
		this.width = this.els.container.getWidth(true);
	},
	// change slide by 1
	changeSlide: function() {
		var index = this.activeSlide + 1;
		//check index		
		if(index < 0) {
			index = (this.carouselSize-1);
		}
		else if(index > (this.carouselSize-1)) {
			index = 0;
		}
		if(!this.slides[index]) {
			return;
		}
		switch (this.transitionType) {
			case 'slide-left':
				var offset = index * this.slideWidth;
				//calc new position
				var xNew = (-1 * offset) + this.els.container.getX();
				if(Ext.isIE && xNew == this.els.container.getX()){
					xNew += 1;
				}
				this.els.slidesWrap.stopFx(false);
				this.els.slidesWrap.shift({
					duration: this.transitionSpeed,
					x: xNew,
					easing: this.transitionEasing
				});
			break;
			case 'scroll-left':
				//calc new position
				var xNew = this.els.slidesWrap.getX() - 1;
				var scrollerWidth = this.els.slidesWrap.getWidth();
				
				if(xNew <= (this.x - scrollerWidth)){
					// we are on end position so set it to start position
					xNew = this.x + this.width;	
				}
				this.els.slidesWrap.setX(xNew);
			break;
			case 'scroll-top':
				//calc new position
				var yNew = this.els.slidesWrap.getY() - 1;
				var scrollerHeight = this.els.slidesWrap.getHeight();
				
				if(yNew <= (this.y - scrollerHeight)){
					// we are on end position so set it to start position
					yNew = this.y + this.height;	
				}
				this.els.slidesWrap.setY(yNew);
			break;
			case 'fade':
				//calc new position
				var offset = index * this.slideWidth;
				//calc new position
				// var xNew = (-1 * offset) + this.els.container.getX();
				// if(Ext.isIE && xNew == this.els.container.getX()){
					// xNew += 1;
				// }
				this.slides[index].setOpacity(0);
				this.slides[this.activeSlide].stopFx(false).fadeOut({
					duration: this.transitionSpeed,
					callback: function(){
						this.els.slidesWrap.setStyle('left', (-1 * offset) + 'px');
						this.slides[this.activeSlide].setOpacity(1);
						this.slides[index].fadeIn({
							duration: this.transitionSpeed
						});
					},
					scope: this
				});
			break;
		}
		this.activeSlide = index;
	}
	
});
