
jQuery.fn.startWaiting = function( className, message )
{
	var that = this;
	this.each( function( i, o )
	{
		var $o = jQuery( o ),
			$d = $o,
			waiting = $d.data( 'waiting' ),
			container = $o.parent(),
			width, height, top, left;
		
		if( !$o.parent().length )
		{
			$o = container = jQuery( o = document.body );			
		}

		
		if( !waiting )
			waiting = {};
		
		if( !waiting.backdrop )
			waiting.backdrop = jQuery( '<div class="waitingBackdrop"></div>' ).hide().appendTo( container );

		if( !waiting.icon )
			waiting.icon = jQuery( '<div class="waitingIcon"></div>' ).hide().appendTo( container );
		
		if( className )
		{
			waiting.backdrop.addClass( className );
			waiting.icon.addClass( className );
		}
		
		if( message )
		{
			if( !waiting.message )
				waiting.message = jQuery( '<div class="waitingMessageContent"></div>' ).appendTo( waiting.icon.addClass( 'waitingMessage' ) );

			waiting.message.text( message );
		}

		var offset, width, height;
		try
		{ 
			offset = $d.position();
			width = $d.outerWidth();
			height = $d.outerHeight();
		} 
		catch( e )
		{
			offset = { left:0, top:0 };
			width = jQuery( window ).width();
			height = jQuery( window ).height();
		}
		
		// compensate margins
		jQuery.each( [ 'top', 'right', 'bottom', 'left' ], function( i,t )
		{
			var k = 'margin-' + t;
			waiting.backdrop.css( k, $o.css( k ) );
			waiting.icon.css( k, $o.css( k ) );
		} );
	
		waiting.backdrop.css( 'left', offset.left +'px' ).css( 'top', offset.top +'px' ).width( width ).height( height );
		waiting.icon.css( 'left', offset.left +'px' ).css( 'top', offset.top +'px' ).width( width ).height( height );
		
		if( message )
		{
			waiting.icon.css('visibility','hidden').show();
			waiting.message.css( 'top', (waiting.icon.outerHeight() / 2) - ( waiting.message.outerHeight() / 2 )  );
			waiting.message.css( 'left', (waiting.icon.outerWidth() / 2) - ( waiting.message.outerWidth() / 2 )  );
			waiting.icon.css('visibility','visible').hide();
		}
		
		$d.data( 'waiting', waiting );
		waiting.backdrop.fadeIn( 200 );
		waiting.icon.fadeIn( 200 );
	});
};

jQuery.fn.stopWaiting = function( )
{
	var that = this;
	this.each( function( i, o )
	{
		var $o = jQuery( o ),
			delay = 200;
		
		if( $o.data( 'waiting' ) )
		{
			if( $o.data( 'waiting' ).backdrop )
			{
				$o.data( 'waiting' ).backdrop.fadeOut( delay, function()
				{
					if( $o && $o.data('waiting') )
						$o.data( 'waiting' ).backdrop.remove();
				} );
			}
			
			if( $o.data( 'waiting' ).icon )
			{
				$o.data( 'waiting' ).icon.fadeOut( delay, function()
				{
					if( $o && $o.data('waiting') )
						$o.data( 'waiting' ).icon.remove();
				} );
			}
			
			window.setTimeout( function()
			{
				if( $o )
					$o.removeData( 'waiting' ); 
			}, delay + 10 );
		}
			
	});
};