


if (typeof UI == "undefined") { var UI = new Object(); }
UI.Slider = Class.create();
    
UI.Slider.prototype = {

    initialize: function(params) {

        this.options = Object.extend({
            visibleHeight: 2,
            visibleWidth: 2,



            autoScroll: 0,
            randomStartPosition: 0
        },params || {});
        
        this.animating = false;  // are we in the middle of rotating pages?
        this.timer = null; // holder for animation timer

        if (this.options.containerElement) { 

            var elContainer = this.options.containerElement;

            this.container = Element.getElementsByClassName(elContainer, "sliderRender")[0];
            this.itemList = Element.getElementsByClassName(elContainer, "sliderContent")[0];

            var prevEl = Element.getElementsByClassName(elContainer, "sliderPrev")[0];
            var nextEl = Element.getElementsByClassName(elContainer, "sliderNext")[0];
            Event.observe(prevEl, "click", this.doClickPrev.bindAsEventListener(this), false);
            Event.observe(nextEl, "click", this.doClickNext.bindAsEventListener(this), false);

            // this allows us to catch the click for inline audio playback before the click event is swallowed
            Event.observe(this.container, "mousedown", this.clearAutoScroll.bindAsEventListener(this), false);

            // we should also setup click/hover stats for the next/prev buttons once those are designed.

        } else { 

            this.container = $(this.options.renderElementId); // container element we're rendering into
            this.itemList  = $(this.options.listElementId);   // element that holds the list of content items

            // hook up event handlers to buttons
            Event.observe($(this.options.prevElementId), "click", this.doClickPrev.bindAsEventListener(this), false);
            Event.observe($(this.options.nextElementId), "click", this.doClickNext.bindAsEventListener(this), false);
        }

        this.pages = [];      // array of pages to display
        this.currentPage = 1; // page we're showing now 

        // grab items and count total pages;
        var items = [];

        var node = this.itemList.firstChild;
        while (node) {
            var nextNode = node.nextSibling;
            if (node.nodeType == 1) {
                items.push(Element.remove(node));
            }
            node = nextNode;
        }
        
        if (this.options.randomStartPosition) { 
            var head = items.splice(Math.floor(Math.random()*items.length));
            items = head.concat(items);
        }

        this.itemWidth  = Math.ceil(parseFloat(Element.getStyle(this.container.parentNode, "width")) / this.options.visibleWidth);
        this.itemHeight = Math.ceil(parseFloat(Element.getStyle(this.container.parentNode, "height")) / this.options.visibleHeight);
        this.pageWidth  = parseInt(Element.getStyle(this.container.parentNode, "width"), 10);
        this.totalPages = Math.ceil(items.length / (this.options.visibleHeight * this.options.visibleWidth));

        // try and back fill if we have insufficient items for the slider by cloning previous items,
        // otherwise give up and deal with some empty slots
        try {
            var clonePosition = 0;
            while (this.totalPages != (items.length / (this.options.visibleHeight * this.options.visibleWidth))) {
                items.push(items[clonePosition].cloneNode(true));
                clonePosition++;
            }
        } catch (err) { }

        // create page elements, putting items in TD's, shifting from array.
        var singlePage, row, cell, item;            
        for (var p=0; p<this.totalPages; p++) {
            
            singlePage = document.createElement("table");
            singlePage.appendChild(document.createElement("tbody"));

            singlePage.border = "0";
            singlePage.cellPadding = "0";
            singlePage.cellSpacing = "0";
            Element.addClassName(singlePage, "sliderPage");
            singlePage.width = this.pageWidth;
            Element.setStyle(singlePage, {width: this.pageWidth});
            
            for (var h=0; h<this.options.visibleHeight; h++) {
                row = document.createElement("tr");
                for (var w=0; w<this.options.visibleWidth; w++) {
                    cell = document.createElement("td");
                    cell.width  = this.itemWidth;
                    cell.height = this.itemHeight;
                    Element.setStyle(cell, {verticalAlign: "top"});
                    item = items.shift();
                    if (item) { 
                        cell.appendChild(item);
                    }
                    row.appendChild(cell);
                }
                singlePage.appendChild(row);                    
            }

            try {
                this.container.appendChild(singlePage);
            } catch(e) {}

        }

        // hack hack hack for IE6
        this.container.innerHTML = this.container.innerHTML;
        this.position = 0;
        
        this.setAutoTimer();
    },
    
    setAutoTimer: function() {
        if (this.autoScrollTimer) {
            clearInterval(this.autoScrollTimer);
        }
        if (this.options.autoScroll > 0) {
            this.autoScrollTimer = setInterval(this.doNext.bindAsEventListener(this), (this.options.autoScroll * 1000));
        }
    },

    movePage: function(direction) {
        // remove child from front/back, append to front/back
        if (direction == "front") {

            var el = this.container.lastChild;
            while (el.nodeType != 1) {
                el = el.previousElement;
            }
            this.container.insertBefore(this.container.removeChild(el), this.container.firstChild);
            this.position = this.position - this.pageWidth;

        } else if (direction == "back") {

            var el = this.container.firstChild;
            while (el.nodeType != 1) {
                el = el.nextElement;
            }
            this.container.appendChild(this.container.removeChild(el));             
            this.position = this.position + this.pageWidth;

        }

        this.container.setStyle({left: (this.position + "px")});
    },
    
    doPrev: function() {
        this.currentPage--;
        if (this.currentPage < 1) {
            this.movePage("front"); 
            this.currentPage = 1;
        }

        this.position = this.position + this.pageWidth;
        this.container.morph({left: (this.position + "px")}, {duration: 0.5,  transition: Effect.Transitions.sinoidal});
    },
    
    doNext: function() {
        this.currentPage++;
        if (this.currentPage > this.totalPages) {
            this.movePage("back"); 
            this.currentPage = this.totalPages;
        }       

        this.position = this.position - this.pageWidth;
        this.container.morph({left: (this.position + "px")}, {duration: 0.5,  transition: Effect.Transitions.sinoidal});
    },
    
    // wrapper functions to differ between user click and auto-rotate
    doClickPrev: function() {
        this.clearAutoScroll();
        this.doPrev();
    },
    
    doClickNext: function() {
        this.clearAutoScroll();
        this.doNext();
    },

    clearAutoScroll: function() {
        this.options.autoScroll = 0;
        this.setAutoTimer();
    }   

}
