( function( $ ) {

   // plugin definition
   $.fn.overlabel = function( options ) {

      // build main options before element iteration
      var opts = $.extend( {}, $.fn.overlabel.defaults, options );

      var selection = $.map(this, function(element) {

         var label = $( element );
         var id = label.attr( 'for' );

         var field = document.getElementById( id );

         if ( !field ) return;

         // build element specific options
         var o = $.meta ? $.extend( {}, opts, label.data() ) : opts;

         label.addClass( o.label_class );

         var hide_label = function() { label.css( o.hide_css ) };
         var show_label = function() { this.value || label.css( o.show_css ) };

         $( field )
              .parent().addClass( o.wrapper_class ).end()
              .focus( hide_label ).blur( show_label ).each( show_label );

         return this;

      } );

      return opts.filter ? selection : this;
   };

   // publicly accessible defaults
   $.fn.overlabel.defaults = {

      label_class:   'overlabel-apply',
      wrapper_class: 'overlabel-wrapper',
      hide_css:      { 'text-indent': '-10000px' },
      show_css:      { 'text-indent': '0px', 'cursor': 'text' },
      filter:        false

   };

} )( jQuery );