/*!
 * Ext Core Library 3.0
 * http://extjs.com/
 * Copyright(c) 2006-2009, Ext JS, LLC.
 * 
 * MIT Licensed - http://extjs.com/license/mit.txt
 */


Ext.ns('Ext.ux');

Ext.ux.Carousel = Ext.extend(Ext.util.Observable, {
    interval: 4,
    transitionDuration: 2,
    transitionType: 'fade',
    transitionEasing: 'easeOut',
    itemSelector: 'img',
    activeSlide: 0,
    wrap: false,
    clickable: false,
    width: null,
    height: null,

    constructor: function(elId, config) {
        config = config || {};
        Ext.apply(this, config);

        Ext.ux.Carousel.superclass.constructor.call(this, config);

        this.addEvents(
            'change',
            'play',
            'pause'
        );

	this.el = Ext.get(elId);
        this.slides = this.els = [];
        
        this.wrap = true;

        this.initMarkup();
        this.initEvents();

        if(this.carouselSize > 0) {
            this.el.setStyle({visibility: 'visible'});
            this.refresh();
        }
    },

    initMarkup: function() {
        var dh = Ext.DomHelper;
        var e;
        
        this.carouselSize = 0;
        var items = this.el.select(this.itemSelector);
        this.els.container = dh.append(this.el, {cls: 'ux-carousel-container'}, true);
        this.els.slidesWrap = dh.append(this.els.container, {cls: 'ux-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);
        this.els.container.setStyle({
            width: this.slideWidth + 'px',
            height: this.slideHeight + 'px'
        });
        
        items.appendTo(this.els.slidesWrap).each(function(item) {
            item = item.wrap({cls: 'ux-carousel-slide'});
            this.slides.push(item);
            item.setWidth(this.slideWidth + 'px').setHeight(this.slideHeight + 'px');
            if(this.clickable){
		item.addListener('click', function(evt){window.open(evt.getTarget().alt);});
		item.addListener('mouseover', function(evt){evt.getTarget().style.cursor = 'pointer';});
		item.addListener('mouseout', function(evt){evt.getTarget().style.cursor = 'default';});
            }
        }, this);
        this.carouselSize = this.slides.length;
        this.el.clip();
    },

    initEvents: function() {
            this.play();
    },

    play: function() {
        if(!this.playing) {
            this.playTask = this.playTask || {
                run: function() {
                    this.playing = true;
                    this.setSlide(this.activeSlide+1);
                },
                interval: this.interval*1000,
                scope: this
            };
            
            this.playTaskBuffer = this.playTaskBuffer || new Ext.util.DelayedTask(function() {
                Ext.TaskMgr.start(this.playTask);
            }, this);

            this.playTaskBuffer.delay(this.interval*1000);
            this.playing = true;
            this.fireEvent('play');
        }        
        return this;
    },
        
    clear: function() {
        this.els.slidesWrap.update('');
        this.slides = [];
        this.carouselSize = 0;
        return this;
    },
    
    add: function(el, refresh) {
        var item = Ext.fly(el).appendTo(this.els.slidesWrap).wrap({cls: 'ux-carousel-slide'});
        item.setWidth(this.slideWidth + 'px').setHeight(this.slideHeight + 'px');
        this.slides.push(item);                        
        if(refresh) {
            this.refresh();
        }        
        return this;
    },
    
    refresh: function() {
        this.carouselSize = this.slides.length;
        this.els.slidesWrap.setWidth((this.slideWidth * this.carouselSize) + 'px');
        if(this.carouselSize > 0) {
            this.activeSlide = 0;
            this.setSlide(0, true);
        }                
        return this;        
    },
    
    setSlide: function(index, initial) {
        if(!this.wrap && !this.slides[index]) {
            return;
        }
        else if(this.wrap) {
            if(index < 0) {
                index = this.carouselSize-1;
            }
            else if(index > this.carouselSize-1) {
                index = 0;
            }
        }
        if(!this.slides[index]) {
            return;
        }

        var offset = index * this.slideWidth;
        if (!initial) {
                    this.slides[index].setOpacity(0);
                    this.slides[this.activeSlide].stopFx(false).fadeOut({
                        duration: this.transitionDuration / 2,
                        callback: function(){
                            this.els.slidesWrap.setStyle('left', (-1 * offset) + 'px');
                            this.slides[this.activeSlide].setOpacity(1);
                            this.slides[index].fadeIn({
                                duration: this.transitionDuration / 2
                            });
                        },
                        scope: this
                    })
        }
        else {
            this.els.slidesWrap.setStyle('left', '0');
        }

        this.activeSlide = index;
        this.fireEvent('change', this.slides[index], index);
    },
    
    gotoSlide: function(index) {
        var offset = index * this.slideWidth;
	this.slides[index].setOpacity(0);
	this.slides[this.activeSlide].stopFx(false).fadeOut({
		duration: 1 / 2,
		callback: function(){
		    this.els.slidesWrap.setStyle('left', (-1 * offset) + 'px');
		    this.slides[this.activeSlide].setOpacity(1);
		    this.slides[index].fadeIn({
			duration: 1 / 2
		    });
		},
		scope: this
	})

        this.activeSlide = index;
    }, 

    pause: function() {
        if(this.playing) {
            Ext.TaskMgr.stop(this.playTask);
            this.playTaskBuffer.cancel();
            this.playing = false;
            this.fireEvent('pause');
        }        
        return this;
    }

});


