function isFilled(field) {
  if (field.value.length < 1 || field.value == field.defaultValue) {
    return false;
  } else {
    return true;
  }
}

function isEmail(field) {
  if (field.value.indexOf("@") == -1 || field.value.indexOf(".") == -1) {
    return false;
  } else {
    return true;
  }
}

var validation_messages;
var validation_labels;
var Validation = Class.create();

Validation.prototype = {
  initialize : function(form, options){
    this.options = Object.extend({}, options || {});
		this.form = form;
    Event.observe(this.form, 'submit', this.onSubmit.bind(this));
  },
  onSubmit : function(e) {
    if (!this.validate()) Event.stop(e);
  },
  validate : function() {
    var error_message = [];
    for (var i=0; i<this.form.elements.length; i++) {
      var element = this.form.elements[i];
      Element.removeClassName(element, 'error');
      if (element.className.indexOf("required") != -1) {
        if (!isFilled(element)) {
          validation_messages = validation_messages || [];
          validation_labels = validation_labels || [];
          if (validation_messages[element.name]) {
            error_message.push(validation_messages[element.name]);
          } else if (validation_labels[element.name]) {
            error_message.push(validation_labels[element.name] + " cannot be blank.");
          } else {
            error_message.push(element.name + " cannot be blank.");
          }
          Element.addClassName(element, 'error');
        }
      }
      if (element.className.indexOf("email") != -1) {
        if (!isEmail(element)) {
          if (validation_messages[element.name]) {
            error_message.push(validation_messages[element.name]);
          } else if (validation_labels[element.name]) {
            error_message.push(validation_labels[element.name] + " must be a valid email address.");
          } else {
            error_message.push(element.name + " must be a valid email address.");
          }
          Element.addClassName(element, 'error');
        }
      }
    }
    if (error_message.length > 0) {
      if ($('errors')) {
        // create <div id="errorExplanation" class="errorExplanation">
        var error_explanation = document.createElement('div');
        error_explanation.className = 'errorExplanation';
        error_explanation.setAttribute('id', 'errorExplanation');

        //create error heading
        var heading = document.createElement('h2');
        var heading_text = validation_messages['heading'] || (error_message.length) + ' errors prohibited this form form from being submitted';
        var heading_text_node = document.createTextNode(heading_text);
        heading.appendChild(heading_text_node);
        error_explanation.appendChild(heading);

        //create error subheading
        var subheading = document.createElement('p');
        var subheading_text = validation_messages['subheading'] || 'There were problems with the following fields:'
        var subheading_text_node = document.createTextNode(subheading_text);
        subheading.appendChild(subheading_text_node);
        error_explanation.appendChild(subheading);

        //create unordered list of errors
        var error_list = document.createElement('ul');
        for (var i=0; i<error_message.length; i++) {
          var list_item = document.createElement('li');
          var error_text = document.createTextNode(error_message[i]);
          list_item.appendChild(error_text);
          error_list.appendChild(list_item);
        }
        error_explanation.appendChild(error_list);

        //write error_explanation to page
        var errors = $('errors');
        if (document.getElementById('errorExplanation')) {
          var old_error_explanation = document.getElementById('errorExplanation');
          errors.replaceChild(error_explanation, old_error_explanation);
        } else {
          errors.appendChild(error_explanation);      
        }
        errors.style.display = 'block';
      } else {
        alert(error_message.join("\n"));
      }
      return false;
    } else {
      return true;
    }
  }
}