(function($){

	/**
	 * The constructor of the Slider Javascript class.
	 * @element - the element which is transferred to the slider component.
	 * @options - options for the slider.
	 */
	var Slider = function(element, options)
	{
		var sliderElement = $(element);
		var self = this; // This instance.
		var timer = null;

		var numberOfSlides = 0;
		var activeSlideIndex = 0;
		var divElements = [];

		var conf = $.extend({
			sliderTimeout:	10000,	// The timeout for the timer (in milliseconds).
			animationSpeed:	300	// How long the opacity changing effect takes (in milliseconds).
		}, options || {});

		/**
		 * Initializes the slider component. It is called only at the beginning.
		 */
		this.initSlider = function() {
			var i;

			sliderElement.append('<div id="slide-left"></div><div id="slide-right"></div>');

			// Getting the collection of slider divs.
			$("div.slide", sliderElement).each(function(i){
				divElements[i] = $(this);
			});

			// Getting the number of slides.
			numberOfSlides = divElements.length;

			// Setting the first slide active and hiding other slides.
			activeSlideIndex = 0;
			for (i in divElements) {
				if (parseInt(i) !== activeSlideIndex) {
					divElements[i].css({opacity:0}).css({zIndex:0});
				} else {
					divElements[i].css({opacity:1}).css({zIndex:1});
				}
			}

			// Initializing the timer.
			this.setTimer();

			// Binding slider events.
			$('#slide-left', sliderElement).click(function(){
				clearTimeout(timer);
				self.prevSlide();
				self.setTimer();
			});
			$('#slide-right', sliderElement).click(function(){
				clearTimeout(timer);
				self.nextSlide();
				self.setTimer();
			});
		};

		/**
		 * Changes the active slide to the given slide.
		 */
		this.changeSlide = function(newSlideIndex) {
			divElements[activeSlideIndex].stop().animate(
				{opacity:0},
				conf.animationSpeed).css({zIndex:0});
			divElements[newSlideIndex].stop().animate(
				{opacity:1},
				conf.animationSpeed).css({zIndex:1});
			activeSlideIndex = newSlideIndex;
		};

		/**
		 * Changes the active slide to the next one.
		 */
		this.nextSlide = function() {
			var newSlideIndex = (parseInt(activeSlideIndex) + 1) % parseInt(numberOfSlides);
			self.changeSlide(newSlideIndex);
		};

		/**
		 * Changes the active slide to the previous one.
		 */
		this.prevSlide = function() {
			var newSlideIndex = (parseInt(activeSlideIndex) + numberOfSlides - 1) % parseInt(numberOfSlides);
			self.changeSlide(newSlideIndex);
		};

		/**
		 * Sets the timer
		 */
		this.setTimer = function() {
			timer = setInterval(self.nextSlide, conf.sliderTimeout);
		};

		this.initSlider();

	};

	// jQuery plugin implementation
	$.fn.slider = function(conf) {

		// return existing instance
		var api = $(this).data("slider");
		if (api) { return api; }

		// install slider for each entry in jQuery object
		this.each(function() {
			api = new Slider(this, conf);
			$(this).data("slider", api);
		});

		return api;
	};

})(jQuery);

