
Site.Widgets.Ticker = Class.create
(
    Site.Base,
    {
        initialize: function($super, element, options)
        {
            $super();
            
            if (element)
            {
                this.element = element;
            
                this.setOptions
                (
                    options,
                    {
                        //animateSpeed: 0.3, /* the duration for the next slide to show (seconds) */
                        animateSpeed: 1.25, /* the duration for the next slide to show (seconds) */
                        messageWidth: 250,
                        interval: 8 /* the duration before the next slide is automatically shown (seconds) */
                    }
                );
            
                this.addObservers("btPreviousOnClick", "btNextOnClick");
                this.addBlocks("next", "previous", "afterShowMessage", "previousMorphAfterFinish", "nextMorphAfterFinish" );
            
                // get a count of messages
            
                this.count = this.element.select("li").length;
                
                this.index = 0;
            
                this.message = this.element.select("li").first();
                this.panel = this.element.select("ul").first();
            
                this.btPrevious = this.element.select("div.bt-previous").first();
                this.btNext = this.element.select("div.bt-next").first();
            
                if (!(this.message && this.panel))
                    throw("Ticker requires both panel and message elements");
            
                if (this.btPrevious)
                {
                    addEvent(this.btPrevious, "click", this.observers.btPreviousOnClick);
                }
                
                if (this.btNext)
                {
                    addEvent(this.btNext, "click", this.observers.btNextOnClick);
                }
                
                this.start();
            }
        },
        
        start: function()
        {
            if (this.interval)
                window.clearInterval(this.interval);
                
            this.interval = window.setInterval(this.blocks.next, this.options.interval * 1000);  
        },
        
        next: function()
        {
            if (this.index == this.count - 1)
            {
                // make it appear as if the ticker messages are on a loop of tape by animating to the end, jumping back to the start, then animating to the first
                this.effect = new Effect.Morph(this.panel, { style: { left: this.getPanelLeft(this.count) + "px" }, duration: this.options.animateSpeed / 2, afterFinish: this.blocks.nextMorphAfterFinish });
            }
            else
            {
                this.index++;
                this.showMessage();
            }
        },
        
        nextMorphAfterFinish: function() 
        { 
            this.panel.setStyle
            (
                {
                    left: this.options.messageWidth + "px"
                }
            ); 
            
            this.index = 0; 
            this.showMessage(true); 
        },
        
        previousMorphAfterFinish: function()
        {
            this.panel.setStyle
            (
                {
                    left: this.getPanelLeft(this.count) + "px"
                }
            ); 
            
            this.index = this.count - 1; 
            this.showMessage(true);    
        },
        
        previous: function()
        {
            if (this.index == 0)
            {
                // make it appear as if the ticker messages are on a loop of tape by animating to the start, jumping to the end, then animating back to the last
                this.effect = new Effect.Morph(this.panel, { style: { left: Site.Widgets.Ticker.MESSAGE_WIDTH + "px" }, duration: this.options.animateSpeed / 2, afterFinish: this.blocks.previousMorphAfterFinish });
            }
            else
            {
                this.index--;
                this.showMessage();
            }
        },
        
        showMessage: function(fast)
        {
            this.animating = true;
            this.effect = new Effect.Morph(this.panel, {afterFinish: this.blocks.afterShowMessage, duration: this.options.animateSpeed / (fast ? 2 : 1), style: { left: this.getPanelLeft() + "px" } });
        },
        
        getPanelLeft: function(index)
        {
            return ( - ( ( (index || this.index)) * (this.options.messageWidth * 2)  ) );
        },
        
        afterShowMessage: function()
        {
            this.animating = false;
        },
        
        /*
            Event observers
        */
        
        btNextOnClick: function(event)
        {
            var element = Event.element(event);
            
            if (!this.animating)
            {
                this.next();
                this.start();
            }
            
            if (element.blur)
                element.blur();
            
            element = null;

            Event.stop(event);
        },
        
        btPreviousOnClick: function(event)
        {
            var element = Event.element(event);

            if (!this.animating)
            {
                this.previous();
                this.start();
            }
            
            if (element.blur)
                element.blur();
            
            element = null;

            Event.stop(event);
        },
        
        destroy: function()
        {
            window.clearInterval(this.interval);
            
            if (this.btPrevious)
            {
                removeEvent(this.btPrevious, "click", this.observers.btPreviousOnClick);
            }
            
            if (this.btNext)
            {
                removeEvent(this.btNext, "click", this.observers.btNextOnClick);
            }
        }
    }
);
