// Twidder: a JavaScript class for MooTools by Pete Allison (c)2008
/**
 * This class allows for the easy creation of a rotating banner-ad style box.
 * Unlike traditional banner ads, that just rotate through images, this class
 * will rotate through proper html, allowing for rotation of content elements
 * as well as adverts.
 * Class finds top level DIV elements within the target.
 * Target element should have CSS style overflow:hidden set along with width
 * and height.  This is done by the class, but IE insists on displaying the
 * contents of the element for a fraction of a second on page load otherwise.
 */
/**
 * initial object: object containing the page elements
 * target (str)            - ID of the element to process
 */
/**
 * options: twidder options
 * delay (int)             - The delay between each transition event firing
 * showNavigation (bool)   - Displays the navigation buttons if true
 * navigationClass (str)   - If provided the navigation buttons
 * transition (str)        - Type of transition: fade; scroll
 * direction (str)         - If a scroll the direction of it:
 *                           rtl = from right to left (default)
 *                           ltr = from left to right
 *                           r   = scrolls to and from right
 *                           t2b = top to bottom
 *                           b2t = bottom to top
 * mouseOverPause (bool)   - If true, then stops transitions when mouse is over the target, defaults to false
 */
var Twiddler = new Class({
    Implements: Options,

    version: '2.0.0',
    options: {
        delay: 3000, // delay between each transition
        showNavigation: true, // show the quick navigation buttons
        navigationClass: '',
        transition: 'fade',
        direction: 'rtl',
        mouseOverPause: false
    },

    // initialise: twiddler constructor
    // @param obj (obj) a js object containing the page elements and format strings { id: 'format', id: 'format' etc }
    // @param props (obj) optional properties

    initialize: function(obj, options){
        if (!obj)
            return false;
        if (!obj.target)
            return false;

        this.setOptions(options);

        if (obj.target) {
            this.targetElement = $(obj.target);
        }

        if (!obj.source) {
            this.sourceElement = this.targetElement.clone(true, true);
            this.targetElement.set('html', '');
        } else {
            this.sourceElement = $(objSource).clone(true, true);
        }

        $try(function(){
            this._style = new Element('style').setProperty('type', 'text/css').inject(document.head);
            var sheet = '#' + obj.target + ' .twiddlerChild{position:absolute;visibility:hidden;width:100%;height:100%;top:0px}' + "\n#" + obj.target + ' .item{visibility:hidden;}';
            sheet += "\n#" + obj.target + ' {overflow:hidden;}';
            if (this.options.navigationClass == '') {
                this.options.navigationClass = 'navigation';
                sheet += "\n#" + obj.target + ' .navigation{position:absolute;bottom:10px;right:10px;}';
                sheet += "\n#" + obj.target + ' .navigation a.page{display:block;font-size:11px;cursor:pointer;padding:2px 4px;margin:0px 2px;float:left;border:1px solid;background-color:rgb(185,185,185);}';
                sheet += "\n#" + obj.target + ' .navigation a.selected, #' + obj.target + ' .navigation a.page:hover{background-color:rgb(70,70,70);color:rgb(153,153,153);}';
            }
            switch (Browser.Engine.name) {
                case 'trident':
                    this._style.styleSheet.cssText = sheet;
                    break;
                default:
                    this._style.set('text', sheet);
                    break;
            }
        }.bind(this));

        this.childCount = 0;

        this.sourceElement.getElements('div').each(function(el){
            if (el.getParent() == this.sourceElement) {
                el.addClass('twiddlerChild');
                this.childCount++;
            }
        }, this);

        if (this.childCount > 1) {
            switch (this.options.transition) {
                case 'fade':
                    this.sourceElement.getElements('div.twiddlerChild').setStyle('opacity', 0);
                    break;
                case 'scroll':
                    switch (this.options.direction) {
                        case 'rtl':
                        case 'ltr':
                        case 'r':
                            this.sourceElement.getElements('div.twiddlerChild').setStyles({
                                'left': '100%',
                                'visibility': 'visible'
                            });
                            break;
                        case 't2b':
                        case 'b2t':
                            this.sourceElement.getElements('div.twiddlerChild').setStyles({
                                'top': '100%',
                                'visibility': 'visible'
                            });
                    }

                    break;
            }
        } else {
            this.sourceElement.getElements('div.twiddlerChild').setStyles({
                'visibility': 'visible',
                'opacity': 1
            });
        }

        this.targetElement.setStyle('position', 'relative');

        this.sourceElement.getChildren().inject(this.targetElement);

        this.currentElement = 1;

        if (this.childCount > 1) {
            window.addEvent('load', function(){
                this.periodical = this.displayNext.periodical(this.options.delay, this);
            }.bind(this));
            if (this.options.showNavigation) {
                this.showNavigation();
            }
            this.show(this.currentElement);

            if (this.options.mouseOverPause) {
                // Establish the pause on mouse over
                this.targetElement.addEvents({
                    'mouseover': function(){
                        $clear(this.periodical);
                    }.bind(this),

                    'mouseout': function(){
                        this.resume();
                    }.bind(this)
                }, this);
            }
        }
    },

    // displayNext: twiddler function
    // Hides the currently displayed element and displays the next one

    displayNext: function(){
        this.hide(this.currentElement);
        this.currentElement++;
        if (this.currentElement > this.childCount) {
            this.currentElement = 1;
        }
        this.show(this.currentElement);
    },

    // display: twiddler function that hides the currently displayed element and displays the one passed
    // @param index (int) child number to display
    display: function(index){
        $clear(this.periodical);

        // No need to reshow the element if its being viewed
        if (this.currentElement != index) {
            this.hide(this.currentElement);
            this.currentElement = index;
            this.show(this.currentElement);
        }

        if (!this.options.mouseOverPause) {
            // We don't want to resume if mouse over is enabled as the mouse out will kick this off
            this.resume.delay(this.options.delay + 4, this);
        }
    },

    // resume: twiddler function that resumes the periodical twiddle

    resume: function(){
        $clear(this.periodical);
        this.periodical = this.displayNext.periodical(this.options.delay, this);
    },

    // show: twiddler function
    // @param index (int) child number to display

    show: function(index){
        if (this.options.showNavigation) {
            this.targetElement.getElement('a.p' + index).addClass('selected');
        }

        switch (this.options.transition) {
            case 'fade':
                this.targetElement.getElement('div.twiddlerChild:nth-child(' + index + ')').fade('in');
                break;
            case 'scroll':
                var element = this.targetElement.getElement('div.twiddlerChild:nth-child(' + index + ')');
                switch (this.options.direction) {
                    case 'rtl':
                        // Right to left
                        if (MooTools.version >= '1.2.1') {
                            element.tween('left', element.getSize().x, 0);
                        } else {
                            element.tween('left', element.getComputedSize().width, 0);
                        }
                        break;
                    case 'ltr':
                        // Left to right
                        if (MooTools.version >= '1.2.1') {
                            element.tween('left', element.getSize().x * -1, 0);
                        } else {
                            element.tween('left', element.getComputedSize().width * -1, 0);
                        }
                        break;
                    case 'r':
                        // Shows/hides from the right
                        if (MooTools.version >= '1.2.1') {
                            element.tween('left', 0, element.getSize().x);
                        } else {
                            element.tween('left', 0, element.getComputedSize().width);
                        }
                        break;
                    case 'b2t':
                        // Bottom to top
                        if (MooTools.version >= '1.2.1') {
                            element.tween('top', element.getSize().y, 0);
                        } else {
                            element.tween('top', element.getComputedSize().height, 0)
                        }
                        break;
                    case 't2b':
                        // Top to bottom
                        if (MooTools.version >= '1.2.1') {
                            element.tween('top', element.getSize().y * -1, 0);
                        } else {
                            element.tween('top', element.getComputedSize().height * -1, 0);
                        }
                        break;
                }
                break;
        }
    },

    // hide: twiddler function
    // @param index (int) child number to hide

    hide: function(index){
        if (this.options.showNavigation) {
            this.targetElement.getElement('a.p' + index).removeClass('selected');
        }

        switch (this.options.transition) {
            case 'fade':
                this.targetElement.getElement('div.twiddlerChild:nth-child(' + index + ')').fade('out');
                break;
            case 'scroll':
                var element = this.targetElement.getElement('div.twiddlerChild:nth-child(' + index + ')');
                switch (this.options.direction) {
                    case 'rtl':
                        // Right to left
                        if (MooTools.version >= '1.2.1') {
                            element.tween('left', 0, element.getSize().x * -1);
                        } else {
                            element.tween('left', 0, element.getComputedSize().width * -1);
                        }
                        break;
                    case 'ltr':
                        // Left to right
                        if (MooTools.version >= '1.2.1') {
                            element.tween('left', 0, element.getSize().x);
                        } else {
                            element.tween('left', 0, element.getComputedSize().width);
                        }
                        break;
                    case 'r':
                        // Shows/hides from the right
                        if (MooTools.version >= '1.2.1') {
                            element.tween('left', element.getSize().x, 0);
                        } else {
                            element.tween('left', element.getComputedSize().width, 0);
                        }
                        break;
                    case 'b2t':
                        // Bottom to top
                        if (MooTools.version >= '1.2.1') {
                            element.tween('top', 0, element.getSize().y * -1);
                        } else {
                            element.tween('top', 0, element.getComputedSize().height * -1);
                        }
                        break;
                    case 't2b':
                        // Top to bottom
                        if (MooTools.version >= '1.2.1') {
                            element.tween('top', 0, element.getSize().y);
                        } else {
                            element.tween('top', 0, element.getComputedSize().height);
                        }
                        break;
                }
                break;
        }
    },

    // showNaviation: displays page numbers

    showNavigation: function(){
        var container = new Element('div').addClass(this.options.navigationClass).inject(this.targetElement);
        for (page = 1; page <= this.childCount; page++) {
            var pageNav = new Element('a').addClass('page').inject(container);
            pageNav.addClass('p' + page);
            pageNav.set('text', page);
            pageNav.addEvent('click', function(el){
                this.display(el.target.get('text'));
            }.bind(this));
        }
    }
});

Twiddler.implement(new Events, new Options);

