/*  jQuery.ajaxLoadImg Version 0.2   08/25/2008
  * REQUIRES: jquery.js (1.2.6 or later)
  * Copyright (c) 2008 Yong Li yuhj(at)hotmail(dot)com
  * Dual licensed under MIT and GPL.	

  SYNTAX: $(Selector).ajaxLoadImg(imgURL,options);
	or   :  $.(imgObj,imgURL,options);
   
   REQUIRED:
	imageSelector: Must be an image DOM element or javascript image object.  Other element will be ignored.
			     However, if an array of img is selected, the imgURL(defined below) should also be chosen from an array accordingly.
	 imgURL :  URL to the image being loaded.
	 
   OPTIONS:
	loadingOnly(Default:false)	:   If it is set to true, the function will only load the image, do nothing else (show,resize, align,fadein,show).
	placeHolderURL(Default: null)	:  URL to the placeholder image, normally an ajax animation gif, which will be shown during the loading process.
	newWidth(Default:0)		:  The intened image width, must be paired with newHeight. If defined, they are used to resize the image after it completes loading.
	newHeight(Default:0)		:  See newWidth above.
	fadeInSpeed(Default:0)		:  Paremeter for using jquery's fadeIn() function to show the image after loading.
	containerWidth(Default:0)	:  The width of the container which holds the image object. When this option is set the image will be horizontally aligned.
	containerHeight(Default:0)	:  Similar to containerWidth, this parameter is set for vertical alignment.
	allowEnlarge(default:false)	:   If the image is smaller than the new size (both Width and Height), whether to allow enlargement of the image.
	onComplete(default:null)		:   Callback function when loading completes.
	onFail(default:null)		:   Callback function when loading fails or aborted;

     RETURN:
	 The image object itself, hence chainable.
	 
     PROPERTIES:
	 imgObj.loadingStatus: 
					'loading'   	The image is loading and does not yet finished.
					'failed'     		The image has failed loading.
					'completed'   	The image has completed loading.
	 
*/
(function($) {		
	var defaultOptions = {			 // Pre-define some default option values.
		loadingOnly		: false,
		placeHolderURL	: null,
		newWidth		: 0,
		newHeight		: 0,
		fadeInSpeed		: 0,
		containerWidth	: 0,
		containerHeight	: 0,
		allowEnlarge	: false,
		onComplete		: null,
		onFail			: null
	};
	
	$.fn.extend(
		{
			ajaxLoadImg:function(imgURL,options)
				{return this.each(function(){return $.ajaxLoadImg(this,imgURL,options); });				   },

			resizeImg:function(newWidth,newHeight,allowEnlarge)
				{return this.each(function(){return $.resizeImg(this,newWidth,newHeight,allowEnlarge); }); },

			alignImg:function(containerWidth,containerHeight)
				{return this.each(function(){return $.alignImg(this,containerWidth,containerHeight); });   }
		}
	);
	
	$.ajaxLoadImg = function(loadingImg,imgURL,opt){
		loadingImg = $(loadingImg);
		
		if(typeof(imgURL) != 'string' || imgURL == opt.placeHolderURL) return loadingImg;   // If it is not an image or imgURL is not set correctly, do nothing.
		opt = $.extend( {}, defaultOptions, opt);				// Use function opt to override default opt.
		
		loadingImg.load(loadingImgHandler).attr('loadingStatus','loading');			// Set the image status to be loading (in progress).			
		var newImg = $('<img/>').load(newImgHandler).error(newImgHandler).bind('abort',newImgHandler);								// Create an new Image object.
	
		!opt.loadingOnly && opt.placeHolderURL    ?
			newImg.attr('src',opt.placeHolderURL) : newImg.attr('src',imgURL);
				
		return loadingImg;
	
		function newImgHandler(e){
			if(newImg.attr('src') == opt.placeHolderURL)			// Finish loading the placeholder image
			{
				loadingImg.attr('src',opt.placeHolderURL);
				newImg.attr('src',imgURL);
			}else{													// Finish loading the target image	
				if(e.type == 'abort' || e.type == 'error')			//Loading the  target image but failed
				{	
					loadingImg.attr('loadingStatus','failed');
					
					if(opt.onFail)
						opt.onFail(loadingImg[0]);
				}
				else if(opt.loadingOnly)
					loadingImg.attr('src',newImg.attr('src'));
				else
					loadingImg.hide().attr('src',newImg.attr('src'));
				
				if(newImg.unbind){
					newImg.unbind('load').unbind('error').unbind('abort');	// Some cleanup work
					newImg = null;
				}
			}				
		}
	
		function loadingImgHandler(e){
			if(loadingImg.attr('src') == opt.placeHolderURL)
				loadingImg.hide().alignImg(opt.containerWidth,opt.containerHeight).show();
				
			else if(loadingImg.attr('src')  == imgURL)
			{
				if(!opt.loadingOnly)
				{	
					loadingImg.resizeImg(opt.newWidth,opt.newHeight,opt.allowEnlarge)
							.alignImg(opt.containerWidth,opt.containerHeight);

					opt.fadeInSpeed ? loadingImg.fadeIn(opt.fadeInSpeed) : loadingImg.show();
				}
				
				loadingImg.attr('loadingStatus','completed');	
					
				if(loadingImg.unbind)
					loadingImg.unbind('load').unbind('error').unbind('abort');	// Some cleanup work
					
				if(opt.onComplete)
					opt.onComplete(loadingImg[0]);	
				
			}	
		}
	};
	
	$.resizeImg=function(objImg,newWidth,newHeight,allowEnlarge){
		objImg = $(objImg);
		var imgWidth = objImg.width();
		var imgHeight = objImg.height();
		
		if(!imgWidth || !imgHeight || !newWidth || !newHeight) 	
			return objImg;
		
		var hRatio,wRatio,Ratio = 1;
		
		wRatio = newWidth / imgWidth;
		hRatio = newHeight / imgHeight;			
		Ratio = (wRatio<=hRatio?wRatio:hRatio);
		
		if (Ratio > 1 && !allowEnlarge)
	        Ratio = 1;
			
		return objImg.width(imgWidth * Ratio).height(imgHeight * Ratio); 
	};
	
	$.alignImg=function(objImg,containerWidth,containerHeight){
		objImg = $(objImg);
		
		if(!objImg.height() || !objImg.width())
			return objImg;			
		
		if(objImg.height() < containerHeight - 1)
			objImg.css('marginTop',(containerHeight - objImg.height())/2 + 'px');

		if(objImg.width()  < containerWidth  - 1)
			objImg.css('margin-left',(containerWidth - objImg.width())/2 + 'px');
			
		return objImg;			
	};
	
})(jQuery);	