(function($) {

	$.fn.superslider = function(options) {
		
		var defaults = {
			autoPlay: false,
			effect: "fade",
			easing: "swing",
			animationTime: 500,
			delay: 5000,
			forwardText: "Next",
			backText: "Previous",
			startText: "Start",
			stopText: "Stop",
			pauseText: "Pause",
			pauseOnHover: true,
			resizeContents: false
		};
		var options = $.extend(defaults, options);
		
		return this.each(function() {
			
			var elem = $(this).hide();
			// append new elements to html
			elem.before("<div class='superslider'><div class='supersliderCenter'><div class='supersliderContent'></div></div></div>");
			var ss = $(".superslider:last .supersliderContent").css("height", "100%");
			ss.parent().css("height", "100%");
			ss.html(
				"<div class='contentarea'><div class='panelsWrapper' /></div>" +
				"<div class='start-stop' />" +
				"<div class='arrow prev' />" +
				"<div class='pager' />" +
				"<div class='arrow next' />"
			);
			var content = ss.children(".contentarea").scrollLeft(0); 
			var panelsWrapper = content.children(".panelsWrapper");
			var startstop = ss.children(".start-stop");
			var prev = ss.children(".prev");
			var next = ss.children(".next");
			var pager = ss.children(".pager");
			var currentSlide = 0; // index of current slide
			var nextSlide = 0; // index of upcoming slide
			var slides = new Array(); // array for real slides, not for clones
			var i = 0;
			var playing = options.autoPlay;
			var timer;
			
			// method for resizing the contentarea and wrapper
			ss.resize = function() {
				content.css({ width: ss.parent().parent().width(), height: ss.parent().parent().height() });
				if(options.resizeContents) {
					if(slides[nextSlide]) {
						var ind = nextSlide
					}
					else {
						if(nextSlide < 0)
							var ind = slides.length - 1;
						else if(nextSlide >= slides.length)
							var ind = 0;
					}
					
					if(ind == currentSlide) {
						content.css({ width: slides[ind].width(), height: slides[ind].height() });
						ss.css({ width: slides[ind].width(), height: slides[ind].height() });
						ss.parent().css({ width: slides[ind].width(), height: slides[ind].height() });
						ss.parent().parent().css({ width: slides[ind].width(), height: slides[ind].height() });
					}
					else {
						ss.parent().parent().animate({ width: slides[ind].width(), height: slides[ind].height() }, { queue: false, duration: options.animationTime });
					}
				}
			}
			// method for resizing panels
			ss.resizePanel = function() {
				if(options.resizeContents) {
					if(slides[nextSlide]) {
						var ind = nextSlide
					}
					else {
						if(nextSlide < 0)
							var ind = slides.length - 1;
						else if(nextSlide >= slides.length)
							var ind = 0;
					}
					
					content.stop().animate({ 
						"width": slides[ind].width(),
						"height": slides[ind].height() 
					}, options.animationTime);
				}
			}
			
			// set panels to stack (fade) or row ( slide)
			ss.setPanels = function(type) {
				var w = 0;
				for(i = 0; i < slides.length; i++) {
					var slideClass = slides[i].attr("class");
					panelsWrapper.append("<div class='panel panel_"+(i+1)+"' />");
					panelsWrapper.children(".panel:last").html(slides[i].html());
					slides[i] = panelsWrapper.children(".panel:last");
					if(slideClass) panelsWrapper.children(".panel:last").addClass(slideClass);
					slides[i].find(".slidePic").css("height", "auto");
					slides[i].children("div").css("height", "inherit");
					slides[i].find(".slidePic").css("height", "inherit");
					
					slides[i].css({
						width: ss.width(), 
						height: ss.height()
					});
					
					/*
					if(type == "fade") {
						slides[i].css({
							width: slides[i].find("img").width(), 
							height: slides[i].css("height") ? slides[i].height() : slides[i].css("height")
						});
					}
					else if(type == "slide") {
						slides[i].css({ 
							height: slides[i].css("height") ? slides[i].height() : slides[i].css("height")
						});
					}
					*/
					
					w += slides[i].width();
				}				
				
				if(type == "fade") {
					panelsWrapper.css("width", "100%");
					for(i = 0; i < slides.length; i++) {
						slides[i].css({
							position: "absolute",
							top: 0,
							left: 0,
							opacity: 0,
							zIndex: 11,
							display: "block"
						});
					}
					slides[currentSlide].addClass("activePanel").css({ "opacity": 1, "z-index": 15 });
				}
				else if(type == "slide") {
					panelsWrapper.width(w + slides[0].width() + slides[slides.length-1].width());
					for(i = 0; i < slides.length; i++) {
						slides[i].css({
							opacity: 1,
							zIndex: 15,
							display: "block",
							"float": "left",
							position: "relative"
						});
					}
					
					// Clone first and last panels 
					slides[0].before(slides[slides.length-1].clone().addClass("clone"));
					slides[slides.length-1].after(slides[0].clone().addClass("clone"));
					
					slides[currentSlide].addClass("activePanel");
					content.scrollLeft(panelsWrapper.children(".clone:first").width());
					content.animate({
						scrollLeft: panelsWrapper.children(".clone:first").width()
					}, 1); // fix for ie8
				}
			} // /setPanels
			
			ss.changeSlide = function(next) {
				var a = panelsWrapper.children(".activePanel");
				
				if(a.is(":animated") || content.is(":animated"))
					return false;
				
				if(next == currentSlide)
					return false;
				
				nextSlide = next
				var n = null;
				n = slides[nextSlide];
				
				if(options.effect == "fade") {
					if(!n) {
						if(nextSlide < 0)
							nextSlide = slides.length - 1;
						else if(nextSlide >= slides.length)
							nextSlide = 0;
							
						n = slides[nextSlide];
					}
					
					
					if(a.find(".slidePic").children("img").attr("src") != "") {
						n.show().css("opacity", 1);
					}
					else {
						n.show().animate({
							"opacity": 1
						}, {
							queue: false,
							duration: options.animationTime,
							easing: options.easing
						});
					}
					
					ss.resize(true);
					ss.resizePanel();
					a.stop().animate({
						"opacity": 0
					}, {
						queue: false, 
						duration: options.animationTime, 
						easing: options.easing, 
						complete: function() {
							pager.children(".activePage").removeClass("activePage");
							pager.children("span:nth-child("+(nextSlide+1)+")").addClass("activePage");
							
							a.removeClass("activePanel").css("zIndex", 11);
							n.addClass("activePanel").css("zIndex", 15);
						}
					});
				}
				else if(options.effect == "slide") {
					if(n == null) {
						if(nextSlide > currentSlide && nextSlide == slides.length)
							n = panelsWrapper.children(".clone:last");
						else if(nextSlide < currentSlide && nextSlide < 0)
							n = panelsWrapper.children(".clone:first");
					}
					ss.resize(true);
					ss.resizePanel();
					content.animate({
						scrollLeft: n.position().left
					}, {
						queue: false, 
						duration: options.animationTime, 
						easing: options.easing, 
						complete: function() {
							if(nextSlide == slides.length) {
								currentSlide = 0;
								n = slides[currentSlide];
								content.scrollLeft(n.position().left);
							}
							else if(nextSlide < 0) {
								currentSlide = slides.length - 1;
								n = slides[currentSlide];
								content.scrollLeft(n.position().left);
							}
							
							pager.children(".activePage").removeClass("activePage");
							pager.children("span:nth-child("+(currentSlide+1)+")").addClass("activePage");
							
							a.removeClass("activePanel");
							n.addClass("activePanel");
						}
					});
				}
				
				
				currentSlide = nextSlide;
				if(currentSlide < 0)
						currentSlide = slides.length - 1;
				else if(currentSlide >= slides.length)
					currentSlide = 0;
					
				ss.setControls();
				
				
				if(playing) {
					timer = setTimeout(function() {
						ss.changeSlide(currentSlide + 1);
					}, options.delay + options.animationTime);
				}
			}
			
			ss.setControls = function() {
				for(i = 1; i <= slides.length; i++) {
					prev.removeClass("panel_"+i);
					next.removeClass("panel_"+i);
					pager.removeClass("panel_"+i);
					startstop.removeClass("panel_"+i);
				}
				
				prev.addClass("panel_"+(currentSlide+1));
				next.addClass("panel_"+(currentSlide+1));
				pager.addClass("panel_"+(currentSlide+1));
				startstop.addClass("panel_"+(currentSlide+1));
			}
			
			
			ss.startTimer = function() {
				playing = true;
				startstop.children("span").text(options.stopText);
				timer = setTimeout(function() {
					ss.changeSlide(currentSlide + 1);
				}, options.delay + options.animationTime);
				startstop.removeClass("stopped");
				startstop.addClass("playing");
			}
			ss.stopTimer = function() {
				playing = false;
				clearTimeout(timer);
				startstop.children("span").text(options.startText);
				startstop.removeClass("playing");
				startstop.addClass("stopped");
			}
			

			// slides to array
			i = 0;
			elem.children("li").each(function() {
				slides[i] = $(this);
				i++;
			});
			elem.remove();
			
			// Texts for controls
			startstop.append("<span>"+(options.autoPlay ? options.stopText : options.startText)+"</span>");
			prev.append("<span>"+options.backText+"</span>");
			next.append("<span>"+options.forwardText+"</span>");
			for(i = 1; i <= slides.length; i++)
				pager.append("<span class='page_"+i+"'>"+i+"</span>");
			pager.children("span:first").addClass("activePage first");
			pager.children("span:last").addClass("last");
			
			
			ss.setPanels(options.effect);
			ss.resize();
			ss.setControls();
			
			
			// bindings
			next.bind("click", function() {
				if(playing) {
					ss.stopTimer();
				}
					
				ss.changeSlide(currentSlide + 1);
			});
			prev.bind("click", function() {
				if(playing) {
					ss.stopTimer();
				}
					
				ss.changeSlide(currentSlide - 1);
			});
			pager.children("span").bind("click", function() {
				if(playing) {
					ss.stopTimer();
				}
					
				ss.changeSlide($(this).prevAll("span").length);
			});
			startstop.bind("click", function() {
				if(playing) {
					ss.stopTimer();
				}
				else {
					ss.startTimer();
				}
			});
			panelsWrapper.children(".panel").bind("mouseover", function() {
				if(options.pauseOnHover) {
					if(playing) {
						clearTimeout(timer);
						startstop.children("span").text(options.pauseText);
						startstop.removeClass("playing");
						startstop.addClass("paused");
					}
				}
			});
			panelsWrapper.children(".panel").bind("mouseout", function() {
				if(options.pauseOnHover) {
					if(startstop.hasClass("paused")) {
						startstop.children("span").text(options.stopText);
						timer = setTimeout(function() {
							ss.changeSlide(currentSlide + 1);
						}, options.delay + options.animationTime);
						startstop.removeClass("paused");
						startstop.addClass("playing");
					}
				}
			});
			
			startstop.addClass("stopped");
			if(options.autoPlay) {
				timer = setTimeout(function() {
					ss.changeSlide(currentSlide + 1);
				}, options.delay + options.animationTime);
				startstop.removeClass("stopped");
				startstop.addClass("playing");
			}
		});
	}
	
})(jQuery);
