/**
 * dm3Slider
 * ver 1.0.2
 * author: D. Danylov
 */
(function($) {
	function dm3Slider(container, options) {
		this.o = options;
		this.container = $(container);
		this.slides = this.container.children();
		this.numSlides = this.slides.length;
		this.curSlideNum = 0;
		this.prevSlideNum = 0;
		this.freeze = false; // freeze the automatic slide transition on mouse over
		
		var that = this;
		var i = 0;
		var slide_height = 0;
		
		// Prepare each slide
		this.slides.each(function() {
			var slide = $(this);
			
			slide.css({
				position: 'absolute',
				left: 0,
				top: 0,
				'z-index': 7
			});
			
			if (i == that.curSlideNum) {
				slide.css('z-index', 9);
				that.changeCaption(slide);
			}
			
			// Find caption
			slide.data('caption', slide.find('img:first').attr('title'));
			slide.find('img:first').removeAttr('title');
			
			if (i == 0) {
				slide_height = slide.height();
			}
			
			this.slideIdx = i;
			++i;
		});
		
		this.container.css({
			position: 'relative',
			height: slide_height + 'px'
		});
		
		this.addControlNav();
		
		// Slides rotation interval
		if (this.o.interval) {
			setInterval(function() {
				if (that.freeze)
					return;
					
				var next_slide_num = that.getNextSlideNum(that.curSlideNum);
				that.changeSlide(next_slide_num);
			}, this.o.interval * 1000);
		}
		
		this.container.hover(function() {
			that.freeze = true;
		}, function() {
			that.freeze = false;
		});
	}
	
	/**
	 * Generate controls
	 */
	dm3Slider.prototype.addControlNav = function() {
		var controls;
		
		if (this.o.controlsCallback == null) {
			// Generate default controls
			controls = $('<div class="dm3Slider_controls"></div>');
			var slideIdx, control, slide;
			var that = this;
			
			this.slides.each(function() {
				slideIdx = this.slideIdx;
				slide = $(this);
				
				if (that.o.controlCallback == null) {
					control = $('<a id="control_'+slideIdx+'" href="#">' + (slideIdx + 1) + '</a>');
				} else {
					// Use customized control
					control = that.o.controlCallback.call(that, slideIdx, slide);
				}
				
				control.click(function(e) {
					e.preventDefault();
					var slideIdx = this.getAttribute('id').replace('control_', '');
					that.changeSlide(slideIdx);
				});
				
				controls.append(control);
				
				if (slideIdx == that.curSlideNum) {
					control.addClass('active');
				}
			});
		} else {
			// Use customized controls
			controls = this.o.controlsCallback.call(this);
		}
		
		this.controls = controls.children();
		this.container.append(controls);
	};
	
	/**
	 * Change the slide
	 */
	dm3Slider.prototype.changeSlide = function(slideNum) {
		if (slideNum == this.curSlideNum)
			return false;

		var that = this;
		var prevSlide = this.slides.eq(this.curSlideNum);
		var nextSlide = this.slides.eq(slideNum);
		
		prevSlide.css({'z-index': 8});
		nextSlide.css({'opacity': 0, 'z-index': 9});
		
		nextSlide.animate({opacity: 1}, {duration: this.o.speed, complete: function() {
			prevSlide.css({'z-index': 7});
		}});
		
		that.changeCaption(nextSlide);
		
		this.prevSlideNum = this.curSlideNum;
		this.curSlideNum = slideNum;
		
		// highlight the right control
		var prev = that.controls.eq(this.prevSlideNum);
		var next = that.controls.eq(this.curSlideNum);
		prev.removeClass('active');
		next.addClass('active');
		
		if (this.o.afterChangeSlide != null)
			this.o.afterChangeSlide.call(this);
	};
	
	/**
	 * Change the caption
	 */
	dm3Slider.prototype.changeCaption = function(slide) {
		var that = this;
		var caption = this.container.find('.dm3Slider_caption:first');
		
		if (!caption.length) {
			caption = $('<div class="dm3Slider_caption"></div>').css({opacity: 0}).appendTo(this.container);
		}
		
		// Cancel previous animation
		caption.stop();
		caption.animate({opacity: 0}, {duration: 300, complete: function() {
			// Set the caption content
			// Get caption content
			var caption_content = slide.data('caption');
			if (typeof caption_content == 'undefined' || caption_content == '') {
				// don't continue if there is no caption for current slide
				return;
			} else if (caption_content.substring(0, 1) == '#') {
				caption_content = $(caption_content).html();
			}
			caption.html(caption_content);
			
			caption.animate({opacity: 1}, {duration: 300});
			
			if (that.o.afterCaption != null) {
				that.o.afterCaption.call(that, caption);
			}
		}});
	};
	
	/**
	 * Get the number of the previous slide
	 */
	dm3Slider.prototype.getPrevSlideNum = function(slideNum) {
		if (slideNum == 0) {
			return this.numSlides - 1; // we count slides from 0
		} else {
			return (slideNum - 1);
		}
	};
	
	/**
	 * Get the number of the next slide
	 */
	dm3Slider.prototype.getNextSlideNum = function(slideNum) {
		if (slideNum >= this.numSlides - 1) { // we count slides from 0
			return 0;
		} else {
			return ++slideNum;
		}
	};
	
	/**
	 * Initialize the plugin
	 */
	$.fn.dm3Slider = function(options) {
		// Defaults
		var o = {
			speed: 400,
			interval: 0,
			controlCallback: null,
			controlsCallback: null,
			afterCaption: null,
			afterChangeSlide: null
		};
		
		return this.each(function() {
			
			if (options) {
				$.extend(o, options);
			}
			
			new dm3Slider(this, o);
			
		});

	}; // End of plugin	
})(jQuery);
