(function( $ ){


  $.fn.formLabels = function(options) {  

    var defaults = {
        valueSource: 'label', //can be "label" for the label text, "initial" for the initial field value, or "values" for user-provided values
        values: {},
        excludeHidden: true //won't touch hidden form fields if set to true
    };      
        
    var options = $.extend(defaults,options);
    
    var wrapset = this;
    
    var setClickHandler = function(obj) {
        
      $(obj).attr('rel',obj.labelTxt);  
      

        
      if ($(obj).attr('type') == 'text') {
        setTextClickHandler(obj)
        return;
      }
      
      if (obj.nodeName == 'TEXTAREA') {
        setTextareaClickHandler(obj)
        return;
      }
    
    }
    
    var setClearHandler = function(obj) {
      
      $(obj).first().parents('form').submit(function(e) {

        $(wrapset).each(function() {
        
          if ($(this).val() == $(this).attr('rel')) {
            $(this).attr('value','');
          }

        });
        
      });
      
    }
    
    var setTextClickHandler = function(obj) {
        
      if ($(obj).val() == "")
        $(obj).val(obj.labelTxt);
          
      $(obj).focus(function() {
        
        if ($(obj).val() == obj.labelTxt)
          $(obj).val('');
                     
      });

      $(obj).blur(function() {
        
        if ($(this).val() == '')
          $(this).val(obj.labelTxt);
          
      });     
      
      
    }
    
    var setTextareaClickHandler = function(obj) {

      if ($(obj).text() == "")
        $(obj).text(obj.labelTxt);
      
      $(obj).focus(function() {
        
        if ($(obj).val() == obj.labelTxt)
          $(obj).text('');
          
      });

      $(obj).blur(function() {
        
        if ($(obj).val() == '')
           $(obj).text(obj.labelTxt);
          
      });     
      
    }
  
    function getLabelText(elem) {
    
      if (options.valueSource == 'label') {
        var forAttr = $(elem).attr('id'); 
        return $('body').find('label[for="'+ forAttr +'"]').text();
      }
      
      if (options.valueSource == 'initial') {
        return $(elem).val();        
      }
      
      if (options.valueSource == 'values') {
        var name = $(elem).attr('name');
        return eval('options.values.'+name);
      }
      
    }


    setClearHandler(wrapset);
    
    if (!options.excludeHidden)
      wrapset == $(wrapset).not('[type="hidden"]');
    
    $(wrapset).not('[type="hidden"]').each(function() {        

      this.labelTxt = getLabelText(this);
      
      if (typeof(this.labelTxt) == 'undefined')
        return;
      
      setClickHandler(this);

    });
  };
})( jQuery );
