﻿/**
* Class: News Ticker 2.2
* Requires: MooTools 1.2.3
* 
* @since: 2.2, 09/02/2010
* @author: lee.boonstra[AT]efocus.nl
* @author: rocco janse <rocco@efocus.nl>
*/

var Ticker = new Class({
    Implements: [Options],
    options: {
        elMainDiv: null, //idname of the outer div
        speedIn: 1000,
        speedOut: 500,
        delayIn: 0, //duration of fade in
        delayOut: 0, //duration of fade out
        elNextBut: null,
        elPrevBut: null
    },
    initialize: function(options) {
        this.setOptions(options);

        if (!$chk(this.options.elMainDiv)) {
            return false;
        }

        this.elViewport = this.options.elMainDiv.getElement('div');
        this.elList = this.options.elMainDiv.getElement('ul');
        this.elListItems = this.elList.getElements('li');
        this.intMaxListItemHeight = this.calculateHeight();
        this.intViewportHeight = this.elViewport.getStyle('height').toInt();
        this.intHeadingHeight = this.elViewport.getElement('h2').getHeight().toInt();
        this.intFooterHeight = $(document.body).getElement('div.footer').getHeight() || 0;
        this.elNewsList = $(document.body).getElement('div.newslist');
        this.intCurrentNum = 0;
        this.objTimer = null;
        this.showPrev = false;

        this.setViewportHeight();
        this.setPosition();
        this.reset();

        this.options.elMainDiv.addEvent('mouseover', function() { this.pause(); } .bind(this));
        this.options.elMainDiv.addEvent('mouseleave', function() { this.resume(); } .bind(this));

        if ($chk(this.options.elNextBut)) {
            this.options.elNextBut.addEvent('click', function(event) {
                event.stop();
                this.next();
            } .bind(this));
        }
        if ($chk(this.options.elPrevBut)) {
            this.options.elPrevBut.addEvent('click', function(event) {
                event.stop();
                this.prev();
            } .bind(this));
        }
    },
    reset: function() {
        if (this.fadeIn) {
            this.fadeIn.cancel();
        }
        if (this.fadeOut) {
            this.fadeOut.cancel();
        }

        this.elListItems.setStyles({
            'opacity': 0
        });

        //next slide play with delay
        this.animate.bind(this).delay(this.options.delay);
    },
    updateCount: function(showPrev) {
        //count list items, and reset after played all
        if (showPrev === true) {
            this.intCurrentNum--;
            if (this.intCurrentNum == -1) {
                this.intCurrentNum = this.elListItems.length - 1;
            }
            //remove the previous element from the DOM tree
            if (this.intCurrentNum !== this.elListItems.length - 1) {
                this.elListItems[this.intCurrentNum + 1].injectInside(this.elList);
            }
        } else {
            this.intCurrentNum++;
            if (this.intCurrentNum >= this.elListItems.length) {
                this.intCurrentNum = 0;
            }
            //remove the previous element from the DOM tree
            if (this.intCurrentNum !== 0) {
                this.elListItems[this.intCurrentNum - 1].injectInside(this.elList);
            }
        }
    },
    calculateHeight: function() {
        var intMaxHeight = 0;
        $each(this.elListItems, function(elList, index) {
            if (intMaxHeight < elList.getStyle('height').toInt()) {
                intMaxHeight = elList.getStyle('height').toInt();
            }
        });
        return intMaxHeight;
    },
    setViewportHeight: function() {
        if ((this.intViewportHeight - this.intHeadingHeight) < this.intMaxListItemHeight) {
            this.elListItems.setStyle('height', this.intMaxListItemHeight);
            this.elViewport.setStyle('height', this.intMaxListItemHeight + this.intHeadingHeight);
        }
    },
    setPosition: function() {
        // add padding to newslist to prevent the ticker from overlaying the newslist
        var intBottomPx = this.intFooterHeight - 7;

        if ($defined(this.elNewsList)) {
            this.elNewsList.setStyle('padding-bottom', this.elViewport.getStyle('height').toInt() + 7);
        }
        // set position ticker
        this.options.elMainDiv.setStyles({
            'position': 'absolute',
            'bottom': intBottomPx
        });
    },
    pause: function() {
        $clear(this.objTimer);
    },
    resume: function() {
        this.fadeIn.resume();
    },
    prev: function() {
        $clear(this.objTimer);
        this.updateCount(this.showPrev = true);
        this.reset();
    },
    next: function() {
        $clear(this.objTimer);
        this.updateCount();
        this.reset();
    },
    animate: function() {
        var blnCanAnimate = true;
        elCurrentListItem = this.elListItems[this.intCurrentNum];

        this.fadeIn = new Fx.Tween(elCurrentListItem, {
            property: 'opacity',
            link: 'chain',
            duration: this.options.speedIn,
            transition: Fx.Transitions.Quart.easeIn,
            onComplete: function() {
                this.objTimer = this.fadeOut.start.pass([1, 0], this.fadeOut).delay(this.options.delayOut);
            } .bind(this)
        });

        this.fadeOut = new Fx.Tween(elCurrentListItem, {
            property: 'opacity',
            link: 'chain',
            duration: this.options.speedOut,
            transition: Fx.Transitions.Quart.easeOut,
            onComplete: function() {
                this.updateCount();
                this.reset();
                blnCanAnimate = true;
            } .bind(this)
        });

        if (blnCanAnimate) {
            blnCanAnimate = false;
            this.fadeIn.start.pass([0, 1], this.fadeIn).delay(this.options.delayIn);
        }
    }
});
