// Copyright (c) 2006 Sébastien Gruhier (http://xilinus.com, http://itseb.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// VERSION 0.26
function $S(v) { return($(v).style); }
var Carousel = Class.create();
Carousel.prototype = {
    // Constructor
    initialize: function(carouselElemID) {
        this.carouselElemID = carouselElemID;

        this.options = Object.extend({
            numVisible:           1,
            scrollInc:            1,
            animParameters:      {},
            buttonStateHandler:  null,
            animHandler:         null,
            ajaxHandler:         null,
            initDoneHandler:     null,
            queue:               "carousel",
            size:                0,
            navisize:            0,
            prevElementID:       "prev-arrow",
            nextElementID:       "next-arrow",
            ajaxParameters:      null,
            url:                 null
        }, arguments[1] || {});

        this.initDone = false;
        this.animRunning = "none";
        this.requestIsRunning = false;

        // add afterFinish options to animParameters (store old function)
        this.animAfterFinish = this.options.animParameters.afterFinish;
        Object.extend(this.options.animParameters, {afterFinish:  this._animDone.bind(this), queue: { position:'end', scope: this.options.queue }});

        // Event bindings
        this.prevScroll = this._prevScroll.bindAsEventListener(this);
        this.nextScroll = this._nextScroll.bindAsEventListener(this);
        this.onComplete = this._onComplete.bindAsEventListener(this);
        this.onFailure  = this._onFailure.bindAsEventListener(this);

        Event.observe(this.options.prevElementID, "click", this.prevScroll);
        Event.observe(this.options.nextElementID, "click", this.nextScroll);

        // Get DOM UL element
        var carouselListClass = "carousel-list";
        this.carouselList     = document.getElementsByClassName(carouselListClass, $(carouselElemID))[0]
        this.naviList         = document.getElementById("naviItem");
        this.options.size     = $(this.carouselList.getElementsByTagName("li")).length;
        this.options.navisize = $(this.naviList.getElementsByTagName("li")).length;
        // Init data
        this._init();
    },

    // Destructor
    destroy: function() {
        Event.stopObserving(this.options.prevElementID, "click", this.prevScroll);
        Event.stopObserving(this.options.nextElementID, "click", this.nextScroll);
    },

    scrollTo: function(newStart) {
        var old_inc = this.options.scrollInc;
        this.ignoreNoMoreImages = true;
        if(newStart > this.currentIndex) {
            this.options.scrollInc = newStart - this.currentIndex;
            this._nextScroll(this);
        } else {
            this.options.scrollInc = this.currentIndex - newStart;
            this._prevScroll(this);
        }
        this.options.scrollInc = old_inc;
    },

    /* "Private" functions */
    _init: function() {
        this.currentIndex = 0;

        // Ajax content
        if (this.options.url && this.options.size == 0)
        {
            this._request(this.currentIndex, this.options.numVisible);
            // Static content
        } else if (this.initDone == false && this.options.url)
        {
            this._getLiElementSize()
            this.currentIndex = 0;
            this.initDone = true;
            if (this.options.initDoneHandler)
            this.options.initDoneHandler(this);

            // Update button states
            this._updateButtonStateHandler(this.options.prevElementID, false);
            this._updateButtonStateHandler(this.options.nextElementID, this.options.size == this.options.numVisible);
            this.noMoreImages = this.options.size < this.options.numVisible;
        } else
        {
            this._getLiElementSize();
            this._updateButtonStateHandler(this.options.prevElementID, false);
            this._updateButtonStateHandler(this.options.nextElementID, this.options.size > this.options.numVisible);
        }
    },

    _prevScroll: function(event) {
        if (this.animRunning != "none" || this.currentIndex == 0)
        return;

        var inc = this.options.scrollInc;

        if (this.currentIndex - inc < 0)
        inc = this.currentIndex;

        this._scroll(inc)
        return false;
    },

    _nextScroll: function(event) {
        if (this.animRunning != "none")
        return false;

        // Check if there are enough elements in cache

        // alert('Size: ' + this.options.size + ' Current Index: ' + this.currentIndex + ' Num visible: ' + this.options.numVisible + ' Scroll inc: ' + this.options.scrollInc);

        if (this.currentIndex + this.options.numVisible + this.options.scrollInc <= this.options.size)
        {
            this._scroll(-this.options.scrollInc);
        } else
        {
            // Compute how many are in the cache
            this.nbInCache = this.options.size - (this.currentIndex + this.options.numVisible);
            if (this.options.url)
            {
                this._request(this.currentIndex + this.options.numVisible + this.nbInCache, this.options.scrollInc - this.nbInCache);
            } else
            {
                if (this.nbInCache > 0)
                {
                    this._scroll(-this.nbInCache);
                }
            }
        }
        return false;
    },

    _request: function(start, nb) {
        if (this.options.url && ! this.requestIsRunning) {
            this.requestIsRunning = true;

            if (this.options.ajaxHandler)
            this.options.ajaxHandler(this, "before");

            var params = "start=" + start + "&nb=" + nb;
            if (this.options.ajaxParameters != null)
            params += "&" + this.options.ajaxParameters

            new Ajax.Request(this.options.url, {parameters: params, onComplete: this.onComplete, onFailure: this.onFailure});
        }
    },


    _attachNewPhotos : function(response)
    {
        eval("var news = ("+response+")");

        if (news.length > 0)
        {
            
            var l = news.length;
            if (l > 1) l--;
            
            for (var i = 0; i < l; i++)
            {
                var li 	 = document.createElement('li');
    
                var h2       = document.createElement('h2');
                h2.innerHTML = 'Destaques:';
    
                var img = document.createElement('img');
                img.setAttribute('src', news[i].image);
                img.setAttribute('alt', '');
    
                var h3       = document.createElement('h3');
                h3.innerHTML = '<a href="/materia/' + news[i].guid + '/">' + news[i].title + '</a>';
    
                var p        = document.createElement('p');
                p.innerHTML  = news[i].desc;
    
                var p2       = document.createElement('p');
                p2.setAttribute('class', 'readMore');
                p2.innerHTML = '<a href="/materia/' + news[i].guid + '/">Ler Tudo</a>';
    
                var div = document.createElement('div');
                div.className = 'newsText';
    
                var div2 = document.createElement('div');
                div2.className = 'newsOverlay';
    
                div.appendChild(h3);
                div.appendChild(p);
                div.appendChild(p2);
    
    
                li.appendChild(h2);
                li.appendChild(img);
                li.appendChild(div);
                li.appendChild(div2);
    
                this.carouselList.appendChild(li);
    
                if (i != 0)
                {
                    var naviLi       = document.createElement("li");
                    var naviStar     = document.createElement("span");
                    var naviTitle    = document.createElement("span");
        
                    naviStar.className   = "naviStar";
                    naviTitle.className  = "naviTitle";
        
                    naviStar.innerHTML   = news[i].star;
                    naviTitle.innerHTML  = news[i].title;
        
                    naviLi.setAttribute('id', 'navi' + (this.options.navisize + i - 1));
                    naviLi.appendChild(naviStar);
                    naviLi.appendChild(naviTitle);
        
        
                    $('naviItem').appendChild(naviLi);
                }
            }
            if (l != news.length)
            {
                
                var naviLi       = document.createElement("li");
                var naviStar     = document.createElement("span");
                var naviTitle    = document.createElement("span");
    
                naviStar.className   = "naviStar";
                naviTitle.className  = "naviTitle";
    
                naviStar.innerHTML   = news[l].star;
                naviTitle.innerHTML  = news[l].title;
    
                naviLi.setAttribute('id', 'navi' + (this.options.navisize + l - 1));
                naviLi.appendChild(naviStar);
                naviLi.appendChild(naviTitle);
    
    
                $('naviItem').appendChild(naviLi);
            }
        }

    },

    _onComplete: function(originalRequest)
    {                 
        this.requestIsRunning = false;
        this._attachNewPhotos(originalRequest.responseText);
        //this.carouselList.innerHTML += originalRequest.responseText;
        // Compute how many new elements we have
        var size = this.options.size;
        this.options.size     = this.carouselList.getElementsByTagName("li").length;
        this.options.navisize = this.naviList.getElementsByTagName("li").length;
        var inc = this.options.size - size;

        // First run, compute li size
        if (this.initDone == false) {
            this._getLiElementSize()
            this.currentIndex = 0;
            this.initDone = true;
            if (this.options.initDoneHandler)
            this.options.initDoneHandler(this);

            // Update button states
            this._updateButtonStateHandler(this.options.prevElementID, false);
            this._updateButtonStateHandler(this.options.nextElementID, this.options.size == this.options.numVisible);
            this.noMoreImages = this.options.size < this.options.numVisible
        }
        // Add images
        else {
            if (!this.ignoreNoMoreImages)
            {
                this.noMoreImages = inc != this.options.scrollInc;
            } else
            {
                this.ignoreNoMoreImages = false;
            }
            // Add images
            if (inc > 0)
            {                            
                this._scroll(-this.options.scrollInc, this.noMoreImages)
            }
            // No more images, disable next button
            else {
                if (this.nbInCache >0)
                this._scroll(-this.nbInCache, true);

                this._updateButtonStateHandler(this.options.nextElementID, false);
            }
        }
        
        if (this.options.ajaxHandler)
        this.options.ajaxHandler(this, "after");        
    },

    _onFailure: function(originalRequest){
        this.requestIsRunning = false;
    },

    _animDone: function(event){
        if (this.options.animHandler)
        this.options.animHandler(this.carouselElemID, "after", this.animRunning);

        this.animRunning = "none";
        // Call animAfterFinish if exists
        if (this.animAfterFinish)
        this.animAfterFinish(event);
    },

    _updateButtonStateHandler: function(button, state) 
    {

        if (this.options.buttonStateHandler)
        this.options.buttonStateHandler(button, state)        
        this._setNavi();
    },

    _scroll: function(delta, forceDisableNext) {
        this.animRunning = delta > 0 ? "prev" : "next";

        if (this.options.animHandler)
        this.options.animHandler(this.carouselElemID, "before", this.animRunning);

        new Effect.MoveBy(this.carouselList, 0, delta * this.elementSize, this.options.animParameters);
        this.currentIndex -= delta;

        this._updateButtonStateHandler(this.options.prevElementID, this.currentIndex != 0);

        if (this.options.url && this.noMoreImages == false)
        enable = true;
        else
        enable = (this.currentIndex + this.options.numVisible < this.options.size);
        this._updateButtonStateHandler(this.options.nextElementID, (forceDisableNext ? false : enable));
    },

    _getLiElementSize: function() {
        var li = $(this.carouselList.getElementsByTagName("li")[0]);
        this.elementSize = li.getDimensions().width + parseFloat(li.getStyle("margin-left")) + parseFloat(li.getStyle("margin-right"));
    },

    _setPrevButton : function(nr)
    {
        var starBox    = $('prev-arrow-container').getElementsByTagName("h4")[0];
        var titleBox   = $('prev-arrow-container').getElementsByTagName("h5")[0];

        starBox.innerHTML  = $('navi' + nr).getElementsByClassName("naviStar")[0].innerHTML;
        titleBox.innerHTML = '&quot;' + $('navi' + nr).getElementsByClassName("naviTitle")[0].innerHTML + '&quot;';
    },

    _setNextButton : function(nr)
    {
        var starBox    = $('next-arrow-container').getElementsByTagName("h4")[0];
        var titleBox   = $('next-arrow-container').getElementsByTagName("h5")[0];

        starBox.innerHTML  = $('navi' + nr).getElementsByClassName("naviStar")[0].innerHTML;
        titleBox.innerHTML = '&quot;' + $('navi' + nr).getElementsByClassName("naviTitle")[0].innerHTML + '&quot;';
    },

    _setNavi : function()
    {
        if (this.options.size > 0)
        {
            if (this.currentIndex == 0)
            {
                $S('prev-arrow-container').backgroundColor = "#7c5b2c";
                $S('next-arrow-container').backgroundColor = "#ac803f";
                if (this.options.size > 1)
                {
                    this._setPrevButton(0);
                    this._setNextButton(1);
                } else
                {
                    if (this.options.size != this.options.navisize)
                    {
                        this._setPrevButton(0);
                        this._setNextButton(1);
                    } else
                    {
                        this._setPrevButton(0);
                        this._setNextButton(0);
                        $S('next-arrow-container').backgroundColor = "#7c5b2c";
                    }

                }
            } else
            {
                
                this._setPrevButton(this.currentIndex - 1);
                $S('prev-arrow-container').backgroundColor = "#ac803f";

                if (this.currentIndex == (this.options.size - 1))
                {                 
                    if (this.options.size != this.options.navisize)
                    {
                        this._setNextButton(this.currentIndex + 1);
                        $S('next-arrow-container').backgroundColor = "#ac803f";
                    } else
                    {
                        this._setNextButton(this.currentIndex);
                        $S('next-arrow-container').backgroundColor = "#7c5b2c";
                    }
                } else
                {                 
                    $S('next-arrow-container').backgroundColor = "#ac803f";
                    this._setNextButton(this.currentIndex + 1);
                }
            }
        }
    }
};