var MiniGallery = function(element, options) {
	var conf = $.extend({}, $.fn.minigallery.defaults, options);
	var gallery = $(element);
	var galleryPreview = $("<div class='mg-preview'><div class='mg-preview-wrap'><ul></ul><div style='clear:both'></div></div></div>");
	var intervalID = false;
	var thumbHolderWidth = 0;
	var shown = 0;
	
	var initialize = function() {
		gallery.addClass("minigallery");
		$("img",gallery).css("visibility","hidden");

		if(!gallery.parent(0).is('body'))
			gallery.parent(0).css("position","relative");
			
		/** ADD BASIC ELEMENTS **/
		gallery.append("<div class='mg-back'></div>");
		gallery.append("<div class='mg-next'></div>");
		if(conf.raster){
			gallery.append("<div class='"+conf.rasterclass+"'></div>");
			$(".mg-raster",gallery).css("opacity",conf.rasteropacity);
		}
		gallery.append("<div class='mg-info-trigger'>i</div>");
		gallery.append("<div class='mg-info'></div>");
		
		if($("div.mg-intro",gallery).length > 0){
			var size = _getParentSize();
			$("div.mg-intro",gallery).css("height",size.height-85);
		}	
		
		
		
		$(".mg-back",gallery).click(function(){
			gallery.showPrevious();
		});
		$(".mg-next",gallery).click(function(){
			gallery.showNext();
		});
		$(".mg-info-trigger",gallery).click(function(){
			gallery.showInfo();
		});
			
		/** CREATE THUMBNAILS **/
		gallery.append(galleryPreview);
		$(".mg-preview").css({
			opacity	:	conf.previewopacity
		});
		thumbHolderWidth = 0;
		
		_preload(gallery.find("img."+conf.galleryclass+":first"));
		
		/** INIT KEY DOWN **/
		 
		$(document).keydown(function(event) {
            if(event.keyCode == 39 || event.keyCode == 38){
            	gallery.showNext();
            	return false;
            }
            if(event.keyCode == 37 || event.keyCode == 40){
            	gallery.showPrevious();
            	return false;
            }
         });

		
	};
	var _preload = function(img){
		var item = $("<li></li>");
		item.append(img);
		img.removeClass(conf.galleryclass);
		item.addClass(conf.loadingclass);
		$("ul",galleryPreview).append(item);
		thumbHolderWidth += item.outerWidth()+(item.css("marginLeft").replace("px","")*1)+(item.css("marginRight").replace("px","")*1);
		$("ul",galleryPreview).css("width",thumbHolderWidth);
		
		
		var image_t   = $(new Image());
		image_t.attr('src',img.attr('rel'));
		if(image_t.attr("width")){
			image_t.remove();
		}else{
			image_t.load(function(){
				image_t.remove();
			});
		}
		
		var image   = $(new Image());
		image.attr('src',img.attr('src'));
		if(image.attr("width")){
			_preloadFinish(item);
			image.remove();
		}else{
			image.load(function(){
				_preloadFinish(item);
				image.remove();
			});
		}
	};
	var _preloadFinish = function(item){
		/*item.css({	backgroundImage:'url('+$("img",item).attr("rel")+')',
			backgroundRepeat:'no-repeat',
			backgroundPosition:'50% 50%',
			opacity:conf.thumbhoveropacity});
		 */
		 item.css({
			opacity		:	conf.thumbhoveropacity,
			overflow	:	'hidden'	
		 });
		 var thumb = $("<img />").attr("src",$("img",item).attr("rel"));
		 item.prepend(thumb);
		
		 item.removeClass(conf.loadingclass);
		 item.hover(function(){
			if(!$(this).hasClass(conf.activeclass)){
				item.animate({"opacity":"1"},"fast");
			}
		},function(){
			if(!$(this).hasClass(conf.activeclass)){
				item.animate({"opacity":conf.thumbhoveropacity},"fast");
			}
		});
		item.click(function(){
			gallery.showImage(item);
			return false;
		});
		if(gallery.find("img."+conf.galleryclass+":first").length > 0){
			_preload(gallery.find("img."+conf.galleryclass+":first"));
		}else{
			if(thumbHolderWidth > galleryPreview.width()){
				_initscrolling();
			}
			if(conf.showfirst){
				$("ul li:first",galleryPreview).each(function(){
					gallery.showImage($(this));
				});
			}
		}
	};
	
	/** SCROLL WHEN OVERFLOW **/
	var _initscrolling = function(){
		previewscrolling = true;
		galleryPreview.append("<div class='mg-preview-scrollleft'></div>");
		galleryPreview.append("<div class='mg-preview-scrollright'></div>");
		$(".mg-preview-scrollleft",galleryPreview).mouseover(function(){
			_startscrolling("left");
		});
		$(".mg-preview-scrollleft",galleryPreview).mouseout(function(){
			_endscrolling("right");
		});
		$(".mg-preview-scrollright",galleryPreview).mouseover(function(){
			_startscrolling("right");
		});
		$(".mg-preview-scrollright",galleryPreview).mouseout(function(){
			_endscrolling("right");
		});
	};
	var _startscrolling = function(type){
		if(!intervalID){
			intervalID = setInterval(function(){_scroll(type)},conf.scrollinterval);
		}
	};
	var _endscrolling = function(type){
		if(intervalID){
			clearInterval(intervalID);
			intervalID = false;
		}
	};
	var _scroll = function(type){
		if(type == "left"){
			if(_getmargins().left < 0){
				$("ul:first",galleryPreview).css("marginLeft",(_getmargins().left + 5)+"px");
			}else{
				_endscrolling(type);
			}
		}else if(type == "right"){
			if(_getmargins().right > 0){
				$("ul:first",galleryPreview).css("marginLeft",(_getmargins().left - 5)+"px");
			}else{
				_endscrolling(type);
			}
		}
		if(_getmargins().left < 0)
			$(".mg-preview-scrollleft",galleryPreview).removeClass("mg-disabled");
		else
			$(".mg-preview-scrollleft",galleryPreview).addClass("mg-disabled");
		
		if(_getmargins().right > 0)
			$(".mg-preview-scrollright",galleryPreview).removeClass("mg-disabled");
		else
			$(".mg-preview-scrollright",galleryPreview).addClass("mg-disabled");
	};
	var _getmargins = function(){
		var leftm = ($("ul:first",galleryPreview).css("marginLeft").replace("px","")*1);
		var rightm = $("ul:first",galleryPreview).width() - ((galleryPreview.width() + Math.abs(leftm)));
		return {left: leftm, right:rightm};	
	};
	var _getParentSize = function(){
		var parentHeight = $(window).height();
		var parentWidth = $(window).width();
		if(!gallery.parent(0).is('body')){
			parentHeight = gallery.parent(0).height();
			parentWidth = gallery.parent(0).width();
		}
		return {width:parentWidth,height:parentHeight}
	};
	
	/** PUBLIC FUNCTIONS **/
	gallery.showNext = function(){
		$(".mg-active",galleryPreview).each(function(){
			$(".mg-active",galleryPreview).each(function(){
				if($(this).next().is("li")){
					gallery.showImage($(this).next());
				}
			});
		});
	};
	gallery.showPrevious = function(){
		$(".mg-active",galleryPreview).each(function(){
			if($(this).prev().is("li")){
				gallery.showImage($(this).prev());
			}
		});
	};
	gallery.showImage = function(item){
		$("."+conf.activeclass,galleryPreview).each(function(){
			$(this).css("opacity",conf.thumbhoveropacity);
			$(this).removeClass(conf.activeclass);
		});
		
		if($("div.mg-intro",gallery).length > 0){
			$("div.mg-intro",gallery).css("display","none");
		}	
			
		item.addClass(conf.activeclass);
		item.css("opacity","1");
		if(conf.fadeimage){
			$("img."+conf.imageclass,gallery).fadeOut(conf.fade,function(){
				$(this).remove();
			});
		}else{
			$("img."+conf.imageclass,gallery).remove();
		}
		var image = item.find("img:last").clone();
		
		/*$(window).unbind("resize");
		$(window).resize(function(){ 
			gallery.resize(image);
		});*/
		image.css("visibility","visible");
		gallery.append(image);
		image.addClass(conf.imageclass);
		gallery.resize(image);
		
		if(conf.fadeimage){
			$("img."+conf.imageclass,gallery).fadeIn(conf.fade);
		}else{
			image.css("display","block");
			
		}
		
		
		/**
		 * CHECK IF THUMB IS VISIBLE, IF NOT, ANIMATE THE MARGIN
		 */
		var elementLeft = item.position().left;
		var currentLeft = _getmargins().left;
		var elWidth = item.outerWidth()+(item.css("marginLeft").replace("px","")*1)+(item.css("marginRight").replace("px","")*1);
		if(elementLeft < 0){
			var nLeft = currentLeft + Math.abs(elementLeft);
			$("ul:first",galleryPreview).animate({"marginLeft": nLeft+"px"}, "slow");
		}else if((elementLeft+elWidth) > galleryPreview.width()){
			var nLeft = galleryPreview.width() - (elementLeft+elWidth+Math.abs(currentLeft));
			$("ul:first",galleryPreview).animate({"marginLeft": nLeft+"px"}, "slow");
		}
	};
	gallery.resize = function(image){
		if(image.attr("title")){
			$(".mg-info-trigger",gallery).css("display","block");
			$(".mg-info",gallery).html("<div class='mg-info-title'>"+image.attr("title")+"</div><div class='mg-info-caption'>"+image.attr("alt")+"</div>");
		}else{
			$(".mg-info-trigger",gallery).css("display","none");
			$(".mg-info",gallery).css("display","none");
		}
		
		var or_height = image.attr("or_height");
		var or_width = image.attr("or_width");
		if(!or_height)
			or_height = image.height();
		if(!or_width)
			or_width = image.width();
		
		
		var botoffset = $(".mg-preview").height()+($(".mg-preview").css("bottom").replace("px","")*1);
		
		var size = _getParentSize();
		var parentHeight = size.height-botoffset;
		var parentWidth = size.width;
		
		var w_ratio = parentWidth/or_height;
		var h_ratio = parentHeight/or_height;
		image.css({
			minWidth:0,
			minHeight:0
		});
		if(w_ratio < h_ratio){
			image.css({width:(or_width*w_ratio), height:"auto"});
		}else{
			image.css({height:(or_height*h_ratio),width:"auto"});
		}
	};
	gallery.showInfo = function(){
		if($(".mg-info",gallery).css("display") == "block"){
			$(".mg-info",gallery).css("display","none");
		}else{
			$(".mg-info",gallery).css("display","block");
		}
	};	
	
	initialize();
	return gallery;
};

(function($) {	
	$.fn.minigallery = function(options) {
		return this.each(function() {
			var element = $(this);

			// Return early if this element already has a plugin instance
			if (element.data('minigallery')) return;
			// pass options to plugin constructor
			var w = new MiniGallery(this, options);
			// Store plugin object in this element's data
			element.data('minigallery', w);
		});
	};
	
})(jQuery);

$.fn.minigallery.defaults = {
	galleryclass		:	"gallery",			//The class that images have
	loadingclass		:	"mg-loading",
	activeclass			:	"mg-active",
	imageclass			:	"mg-image",
	rasterclass			:	"mg-raster",
	fadeimage			:	false,				//ImageFading
	fade				:	200,				//Speed of fade
	raster				:	true,				//Show raster or not
	rasteropacity		:	0.2,				//Opacity of the raster
	thumbhoveropacity	:	0.4,				//Opacity of thumbnails			
	previewopacity		:	0.8,
	scrollinterval		:	20,
	showfirst			:	true
};
