(function( $ )
{
	// @todo Document this.
	$.extend( $, { placeholder: {
		browser_supported: function()
		{
			return this._supported !== undefined ?
				   this._supported :
				   ( this._supported = !!('placeholder' in $( '<input type="text">' )[0]) );
		},
		shim: function( opts )
		{
			var config = {
				color: '#ccc',
				cls: 'placeholder',
				lr_padding:4,
				selector: 'input[placeholder], textarea[placeholder]'
			};
			$.extend( config, opts );
			!this.browser_supported() && $( config.selector )._placeholder_shim( config );
		}
	}} );

	$.extend( $.fn, {
		_placeholder_shim: function( config )
		{
			function calcPositionCss( target )
			{
				var op = $( target ).offsetParent().offset();
				var ot = $( target ).offset();

				return {
					/*top: ot.top - ( op.top + ($( target ).outerHeight() - $( target ).height()) / 2 ),*/
					top: ot.top,
					left: ot.left - op.left + config.lr_padding,
					width: $( target ).width() - config.lr_padding
				};
			}

			return this.each( function()
							  {
								  var $this = $( this );

								  if ( $this.data( 'placeholder' ) )
								  {
									  var $ol = $this.data( 'placeholder' );
									  $ol.css( calcPositionCss( $this ) );
									  return true;
								  }

								  var possible_line_height = {};
								  if ( !$this.is( 'textarea' ) && $this.css( 'height' ) != 'auto' )
								  {
									  possible_line_height = { lineHeight: $this.css( 'height' ), whiteSpace: 'nowrap' };
								  }

								  var ol = $( '<label />' )
										  .text( $this.attr( 'placeholder' ) )
										  .addClass( config.cls )
										  .css( $.extend( {
															  position:'absolute',
															  display: 'inline',
															  float:'none',
															  overflow:'hidden',
															  textAlign: 'left',
															  color: config.color,
															  cursor: 'text',
															  paddingTop: $this.css( 'padding-top' ),
															  paddingLeft: $this.css( 'padding-left' ),
															  fontSize: $this.css( 'font-size' ),
															  fontFamily: $this.css( 'font-family' ),
															  fontStyle: $this.css( 'font-style' ),
															  fontWeight: $this.css( 'font-weight' ),
															  textTransform: $this.css( 'text-transform' ),
															  zIndex: 99
														  }, possible_line_height ) )
										  .css( calcPositionCss( this ) )
										  .attr( 'for', this.id )
										  .data( 'target', $this )
										  .click( function()
												  {
													  $( this ).data( 'target' ).focus()
												  } )
										  .insertBefore( this );
								  $this
										  .data( 'placeholder', ol )
										  .focus(
										  function()
										  {
											  ol.hide();
										  } ).blur(
										  function()
										  {
											  ol[$this.val().length ? 'hide' : 'show']();
										  } ).triggerHandler( 'blur' );
								  $( window )
										  .resize( function()
												   {
													   var $target = ol.data( 'target' )
													   ol.css( calcPositionCss( $target ) )
												   } );
							  } );
		}
	} );
})( jQuery );

jQuery( document ).add( window ).bind( 'ready load', function()
{
	if ( jQuery.placeholder )
	{
		jQuery.placeholder.shim();
	}
} );
