(function($){
	$.fn.tawPreloadImages = function(options, func) {
				
		var defaults = {
			image_path: 'ajax-loader.png',
			css_background_class: 'tawImagePreloaderContainer',
			css_background_class_on_error: 'tawImagePreloaderContainerOnError',
			width: "100%",
			height: "100%",
			image_fade_in_time: 200,
			jqSize: false,
			substractCssSize: false,
			substractPadding: false,
			substractBorder: false
		};
		
		
		
		var options = $.extend(defaults, options);		
		
		return this.each(function() {
								  
			var imgs = $('img', this);
			
			if(imgs.length === 0){
				return false;
			} else {
				
     			var loadedImages = [];
				var i = 0;
				
				imgs.each(function(i, val){	
							   
					if(options.jqSize == false) {
						if($(this).width() > 0){
							var rslt_width = $(this).width() + "px";
						} else {
							var rslt_width = options.width;
						}
						if($(this).height() > 0){
							var rslt_height = $(this).height() + "px";	
						} else {
							var rslt_height = options.height;
						}
					} else {
						var rslt_width = options.width;
						var rslt_height = options.height;
					}
					$(this).css({ "visibility": "hidden" });
					$(this).wrap('<div class="' + options.css_background_class + '"></div>');
					
					cssWidth = $(this).parent().css("width");
					cssHeight = $(this).parent().css("height");
					if(cssWidth != "auto" && cssWidth != "0px") rslt_width = cssWidth;
					if(cssHeight != "auto" && cssHeight != "0px") rslt_height = cssHeight;
					
					
					$(this).parent().width(rslt_width).height(rslt_height);
					
					var or_width = $(this).width();
					var or_height = $(this).height();
					
					$(this).bind('load', function () {
												   
						$(this).css({ "visibility": "visible", "display": "none" });
						var randomID = "tawImagePreloaderRandomId" + (Math.floor(Math.random() * 100001));
						$(this).addClass(randomID);
						$(this).parent().replaceWith($(this).parent().html());
						
						if(options.jqSize === true) $("." + randomID).width(options.width).height(options.height);
						
						$("." + randomID).fadeIn(options.image_fade_in_time, function(){
							$(this).removeClass(randomID);
						});
						
						if($.inArray(i, loadedImages) == -1){
							loadedImages.push(i);
							if(loadedImages.length == imgs.length){
								if(func) setTimeout(function(){ func() }, options.image_fade_in_time + 50);								
							}
						}
						
						
					}).error(function() {					
						
						if($(this).width() > 0 && options.jqSize == false){
							if(or_width > 0){
								var rslt_width = or_width + "px";
							} else {
								var rslt_width = $(this).width() + "px";
							}
						} else {
							var rslt_width = options.width;
						}
						if($(this).height() > 0 && options.jqSize == false){
							if(or_width > 0){
								var rslt_height = or_height + "px";
							} else {
								var rslt_height = $(this).height() + "px";
							}
						} else {
							var rslt_height = options.height;
						}
						
						var randomID = "tawImagePreloaderRandomId" + (Math.floor(Math.random() * 100001));
						$(this).parent().replaceWith('<div id="' + randomID + '" class="' + options.css_background_class_on_error + '">' + $(this).attr("alt") + '<div>');
						$("#" + randomID).hide();
											
						cssWidth = $("#" + randomID).css("width");
						cssHeight = $("#" + randomID).css("height");
						if(cssWidth != "auto" && cssWidth != "0px") rslt_width = cssWidth;
						if(cssHeight != "auto" && cssHeight != "0px") rslt_height = cssHeight;
						
						if(options.substractCssSize){
							options.substractPadding = true;
							options.substractBorder = true;
						}						
						if(options.substractPadding === true){
							var paddingTop = parseInt($("#" + randomID).css("paddingTop"));
							var paddingRight = parseInt($("#" + randomID).css("paddingRight"));
							var paddingBottom = parseInt($("#" + randomID).css("paddingBottom"));
							var paddingLeft = parseInt($("#" + randomID).css("paddingLeft"));
							
							rslt_width = (parseInt(rslt_width) - paddingLeft - paddingRight) + "px";
							rslt_height = (parseInt(rslt_height) - paddingTop - paddingBottom) + "px";
						}
						if(options.substractBorder === true){
							var borderTopWidth = parseInt($("#" + randomID).css("borderTopWidth"));
							var borderRightWidth = parseInt($("#" + randomID).css("borderRightWidth"));
							var borderBottomWidth = parseInt($("#" + randomID).css("borderBottomWidth"));
							var borderLeftWidth = parseInt($("#" + randomID).css("borderLeftWidth"));
							
							rslt_width = (parseInt(rslt_width) - borderLeftWidth - borderRightWidth) + "px";
							rslt_height = (parseInt(rslt_height) - borderTopWidth - borderBottomWidth) + "px";
						}
						
						$("#" + randomID).width(rslt_width).height(rslt_height);	
						
						$("#" + randomID).fadeIn(options.image_fade_in_time);
						$("#" + randomID).removeAttr("id");
						
						
						if($.inArray(i, loadedImages) == -1){
							loadedImages.push(i);
							if (navigator.appName == "Netscape") imgslength = imgs.length - 1;
							else imgslength = imgs.length;
							if(loadedImages.length == imgslength){
								if(func) setTimeout(function(){ func(); }, options.image_fade_in_time + 50);
							}
						}
						
					});
						
				}).each(function(){
					  if(this.complete || this.complete === undefined){ this.src = this.src; } //needed for potential cached images
					  
					  i++
					  if(i == imgs.length){
					 	 if(func) setTimeout(function(){ func() }, options.image_fade_in_time + 50);
						 i = 0;
					  }
					  /*
					  if($.inArray(i, loadedImages) == -1){
						  loadedImages.push(i);
						  if(loadedImages.length == imgs.length){
						     if(func) setTimeout(function(){ func() }, options.image_fade_in_time + 50);								
						  }
					  }
						*/
					  $(this).css("visibility", "visible");
					  $(this).parent().removeAttr("id").removeClass();
				});
			}
		});
	};
})(jQuery);

