(function($) {
	var mgSlider = function (object, options) {
		var defaults = {
			elements: {
				container: 'container',
				prev: 'prev',
				next: 'next',
				loader: 'loader',
				status: 'status',
				status_item: 'item',
				status_timer: 'timer'
			},
			width: 940,
			autochange: true,
			time: 6000,
			time_after_go: 10000,
			transition: 1000,
			easing: 'easeInOutCubic',
			statusbar: true,
			statusbar_center: false,
			statusbar_timer: true,
			buttons: true,
			slides: 0,
			current: 0,
			effect: 'slide' /* slide | fade */
		};
		var options = $.extend(defaults, options);
		var root = $(object);
		var timer = null;
	
		/* Internal methods */
		function init () {
			var slides = root.html();
			root.html('');
			root.addClass(options.effect);
			
			/* Loader */
			$('<div>').addClass(options.elements.loader).appendTo(root);
			
			/* Buttons */
			if (options.buttons) {
				$('<div>').addClass(options.elements.prev).click(function(){ goPrev(); }).appendTo(root);
				$('<div>').addClass(options.elements.next).click(function(){ goNext(); }).appendTo(root);
			}
			
			/* Container */
			$('<div>').addClass(options.elements.container).html(slides).appendTo(root);

			loadSlides();
			
			/* Status */
			if (options.statusbar) {
				var status = $('<div>').addClass(options.elements.status).appendTo(root);
				for (var x = 0; x < options.slides; x++) {
					var it = $('<div>').addClass(options.elements.status_item).appendTo(status).data('key', x);
					it.click(function(){
						go($(this).data('key'));
					})
					if (x == options.current)
						it.addClass('current');

					if (options.statusbar_center)
						status.css({marginLeft: options.width/2-(it.width()*options.slides)/2});
				}
			}
			
			if (options.statusbar_timer)
				$('<div>').addClass(options.elements.status_timer).appendTo(root);
				
			if (options.slides == 1) {
				$(root).find('.'+options.elements.prev+', .'+options.elements.next+', .'+options.elements.status).hide();
			};

			go(options.current, true);
		}
		
		function loadSlides () {
			var images = root.find('img');
			options.slides = images.length;

			if (images.length > 0) {
				$('<img>').attr('src', $(images[0]).attr('src')).load(function() {
					$(this).remove();

					root.find('.'+options.elements.loader).fadeOut(600, options.easing);
					root.find('.'+options.elements.container).css('width', options.width*options.slides);
				});
			} else {
				root.find('.'+options.elements.loader).fadeOut(600, options.easing);
				root.find('.'+options.elements.container).css('width', options.width*options.slides);
			}
		}
		
		function goNext (auto) {
			var key = options.current+1 < options.slides ? options.current+1 : 0;
			go(key, auto);
		}
		
		function goPrev () {
			var key = options.current-1 >= 0 ? options.current-1 : options.slides-1;
			go(key);
		}
		
		function go (key, auto) {
			var prev = options.current;
			options.current = key;
			root.find('.'+options.elements.container).clearQueue();

			if ($(root.find('.'+options.elements.container+' .slide')[prev]).find('.embed').length > 0) {
				var element = $(root.find('.'+options.elements.container+' .slide')[prev])
				var temp = element.find('.embed').clone();
				setTimeout(function(){
					element.find('.embed').remove();
					temp.appendTo(element);
				}, options.transition);
			}

			if (options.statusbar) {
				root.find('.'+options.elements.status+' .'+options.elements.status_item+'.current').removeClass('current');
				$(root.find('.'+options.elements.status+' .'+options.elements.status_item)[options.current]).addClass('current');
			}
			
			if (options.effect == 'slide') {
				root.find('.'+options.elements.container).animate({
					marginLeft: -(key*options.width)
				}, options.transition, options.easing);
			} else {
				root.find('.'+options.elements.container+' .current').fadeOut(options.transition, options.easing).removeClass('current');
				$(root.find('.'+options.elements.container+' div')[options.current]).addClass('current').fadeIn(options.transition, options.easing);
			}

			if (options.autochange) {
				var time = auto ? options.time : options.time_after_go;
				if (timer) clearTimeout(timer);
				timer = setTimeout(function(){goNext(true);}, time);
			}
			
			if (options.statusbar_timer)
				root.find('.'+options.elements.status_timer).clearQueue()
				.css({ width: 0 })
				.animate({ width: options.width }, time, options.easing);
		}
		
		/* Api methods */
		this.api = {
			go: function (key){ go(key) },
			goNext: function () { goNext(); },
			goPrev: function () { goPrev(); }
		};
		
		init();
	}
	
	$.fn.mgSlider = function(options) {
		if ($(this).data('mgSlider')) {
			var obj = $(this).data('mgSlider');
		} else {
			var options = typeof(options) === 'object' ? options : {};
			var obj = new mgSlider(this, options);
			$(this).data('mgSlider', obj);
		}
		return obj.api;
	}
})(jQuery);
