(function($) {
	/*
	 * options:
	 * height: int
	 * width: int
	 * child_height: int
	 * child_width: int
	 * transition: [fade, scroll-x, scroll-y]
	 * thumbs: jQuery obj, elm, expression
	 * thumbs_position [bottom, top, side]
	 * thumbs_height: int
	 * thumbs_width: int
	 * thumb_height: int
	 * thumb_width: int
	 * thumb_crop: boolean
	 * btn_prev: jQuery obj, elm, expression
	 * btn_next: jQuery obj, elm, expression
	 * btn_first: jQuery obj, elm, expression
	 * btn_last: jQuery obj, elm, expression
	 * keyboard_shortcuts: boolean
	 * start: int
	 */

	$.fn.enslider = function(options) {
		$.each({
			transition: ["fade", "scroll-x", "scroll-y"],
			thumbs_position: ["bottom", "top", "side"]
		}, function(key, arr) {
			if (!options || !options[key] || $.inArray(options[key], arr) == -1)
				options[key] = arr[0];
		});

		options = $.extend({
			use_thumbs: true,
			keyboard_shortcuts: true,
			thumb_crop: true,
			start: 0
		}, options);
		
		return this.each(function() {
			var $this = $(this);
			var _childs = $this.children();
			var _index = options.start;

			$this.children().each(function() {
				_this = $(this);
				if (!options.width || _this.outerWidth(true) > options.width)
					options.width = _this.outerWidth(true);
				if (!options.height || _this.outerHeight(true) > options.height)
					options.height = _this.outerHeight(true);
				if (!options.child_width || _this.width() > options.child_width)
					options.child_width = _this.width();
				if (!options.child_height || _this.height() > options.child_height)
					options.child_height = _this.height();
			});

			/* Thumbnails */

			if (options.use_thumbs) {
				var _thumbs = options.thumbs ? $(options.thumbs) : $("<div></div>");

				if (options.thumbs_position == "side") {
					_thumbs.css({height: options.height});
					if (!options.thumb_height)
						options.thumb_height = Math.floor(options.height / _childs.length);
					if (!options.thumb_width)
						options.thumb_width = options.thumb_height;
				}
				else {
					_thumbs.css({width: options.width});
					if (!options.thumb_width)
						options.thumb_width = Math.floor(options.width / _childs.length);
					if (!options.thumb_height)
						options.thumb_height = options.thumb_width;
				}

				if (!options.thumbs) {
					_childs.each(function(i) {
						$("img:eq(0)", this).each(function() {
							$("<a href=\"#\" class=\"enSliderThumb\"></a>")
							.append(
								$(this).clone(true).load(function() {
									var _this = $(this);
									var _w = _this.width(), _h = _this.height(), _m = undefined;

									if (options.thumb_crop) {
										_m = [Math.floor((_w - options.thumb_width) / 2), Math.floor((_h - options.thumb_height) / 2)];
										_w = options.thumb_width, _h = options.thumb_height;
									}
									else {
										if (_w > options.thumb_width) {
											_h = Math.floor((options.thumb_width / _w) * _h);
											_w = options.thumb_width;
										}
										if (_h > options.thumb_height) {
											_w = Math.floor((options.thumb_height / _h) * _w);
											_h = options.thumb_height;
										}
									}
									
									_this.css({
										margin: '-10px',
										width: _w,
										height: _h
									});
								})
							).appendTo(_thumbs);
						});
					});
				}

				$.each(_thumbs.children(), function(i, thumb) {
					var _thumb = $(thumb).addClass("enSliderThumb").css({
						opacity: (i == _index ? 1 : 0.6)
					}).hover(function() {
						$(this).animate({opacity: 1});
					}, function() {
						if (!$(this).hasClass("active"))
							$(this).animate({opacity: 0.6}, "fast");
					}).click(function(e) {
						e.preventDefault();
						_go(i);
					});

					if (i == _index) {
						_thumb.addClass("active");
					}
				});

				if (options.thumbs_position == "bottom")
					$this.after(_thumbs);
				else
					$this.before(_thumbs);
			}

			/* Functions */

			var _go = function(to, thumb) {
				if (to < 0)
					to = _childs.length - 1;
				else if (to >= _childs.length)
					to = 0;

				if (options.transition == "scroll-x") {
					$this.animate({scrollLeft: to * options.width});
				}
				else if (options.transition == "scroll-y") {
					$this.animate({scrollTop: to * options.height});
				}
				else if (options.transition == "fade") {
					_childs.eq(_index).fadeOut("fast");
					_childs.eq(to).fadeIn("slow");
				}
				_index = to;
				
				if (options.use_thumbs) {
					_thumbs.children(".enSliderThumb.active").removeClass("active").animate({opacity: 0.6}, "fast");
					_thumbs.children(".enSliderThumb").eq(_index).addClass("active").animate({opacity: 1}, "slow");
				}
			}
			
			if (options.btn_prev)
				$(options.btn_prev).click(function(e) {
					e.preventDefault();
					_go(_index - 1);
				});
			if (options.btn_next)
				$(options.btn_next).click(function(e) {
					e.preventDefault();
					_go(_index + 1);
				});
			if (options.btn_first)
				$(options.btn_first).click(function(e) {
					e.preventDefault();
					_go(0);
				});
			if (options.btn_last)
				$(options.btn_last).click(function(e) {
					e.preventDefault();
					_go(_childs.length - 1);
				});
			if (options.keyboard_shortcuts)
				$(document).keydown(function(e) {
					if (e.which == 37) _go(_index - 1);
					if (e.which == 39) _go(_index + 1);
				});

			/* Draw */
			
			$this.css({
				width: options.width,
				height: options.height,
				overflow: "hidden",
				"overflow-x": options.transition == "scroll-x" ? "hidden" : "auto",
				"overflow-y": options.transition == "scroll-x" ? "auto" : "hidden"
			})
			
			if (options.transition == "scroll-x" || options.transition == "scroll-y")
			{
				var _wrapper = $("<div></div>").css({
					margin: 0,
					padding: 0,
					width: options.width,
					height: options.height
				});

				if (options.transition == "scroll-x")
					_wrapper.css({
						scrollLeft: _index * options.width,
						width: (options.width * _childs.length) + 100
					});
				else if (options.transition == "scroll-y")
					_wrapper.css({
						scrollTop: _index * options.height,
						height: options.height * _childs.length
					});

				_childs.wrapAll(_wrapper)
				_childs = $this.children().children();
			}

			_childs.css({
				margin: 0,
				width: options.child_width,
				height: options.child_height,
				position: options.transition == "fade" ? "absolute" : undefined,
				display: options.transition == "fade" ? "none" : undefined,
				"list-style": "none",
				"float": options.transition == "scroll-x" ? "left" : undefined
			});

			if (options.transition == "fade")
				_childs.eq(_index).css({display: "block"});
		});
	}
})(jQuery);