var CarouselOrig = Class.create();
CarouselOrig.prototype = {
    // Constructor
    initialize: function(carouselElemID) {
        this.carouselElemID = carouselElemID;
		var carouselList = "carousel-list";
        $(carouselList).innerHTML = '';
        this.options = Object.extend({
            numVisible:           5,
            scrollInc:            5,
            animParameters:      {},
            buttonStateHandler:  null,
            animHandler:         null,
            ajaxHandler:         null,
            initDoneHandler:     null,
            queue:               "carousel",
            size:                0,
            prevElementID:       "prev-arrow",
            nextElementID:       "next-arrow",
            ajaxParameters:      null,
            url:                 null
        }, arguments[1] || {});

		if ($('year')) 
			this.year = $('year').value;
		else
			this.year = '';
        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
        		
        this.carouselList = $(carouselList);
        this.options.size =  $(this.carouselList.getElementsByTagName("img")).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.year)
            {
            	params += '&year=' + this.year;
            } else
            {
            	params += '&year=0';
            }
            
            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 photos = ("+response+")");
                
        for (var i = 0; i < photos.length; i++)
        {
			var li 		= document.createElement('li');
           	var a		= document.createElement('a');
           	var img 	= document.createElement('img');
           	var span	= document.createElement('span');
           	
			a.className = 'carouselIssue';
			a.setAttribute('href', '/archiwum/' + parseInt(photos[i].year) + '/' + parseInt(photos[i].number));                      
			img.setAttribute('src', photos[i].image);
			img.setAttribute('alt', '');
           
			span.innerHTML = '<em>nr ' + photos[i].number + '</em> / ' + photos[i].year;           
           	a.appendChild(img);
           	a.appendChild(span);
           	           
           	li.appendChild(a);
           	
           	var ol = document.createElement('ol');
           	for (var j = 0; j < photos[i].list.length; j++)
           	{
           		var item = photos[i].list[j];
           		
           		var li2 = document.createElement('li');
           		
           		if (j == 0) li2.className = 'firstItem';
           		
           		if (item.link)
           		{
           			li2.innerHTML = '<a href="http://' + item.link + '">' + item.title + '</a>';
           		} else
           		{
           			li2.innerHTML = item.title;
           		}
           		ol.appendChild(li2);
           	}
            li.appendChild(ol);
           	this.carouselList.appendChild(li);                 
        }     
    },
    
    _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("img").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) 
            {
            	if (inc < this.options.scrollInc)
            	{
            		this._scroll(-inc, this.noMoreImages)
            	} else
            	{         	
                	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)
    },

    _scroll: function(delta, forceDisableNext) {
        this.animRunning = delta > 0 ? "prev" : "next";

        if (this.options.animHandler)
        this.options.animHandler(this.carouselElemID, "before", this.animRunning);

        this.effect = 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]);
        if (li)     
        this.elementSize = li.getDimensions().width + parseFloat(li.getStyle("margin-left")) + parseFloat(li.getStyle("margin-right"));        
    },
    reset: function()
    {  	
    	try
    	{    	
	        if (this.effect)
	        {
	            this.effect.cancel();
	            this._animDone();
	        }
	        this.carouselList.style.left    = '0px';
	        this.currentIndex               = 0;
	        if (this.carouselList.hasChildNodes())
	        {
	            while (this.carouselList.childNodes.length >= 1)
	            {
	                this.carouselList.removeChild(this.carouselList.firstChild);
	            }
	        }
			this.options.size = 0;
	        this.initDone = false;	            
	        this._init();      
	        return false;  
		} catch(ex) {alert(ex); }
    },
    setYear: function(year)
    {    	
    	if (year)
    	{
	    	this.year = year;
	    	this.reset();
    	}
    }
};


function initCarousel_html_carousel()
{
    carousel = new CarouselOrig(
    'small-carousel',
    {
        animHandler:animHandler,
        buttonStateHandler:buttonStateHandler,
        animParameters:{duration:0.5},
        nextElementID:'next',
        prevElementID:'prev',
        numVisible:5,
        ajaxHandler:ajaxHandler,
        url:'/default/magazine/slider'
    });
};


Event.observe(window, 'load', initCarousel_html_carousel);