YAHOO.namespace('BIZARRO');
(function(){
    var Dom = YAHOO.util.Dom,
        Event = YAHOO.util.Event,
        Lang = YAHOO.lang,
        CONTAINER_ID = 'featureFlash',
        FEATURE_LIST_CLASS = 'flash-elements',
        ARROW_CLASS = 'arrow',
        TOP_ZINDEX = 10,
        CONTROLS_ID = 'featureFlashControls';

    /*
    * @param el {HTMLElement | String} The HTML element that represents the
    * the container that houses the Feature.
    */
    // the constructor for the new object
    var FeatureFlash = function(oConfigs) {

        // This is how you call the constructor of the class you inherit from
        // we adjust the scope via method call
        // create the DIV which will be the actual HTML element this Element object will represent
        // and pass the configuration attributes
        FeatureFlash.superclass.constructor.call(this, Dom.get(CONTAINER_ID), oConfigs);

        // notice how easy it is to create an event given that your object will inherit from EventProvider
        this.createEvent('clickEvent');
        this.createEvent('startAutoPlayEvent');

    };

    // By copying a reference to it to to a variable rooted in the global namespace, we make it public
    YAHOO.BIZARRO.FeatureFlash = FeatureFlash;

    // now we are actually doing the inheritance part.
    Lang.extend(FeatureFlash,YAHOO.util.Element, {

        // actually, the first such prototype will be an override.
        // Element already has a initAttributes function
        // here we override it with out own so we can add out own configuration properties
        initAttributes: function (oConfigs) {

            // First of all we call the base class initAttributes so Element has its predefined configuration attributes
            FeatureFlash.superclass.initAttributes.call(this, oConfigs);

            // The Element constructor will already put our component container along the attributes
            var container = this.get('element');

            // SET UP OUR ATTRIBUTES AND DEFAULT VALUES FROM THE PROVIDED CONFIGURATION
            this.setAttributeConfig('startIndex', {
                writeOnce: true,
                validator: Lang.isNumber,
                value: 0
            });

            this.setAttributeConfig("autoPlay",{
                validator: Lang.isBoolean,
                value: oConfigs.autoPlay || true,
                method: function (val) {
                    if (val) {
                        return;
                    }
                    this._undefineAnimTimer();
                    this._undefineRestartTimer();
                    this._checkRestartInterval();
                }
            });

            this.setAttributeConfig("topIndex",{
                validator : Lang.isNumber,
                value : 0
            });

            this.setAttributeConfig("autoPlayInterval", {
                writeOnce: true,
                validator : Lang.isNumber,
                value     : oConfigs.autoPlayInterval || 0
            });

            this.setAttributeConfig("animDuration",{
                writeOnce: true,
                validator: Lang.isNumber,
                value: oConfigs.animDuration || .2
            });

            this.setAttributeConfig("topIndex",{
                validator : Lang.isNumber,
                value : 0
            });

            this.setAttributeConfig("elementsContainer",{
                value : null
            });

            this.setAttributeConfig("numItems",{
                validator : Lang.isNumber
            });

            this.setAttributeConfig("currentIndex", {
                validator : function (val) {
                    return this._validateSlideIndex(val);
                },
                value : 0,
                method : function (value) {
                    this._updateSlideOrder(value);
                }
            });

        },

        // PROTECTED PROPERTIES
        _isAutoPlayInProgress: false,
        _slides: [],
        _arrow: null,
        //_autoPlayTimer this is used but leat undefined
        //_restartTimer this is used but left undefined

        render: function (parentId) {
            var items, controls;
            var containerEl = this.get('element');

            Dom.addClass(containerEl, 'running');
            this.setup();
            this._slides = this.addItems(this._slides);

            containerEl.appendChild(this._createControls());
            containerEl.appendChild(this._createArrow());
            Dom.addClass(this._slides[0].el, 'initial');

            this.autoPlayStart();
        },

        destroy: function () {
            var el = this.get('element');
            Event.purgeElement(el, true);
            el.parentNode.removeChild(el);
        },

        setup:function() {
            var elements_container = Dom.getElementsByClassName(FEATURE_LIST_CLASS, 'ul', this.get('element'))[0];
            this.set('elementsContainer', elements_container);
            this._slides = this.get('elementsContainer').getElementsByTagName('li');
        },

        createSlide: function (item) {
            Dom.addClass(item, 'feature_flash_slide');
            return {
                el: item,
                thumb: item.getElementsByTagName('img')[0].src
            };
        },

        addItems: function (items) {
            var slides = [];
            for (var i=0; i < items.length; i++) {
                slides[i] = this.createSlide(items[i], i > 0);
            }
            return slides;
        },

        moveTo: function (idx) {
            this.set("currentIndex",idx);
            return true;
        },

        moveSlideToDepth: function (idx,zIndex) {
            if (zIndex == 0) {
                Dom.setStyle(this._slides[idx].el,'opacity','0');
            } else {
                Dom.setStyle(this._slides[idx].el,'opacity','1');
            }
            Dom.setStyle(this._slides[idx].el,'z-index',zIndex);
        },

        autoPlayStart: function () {
            var featureFlash = this, timer;

            if (Lang.isUndefined(this._autoPlayTimer)) {
                timer = this.get("autoPlayInterval");
                if (timer <= 0) {
                    return;
                }
                this._isAutoPlayInProgress = true;
                this.fireEvent('startAutoPlayEvent');
                this._autoPlayTimer = setTimeout(function () {
                    featureFlash._autoPlay();
                }, timer);
            }
        },

        isAnimating: function () {
            return this._isAnimationInProgress;
        },

        toString: function () {
            return "FeatureFlash Object";
        },

        getNextIndex: function (idx) {
            var next,numItems = this._slides.length;
            next = idx + 1;
            next = next > numItems-1 ? 0 : next;
            return next;
        },

        getPreviousIndex: function (idx) {
            var previous,numItems = this.get('numItems');
            previous = idx - 1;
            previous =  previous < 0 ? numItems-1 : previous;
            return previous;
        },

        _updateSlideOrder: function (idx) {
            if (!this._validateSlideIndex(idx)) return;
            var slide = this._slides[idx];

            current = this.get('currentIndex');
            if (idx === current) {
                return;
            }

            this.moveSlideToDepth(idx,TOP_ZINDEX-1);
            this._animateSlide(idx,current);
        },

        // next becomes current at the end of the animation.
        _autoPlay: function () {
            var currentIndex = this.get("currentIndex");
            this.set('currentIndex', this.getNextIndex(currentIndex) );
        },

        _animateSlide: function (idx, last) {
            var feature = this,
                animObj = null;

            animObj = new YAHOO.util.Anim(this._slides[last].el,{
                opacity:{from:1,to:0}
            });
            animObj.duration = this.get("animDuration");
            feature._isAnimationInProgress = true;
            animObj.onComplete.subscribe(feature._animationCompleteHandler,{ scope: feature, last: last, next: idx });
            animObj.animate();
            animObj = new YAHOO.util.Anim(this._arrow,{
                top:{to:(idx*68)+17}
            },this.get("animDuration"),YAHOO.util.Easing.easeBoth);
            animObj.animate();
        },

        _animationCompleteHandler: function (ev, p, o) {
            o.scope._isAnimationInProgress = false;
            updateAfterAnimate.call(o.scope, o.last, o.next);
        },

        _validateSlideIndex: function (idx) {
            return Lang.isNumber(idx) && idx >= 0 && idx < this._slides.length;
        },

        _undefineRestartTimer: function (){
            clearTimeout(this._restartTimer);
            delete this._restartTimer;
            return true;
        },

        _undefineAnimTimer: function () {
            clearTimeout(this._autoPlayTimer);
            delete this._autoPlayTimer;
            return true;
        },

        _checkRestartInterval: function (){
            var feature = this,
                restart = this.get("restartInterval");
            if (0 < restart) {
                this._restartTimer = setTimeout(function(){
                    feature.set("autoPlay",true);
                    feature.autoPlayStart();
                },restart);
            }
        },

        _createControls: function () {
            var feature = this,
                elId,
                container,
                button,
                animObj = null,
                container = document.createElement("ul");

            for (var i=0; i < this._slides.length; i++) {
                button = document.createElement("li");
                button.innerHTML = '<span><img src="'+this._slides[i].thumb+'" width="84" height="56"></span>';
                elId = Dom.generateId();
                button.setAttribute('id',elId);

                var clicker = function(number) {
                    return function (event) {
                        if(!feature.isAnimating()){
                            feature.set('currentIndex', number );
                        }
                    };
                };

                Event.on(button, 'click', clicker(i));
                container.appendChild(button);
            };
            container.setAttribute('id', CONTROLS_ID);
            return container;
            // animObj = new YAHOO.util.Anim(container,{opacity:{from:0,to:1}});
            // animObj.duration = .2;
            // animObj.animate();
            // return true;
        },
        _createArrow: function () {
            this._arrow = document.createElement('span');
            Dom.addClass(this._arrow, 'arrow');
            return this._arrow;
        }

    });
    function updateAfterAnimate(last, next) {
        this._undefineAnimTimer();

        this.moveSlideToDepth(last,0);
        this.moveSlideToDepth(next,TOP_ZINDEX);

        this.autoPlayStart();
    };

})();

YAHOO.register('BIZARRO.FeatureFlash', YAHOO.BIZARRO.FeautureFlash, {version: '2.7.0', build: '2'});

(function(){
    YAHOO.util.Event.onAvailable('featureFlash',function(){
        var featureFlash = new YAHOO.BIZARRO.FeatureFlash({
            autoPlayInterval:6000,// in milliseconds
            restartInterval:10000,// in milliseconds
            animDuration:.15 // in whole seconds for the animation object. This should not be longer than the autoplay interval
        });

        featureFlash.render('featureFlash');
    });
})();

