/**
 * jQuery.labelify - Display in-textbox hints
 * Stuart Langridge, http://www.kryogenix.org/
 * Released into the public domain
 * Date: 25th June 2008
 * @author Stuart Langridge
 * @version 1.3
 *
 *
 * Basic calling syntax: $("input").labelify();
 * Defaults to taking the in-field label from the field's title attribute
 *
 * You can also pass an options object with the following keys:
 *   text
 *     "title" to get the in-field label from the field's title attribute 
 *      (this is the default)
 *     "label" to get the in-field label from the inner text of the field's label
 *      (note that the label must be attached to the field with for="fieldid")
 *     a function which takes one parameter, the input field, and returns
 *      whatever text it likes
 *
 *   labelledClass
 *     a class that will be applied to the input field when it contains the
 *      label and removed when it contains user input. Defaults to blank.
 *  
 */
// Patch replaceWith to correctly keep events and such.
jQuery.fn.replaceWith = function(value) {
  return this.each(function() {
    var e = $(this);
    var s = e.next();
    var p = e.parent();
    e.remove();
    if (s.size())
      s.before(value);
    else
      p.append(value);
  });
}

jQuery.fn.labelify = function(settings) {
  settings = jQuery.extend({
    text: "title",
    labelledClass: ""
  }, settings);
  var lookups = {
    title: function(input) {
      return $(input).attr("title");
    },
    label: function(input) {
      return $("label[for=" + input.id +"]").text();
    }
  };
  var lookup;
  var jQuery_labellified_elements = $(this);
  var removeValuesOnExit = function() {
    jQuery_labellified_elements.each(function(){
      if (this.value === $(this).data("label")) {
        this.value = '';
        $(this).removeClass(settings.labelledClass);
      }
    })
  };
  
  $(this).parents("form").submit(removeValuesOnExit);
  $(window).unload(removeValuesOnExit);
    
  return jQuery_labellified_elements.each(function() {
    if (typeof settings.text === "string") {
      lookup = lookups[settings.text]; // what if not there?
    } else {
      lookup = settings.text; // what if not a fn?
    };
    // bail if lookup isn't a function or if it returns undefined
    if (typeof lookup !== "function") { return; }
    var lookupval = lookup(this);
    if (!lookupval) { return; }

    var isPassword = $(this).is(':password');
    if (isPassword)
    {
      var textElt = $("<input type='text' />");
      textElt.attr('class', $(this).attr('class'));
      textElt.attr('id', $(this).attr('id'));
      textElt.attr('name', $(this).attr('name'));
      this.textElt = textElt.get(0);
      this.textElt.pwElt = this;
    }

    // need to strip newlines because the browser strips them
    // if you set textbox.value to a string containing them    
    lookuval = lookupval.replace(/\n/g, '');
    $(this).data('label', lookupval);

    if (isPassword) {
      var blur = function() { // happens on pw elt
        if (this.value === '') {
          $(this).replaceWith(this.textElt);

          $(this.textElt).val(lookupval)
                         .focus(focus)
                         .addClass(settings.labelledClass);
        }
      }, focus = function() { // happens on text elt
        $(this).replaceWith(this.pwElt);

        $(this.pwElt).val(this.pwElt.defaultValue)
                     .blur(blur);

        // So IE correctly focuses.
        setTimeout(function() { $(this.pwElt).focus(); }, 1);
        $(this.pwElt).focus();
      };
      $(this).blur(blur);
      $(this.textElt).focus(focus);
    } else {
      $(this).focus(function() {
        if (this.value === lookupval) {
          this.value = '';
          $(this).removeClass(settings.labelledClass);
        }
      }).blur(function() {
        if (this.value === '' || this.value === lookupval) {
          this.value = lookupval;
          $(this).addClass(settings.labelledClass);
        }
      });
    }

    if (this.value !== '') {
      // user already started typing; don't overwrite their work!
      return;
    }

    // actually set the value
    $(this).blur();
  });
};
