/**************************************
 *	Create ListSliders
 **************************************/
window.addEvent('domready', function(){
	$$('div.slider').each(function(slider){
		var slider = new ListSlider({
			slider:				slider,
			previousButton:		slider.getElement('button.previous'),
			nextButton:			slider.getElement('button.next'),
			autoSlideInterval:	10000
		});
	})
});


/**************************************
 *	ListSlider
 **************************************/
ListSlider = new Class({
	
	options:	{
		slider:				false,
		previousButton:		false,
		nextButton:			false,
		transition:			Fx.Transitions.Back.easeOut,
		duration:			500,
		autoSlideInterval:	false
	},
	
	inTransition:			false,
	slideList:				false,
	sliderWidth:			false,
	itemWidth:				false,
	itemCount:				false,
	visibleItems:			false,
	slideEffect:			false,
	currentItem:			0,
	currentDirection:		0,
	queuedImages:			false,
	autoSlideIntervalId:	false,
	
	/**
	 *	Initialize
	 */
	initialize: function(options){
		// Fetch options
		this.setOptions(options);

		this.slideList		= this.options.slider.getElement('ul');
		if (this.slideList)	{
			this.sliderWidth	= this.options.slider.getSize().x;

			listItem 			= this.slideList.getElement('li');
			this.itemWidth		= listItem.getSize().x + parseInt(listItem.getStyle('margin-left')) + parseInt(listItem.getStyle('margin-right'));
			this.itemCount		= this.slideList.getElements('li').length;
			this.visibleItems	= Math.ceil(this.sliderWidth / this.itemWidth);
			
			// Place loading of invisible items in queue. We will only load visible items + next range to decrease http requests
			this.queuedImages = new Array();
			var images = this.slideList.getElements('img[id]');
			images.each(function(image){
				image.queuedSrc = '/uploads/images/' + image.id.replace('preload_', '') + '.jpg';
				this.queuedImages.push(image);
			}, this)
			
			// Create slide effect
			this.slideEffect 	= new Fx.Tween(this.slideList, {
				duration:	this.options.duration,
				transition:	this.options.transition,
				property:	'margin-left'
			});
			
			// Enable autoslide
			if(this.options.autoSlideInterval){
				this.autoSlideIntervalId = this.autoSlide.periodical(this.options.autoSlideInterval, this);
			}
		
			// Add handlers
			this.addHandlers();

			// Disable unusable buttons
			this.disableUnusable();
		}
		else
			this.disableAll();
	},
	
	/**
	 *	Add eventhandlers
	 */
	addHandlers: function(){
		
		// Disable following of link
		this.options.previousButton.onclick = function(){ return false; }
		this.options.nextButton.onclick = function(){ return false; }
		
		// Slide events
		this.options.previousButton.addEvent('click', this.slidePrevious.bind(this));
		this.options.nextButton.addEvent('click', this.slideNext.bind(this));
		this.slideEffect.addEvent('onComplete', function(){
			this.inTransition = false;												 
		}.bind(this));
		
		// Autoslide disable events
		this.options.previousButton.addEvent('click', function(){
			$clear(this.autoSlideIntervalId);
		}.bind(this));
		this.options.nextButton.addEvent('click', function(){
			$clear(this.autoSlideIntervalId);
		}.bind(this));
	},
	
	/**
	 *	Slide to previous item
	 */
	slidePrevious: function(e){
		if(!this.options.previousButton.disabled){
			this.slide(this.itemWidth);
		}
	},
	
	slideNext: function(e){
		if(!this.options.nextButton.disabled){
			this.slide(0 - this.itemWidth);
		}
	},
	
	/**
	 *	Perform slide
	 */
	slide: function(direction){
		
		// Load next range of queued images
		if(direction < 0 && this.queuedImages.length){
			for(i = 0; i < this.visibleItems; i++){
				if(image = this.queuedImages[i]){
					image.src = image.queuedSrc;
					image.queuedSrc = null;
				}
				this.queuedImages.remove(image);
			}
		}
	
		// Perform slide
		if(!this.inTransition){
			newMargin = parseInt(this.slideList.getStyle('margin-left')) + direction;
			this.inTransition = true;
			this.slideEffect.start(newMargin);
			
			// Determine current item (on left side)
			this.currentItem += (direction > 0)? -1 : 1;
			
			// Enabled or disable buttons
			this.disableUnusable();		
		}
		
		// Set current direction
		this.currentDirection = direction;
	},
	
	/**
	 * Perform autoslide
	 */
	autoSlide: function(){
		if(this.currentItem + this.visibleItems <= this.itemCount && this.currentDirection <= 0){
			this.slideNext();
		}else if(this.currentItem > 0 && this.currentItem > 0){
			this.slidePrevious();
		}else if(this.currentItem == 0 && this.currentDirection > 0){
			this.currentDirection = -this.currentDirection;
		}
	},
	
	/**
	 *	Disable buttons that are not usable
	 */ 
	disableUnusable: function(){
		visibleItems = parseInt(this.sliderWidth / this.itemWidth);
		maxItem = this.itemCount - visibleItems;

		if((this.currentItem == maxItem) || (this.itemCount <= visibleItems)){
			this.options.nextButton.addClass('disabled');
			this.options.nextButton.disabled = true;
		}else{
			this.options.nextButton.removeClass('disabled');
			this.options.nextButton.disabled = false;
		}
		
		if(this.currentItem == 0){
			this.options.previousButton.addClass('disabled');
			this.options.previousButton.disabled = true;
		}else{
			this.options.previousButton.removeClass('disabled');
			this.options.previousButton.disabled = false;	
		}
	},

	disableAll: function() {
		this.options.nextButton.addClass('disabled');
		this.options.nextButton.disabled = true;

		this.options.previousButton.addClass('disabled');
		this.options.previousButton.disabled = true;
	}
});
ListSlider.implement(new Options);