/**
 * Evos 1.1 - epointment validate on submit (or 'easiest validate on submit')
 *
 * (c) 2006-2007 http://www.epointment.com
 *
 * Author: Ivo Jansch <ivo@epointment.com>
 *
 * Evos is freely distributable under the terms of a BSD-style license.
 * Evos is provided as-is, with absolutely no warranty of any kind.
 *
 * For details, see the Evos web site: http://www.epointment.com/software/evos
 *
 * (prototype is included to make the demo work out of the box, see the
 * prototype.js file for prototype details)
 */


document.getElementsByTagNames = function(tagNames, parentElement) {
  var list = tagNames.split(',');
  var children = ($(parentElement) || document.body).getElementsByTagName('*');
  return $A(children).inject([], function(elements, child) {
    if (list.include(child.tagName.toLowerCase()))
      elements.push(child);
    return elements;
  });
}

if (typeof(Epointment) == 'undefined')
{
  var Epointment = {};
}

Epointment.SubmitObserver = Class.create();
Epointment.SubmitObserver.prototype = {

  initialize: function(parentElement) {
    this.parentElement = parentElement;
    Event.observe(window, 'load', this.onWindowLoad.bind(this));
  },

  onWindowLoad: function() {
    var observer = this;

    document.getElementsByTagNames('form').each(function (element)
    {
      Event.observe($(element.id), 'submit', observer.onSubmit.bind(observer));
    });

  },

  errors: null,
  currenterrors: null,

  validate: function(element, form) {
    var observer = this;
    observer.currenterrors = new Array();

    var fieldname = observer.getFieldname(element, form);

    // id based (custom) validation.
    var fn = 'validate_'+element.id;
    func = window[fn];
    if (typeof(func)=='function')
    {
      func(observer, element, fieldname, form);
    }

    // class based validation
    Element.classNames(element).each(function(classname)
    {
      var fn = 'validate_'+classname;
      func = observer[fn];
      if (typeof(func)=='function')
      {
        func(observer, element, fieldname, form);
      }
    });

    if (observer.currenterrors.length == 0)
    {
      observer.removeErrorClass(element, form);
    }
    else
    {
      observer.addErrorClass(element, form);
    }

  },

  onSubmit: function(ev) {
    var observer = this;
    

    // locate the form that has been submitted
    currentform = Event.findElement(ev, 'form');

    observer.errors = new Array();
    formelements = Form.getElements(currentform);
    formelements.each(
      (function (element)
       {
         observer.validate(element, currentform);
       }
       ));

    if (observer.errors.length>0)
    {
      var result = '';
      for(i=0; i<observer.errors.length; i++)
      {
        result+=(observer.errors[i])+'\n';
      }
      els = document.getElementsByClassName('errors', currentform);
      
      if (els.length>0)
      {
        els.each(function(element)
        
        {
          $(element).innerHTML = result.replace(/\n/g,'<br />');
          /* ' (zend studio syntax highligher bug) */
          $(element).style.display = 'block';
			
        });
      }
      else
      {
        alert(result);
      }
      Event.stop(ev);
    }

  },

  findLabel: function (el, form)
  {
    var labels=form.getElementsByTagName('label');

    for(var i=0;i<labels.length;i++)
		{
			if(labels[i].htmlFor==el.id)
		  {
			  return labels[i];
			}
		}
		return null;
  },

  getFieldname: function(element, form) {
    var label = this.findLabel(element, form);

    if (label)
    {
      return label.innerHTML;
    }
    return $(element).name;
  },

  addErrorClass: function(element, form) {
    Element.classNames(element).add('error');

    var label = this.findLabel(element, form);
    if (label)
    {
    	Element.classNames(label).add('error');
    }
  },

  removeErrorClass: function(element, form) {
    Element.classNames(element).remove('error');

    var label = this.findLabel(element, form);
    if (label)
    {
      Element.classNames(label).remove('error');
    }
  },

  addError: function(observer, msg) {
    observer.errors[observer.errors.length] = msg;
    observer.currenterrors[observer.currenterrors.length] = msg;
  },

  /**
   * The actual validation methods start here.
   */


  validate_required: function(observer, element, fieldname) {
    if (!$F(element))
    {
      observer.addError(observer, Epointment.txt['required'].replace("%s", fieldname));
    }
  },

  validate_required_choice: function(observer, element, fieldname, form) {
    name = element.name;
    var found = false;
    Form.getInputs(form, null, name).each(function(element){
      if ($F(element)) found = true;
    });
    if (!found) {
      var msg = Epointment.txt['required_choice'].replace("%s", fieldname)
      found = false;
      $A(observer.errors).each(function(mess){
        if (msg==mess) found=true;
      });
      if (!found)
        observer.addError(observer, msg);
    }
  },

  validate_numeric: function(observer, element, fieldname) {
    var re = /^(-)?(\d*)(\.?)(\d*)$/;
    if (!$F(element).match(re))
    {
      observer.addError(observer, Epointment.txt['numeric'].replace("%s", fieldname));
    }
  },

  validate_email: function(observer, element, fieldname) {
    var re = /^[\w-_.]*[\w-_.]\@[\w].+[\w]+[\w]$/;
    if ($F(element) && !$F(element).match(re))
    {
      observer.addError(observer, Epointment.txt['email'].replace("%s", fieldname));
    }
  },

  /**
   * @todo Only supports dd-mm-yyyy format at the moment.
   */
  validate_date: function(observer, element, fieldname) {
    var re = /^[0123][0-9]-[01][0-9]-[12][90][0-9]{2}$/;
    if ($F(element) && !$F(element).match(re))
    {
      observer.addError(observer, Epointment.txt['date'].replace("%s", fieldname));
    }
  }
};
