(function($){
	$.fn.jAccordion = function(options) {
		var defaults = {
			slideMaxWidth : 650,
			slideDuration : 500,
			spacing : 0,
			event : 'mouseenter',
			sticky : false,
			autoplay : false,
			autoplayDelay : 3000,
			pauseOnHover : true,
			countdownMaxWidth : 650,
			activeSlide : null,			
			usePreloader : true,
			preloadFadeInDuration : 500,
			preloaderImg : 'images/ajax-loader.gif',
			activatedSlideID : 'active_slide',
			slidesEasing : 'swing',			
			onSlideOpened : function() {},
			onSlideStartOpening : function() {},
			onSlideStartClosing : function() {}
		}		
		var options = $.extend(defaults, options);
		return this.each(function() {
			var accordion = $(this);
			var slides = $('li', accordion);
			var slidesNmbr = slides.length;
			var accordionWidth = accordion.width();
			var inactiveSlideWidth = Math.round((accordionWidth / slidesNmbr) + (options.spacing / (slidesNmbr - 1)));
			var activatedSlide = null;
			var activatedSlideIndex;
			var slideOpening = false;
			var hovered = false;
			var shrinkedSlideWidth = Math.round((accordionWidth - options.slideMaxWidth)  / (slidesNmbr - 1));
			
			accordion.methods = {
				init : function() {
					$('ul', accordion).css({'width' : '100%', height : accordion.height(), 'position' : 'relative', 'overflow' : 'hidden'}).parent().css({'position' : 'static', 'overflow' : 'visible'});					
					if (options.autoplay) autoPlay.init();
					slides.each(function(e) {
						var currSlide = $(this);
						
						currSlide.removeClass('noJS');	//Javascript is enabled, no need to use js fallback
						currSlide.css({'position' : 'absolute', width : inactiveSlideWidth - options.spacing, 'left' : (e * inactiveSlideWidth) + 'px'});	//Set width and position of curr slide
						
						currSlide.bind(options.event, function() {
							$(this).triggerHandler('openSlide');
						}).bind('mouseleave', function() {
							$(this).triggerHandler('closeSlide');
						});
						
						currSlide.bind('openSlide', function() {				
							if (activatedSlide == null || $(this)[0] != activatedSlide[0]) {
								if (options.autoplay) {		//Stop autoPlay before current slide is open
									autoPlay.stop();
									slideOpening = true;
								}
								activatedSlideIndex = $(this).prevAll().length;
								slides.each(function(f) {
									if (f > activatedSlideIndex)
										$(this).stop(true).animate({width : shrinkedSlideWidth - options.spacing, left: options.slideMaxWidth + (f - 1) * shrinkedSlideWidth + options.spacing}, options.slideDuration, options.slidesEasing);
									else if ($(this).prevAll().length == activatedSlideIndex) {										
										$(this).stop(true).animate({width : options.slideMaxWidth, left: f * shrinkedSlideWidth}, options.slideDuration, options.slidesEasing, function() {
											//Callback
											if ($.isFunction(options.onSlideOpened)) {												
												options.onSlideOpened.call($(this));
											}
											if (options.autoplay) {		//Start autoPlay for current slide as soon as the slide is open
												autoPlay.start();
												if (hovered) autoPlay.pause();	//Pause autoplay if the mouse is over accordion
												slideOpening = false;
											}
										});
									}
									else
										$(this).stop(true).animate({width : shrinkedSlideWidth - options.spacing, left: f * shrinkedSlideWidth}, options.slideDuration, options.slidesEasing);
								});	
								
								if (options.sticky) {
									//Callback
									if ($.isFunction(options.onSlideStartClosing) && activatedSlide != null) {										
										options.onSlideStartClosing.call(activatedSlide);
									}
								}
								//Callback
								if ($.isFunction(options.onSlideStartOpening)) {
									options.onSlideStartOpening.call($(this));
								}
								if (activatedSlide != null) activatedSlide.removeAttr('id');
								$(this).attr('id', options.activatedSlideID);
								activatedSlide = $(this);
							}
						}).bind('closeSlide', function() {
							if (!options.sticky) {
								slides.each(function(f) {
									$(this).stop(true).animate({width : inactiveSlideWidth - options.spacing, left : f * inactiveSlideWidth}, options.slideDuration, options.slidesEasing);
								});
								if ($.isFunction(options.onSlideStartClosing)) {
									options.onSlideStartClosing.call($(this));
								}
								activatedSlide.removeAttr('id');
								activatedSlide = null;
							}
						});
					});
					//Open user-defined slide as soon as the accordion is created (if the slide is specified)
					if (options.activeSlide !== null && options.activeSlide !== 'undefined' && options.activeSlide > 0 && options.activeSlide <= slides.length) {
						slides.eq(options.activeSlide - 1).triggerHandler('openSlide');
					}
				},
				preload : function() {
					accordion.css({'visibility' : 'hidden', opacity : 0}).wrap('<div class="accWrapper" />').parent().css({'background' : 'transparent url(' + options.preloaderImg + ') no-repeat center', 
																																						   width : accordion.outerWidth()});	
					//Preloader of each slide's image
					$('li > a > img', accordion).imgPreloader({
						onImagesLoaded : function(e) {
							accordion.methods.init();
							accordion.css('visibility', 'visible').animate({ opacity : 1 }, options.preloadFadeInDuration, function() {
								accordion.unwrap();
							});						
						}
					});
				},
				getNextSlide : function() {
					if (activatedSlide == null || activatedSlide.next().length == 0) {
						return $('li', accordion).first();
					} else {
						return activatedSlide.next();
					}
				}
			}
			
			//Visual representation of autoplay displayed on every slide
			var countdown = {			
				start : function() {
					$('.countdown', activatedSlide).css({opacity : 1, width : 0}).stop(true).animate({width : options.countdownMaxWidth == 650 ? options.slideMaxWidth : options.countdownMaxWidth}, options.autoplayDelay, 'linear');
				},			
				stop : function() {
					$('.countdown', activatedSlide).stop(true).animate({opacity : 0}, 200);
				},			
				pause : function() {
					$('.countdown', activatedSlide).stop(true);	
				},			
				resume : function(durationLeft) {
					$('.countdown', activatedSlide).stop(true).animate({width : options.countdownMaxWidth == 650 ? options.slideMaxWidth : options.countdownMaxWidth}, durationLeft, 'linear');
				}
			}		
			
			var autoPlay = {
				startTime : null,
				timeLeft : null,
				timePassed : null,
				pomTimer : null,
				mainTimer : null,
				
				init : function() {
					slides.append('<div class="countdown"></div>');
					options.sticky = true;
					//If user didnt specify any slide open by default, its automatically set to 1
					if (options.activeSlide === null || options.activeSlide === 'undefined' || options.activeSlide <= 0 || options.activeSlide > slides.length) {
						options.activeSlide = 1;
					}
					//Stop autoplay when the mouse is over any slide
					if (options.pauseOnHover) {
						accordion.mouseenter(function() {
							autoPlay.pause();
							hovered = true;
						}).mouseleave(function() {
							if (!slideOpening) autoPlay.resume();
							hovered = false;
						});
					}
				},			
				start : function() {
					this.timePassed = 0;				
					this.startTime = new Date().getTime();
					countdown.start();
					this.mainTimer = window.setInterval(function() { accordion.methods.getNextSlide().triggerHandler('openSlide'); }, options.autoplayDelay);				
				},
				stop : function() {
					countdown.stop();
					clearInterval(this.mainTimer);				
				},
				pause : function() {				
					this.stop();
					countdown.pause();
					clearTimeout(this.pomTimer);
					this.timePassed += new Date().getTime() - this.startTime;
					this.timeLeft = options.autoplayDelay - this.timePassed;
				},
				resume : function() {
					countdown.resume(autoPlay.timeLeft);
					this.startTime = new Date().getTime();
					this.pomTimer = window.setTimeout(function() { accordion.methods.getNextSlide().triggerHandler('openSlide'); }, this.timeLeft);				
				}
			}			
			//Initialize the accordion
			if (options.usePreloader) accordion.methods.preload();
			else accordion.methods.init();
		});
	};
})(jQuery);

(function($){
	$.fn.imgPreloader = function(options) {
		var defaults = {
			preloaderImg : 'images/ajax-loader.gif',
			imgFadeInDuration : 500,
			onImagesLoaded : function() {}
		}
		var options = $.extend(defaults, options);		
		var imagesToLoad = this.length;
		if (imagesToLoad == 0) options.onImagesLoaded.call();
		return this.each(function(e) {								  
   			var currentImg = $(this);
			currentImg.css('visibility', 'hidden'); //Hide image			
			//Show image when loading is done
			currentImg.one('load', function(){
				$(this).css('visibility', 'visible');
				if (--imagesToLoad == 0) options.onImagesLoaded.call();
			}).each(function() {
				if(this.complete) {
					$(this).trigger("load");
				}
			});
 		});
	};
})(jQuery);

jQuery.fn.animateAuto = function(prop, speed, easing, callback){
	var elem, height, width;
	return this.each(function(i, el){
		if (prop === "height") {
			el = jQuery(el), elem = el.clone().css({"height" : "auto"}).insertAfter($(this));
		} else {
			el = jQuery(el), elem = el.clone().css({"width" : "auto"}).insertAfter($(this));	
		}
		height = elem.css("height"),
		width = elem.css("width"),
		elem.remove();			
		
		if(prop === "height")
			el.animate({"height":height}, speed, easing, function() { 
				el.css('height', 'auto'); 
				callback; 
			});			
		else if(prop === "width")
			el.animate({"width":width}, speed, easing, function() {
				el.css('width', 'auto'); 
				callback; 													
			});
	});  
}
