
if (!String.parseAttributes)
  String.prototype.parseAttributes = function (sep) {
    var
      av,
      a = {},
      attrib = this.split (sep || /\s*;\s*/);

      !sep && (attrib.length == 1) && (attrib[0].indexOf(':') == false) && (attrib = attrib[0].split (/\s+/));

    for (var i = attrib.length; i--;)
      if (attrib[i]) {
        av = attrib[i].match (/^([a-z0-9-_]+)(:\s*(.*)\s*)?$/i);
        if (av && av[3] && av[3].match (/^\d+$/))
          av[3] = parseInt (av[3], 10);
        av && av.length && (a[av[1].toLowerCase()] = ((av[3] != 0) && (av[3] == '' || !av[3]) ? true : av[3]));
      }
    return a;
  }


function addEvent (el, ev, handler){
  if (el.addEventListener)
    el.addEventListener (ev, handler, false);
  else if (el.attachEvent)
    el.attachEvent ("on" +ev, handler);
}


var prompt = { //====================================== form field prompter ===
  absPos: function (el) {
    var p = {'y': 0, 'x': 0};
    do {
      p.y += el.offsetTop;
      p.x += el.offsetLeft;
    }  while (el = el.offsetParent);
    return p;
  },

  toggle: function (el) { // Toggle help text depending on INPUT field contents
    prompt.el = el = el.target || window.event.srcElement;
    var pdiv = el.prompt || prompt.div;

    if (el.value == '') {  // Field is empty; show text
      var elpos = prompt.absPos (el);
      pdiv.style.left = (elpos.x + 10) + 'px';
      pdiv.style.top = (elpos.y + el.offsetHeight / 2 - 7) + 'px';
      if (pdiv.innerHTML = el.getAttribute ('help') || el.title) {
        el.onblur = prompt.hide;
        pdiv.style.visibility = 'visible';
      }
    }
    else {
      delete el.onblur;
      pdiv.style.visibility = 'hidden';
    }
  },

  hide: function  (el) { // Turn off prompt display
    if(prompt.el == (el = el.target || window.event.srcElement))
      (el.prompt || prompt.div).style.visibility = 'hidden';
  },

  init: function (el) {
    if (!prompt.div && !(prompt.div = document.getElementById ("prompt"))) {
      document.body.innerHTML += '<div class="prompt" id="prompt"></div>';
      prompt.div = document.getElementById ("prompt");
    }

    var
      elist = document.getElementsByTagName ('input');
    for (var p, i = elist.length; i--;) if (elist[i].getAttribute('help')) {
      elist[i].onfocus = elist[i].onkeyup = prompt.toggle;
      if (p = elist[i].getAttribute('prompt'))
        elist[i].setAttribute('prompt', document.getElementById (p) || prompt.div);
    }
  }
}

window.prompt && prompt.init && addEvent (window, 'load', prompt.init);


var formCheck = { //==================================== form field checker ===
  validate: {
    'alphameric': RegExp ('^[A-Z0-9]+$','i'),
    'alpha':      RegExp ('^[A-Z]+$','i'),
    'required':   RegExp ('\\S+'),
    'numeric':    RegExp ('^[0-9]+$'),
    'signed':     RegExp ('^[-+]?[0-9]+$'),
    'tel':        RegExp ('^(\\+[0-9]+\\s*)?(\\([0-9]+\\)\\s*)?([0-9]+\\s*)+$'),
    'email':      RegExp ('^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.([A-Z]{2,4}|museum)$', 'i')
  },

  actions: {
    'trim': function (el) {el.value = trim(el.value)}
  },


  fieldcheck: function (el) {
    el = el ? el.target || el : window.event.srcElement;

    var
      cl,
      clauses,
      re,
      emel = document.getElementById ("err_" + el.name),
      check = el.getAttribute ("check"),
      form = el;

    if (!check || !(check = check.parseAttributes ()))
      return true;

    while (form && !form.elements)
      form = form.parentNode;

    clauses = (check.fmt || "").split (/\&\&|^^|\|\||\(\(|\)\)!/);
    for (cl in clauses) {
      re = clauses[cl].match (/^ *(.*?)( *\[ *([^[\]]+) *\])? *$/);
      re[1] = formCheck.validate[re[1]] || RegExp (re[1]);
      re[3] = re[3] ? form[re[3]].value : el.value;
      check.fmt = check.fmt.replace (clauses[cl], re[1].test (re[3]) ? '1' : '0');
//    confirm (cl + " : " + clauses[cl] + " -- " + check.fmt);
    }

    if (!eval (check.fmt.replace('^^', '^') || "1")) {
      el.focus ();
      formCheck.focussed = true;
      if (!el.className.match (/\berror\b/i)) {
        el.className += " error";
        if (check.msg) {
          check.msg = check.msg.replace ("\\n", "<br /> ");
          if (emel)
            emel.innerHTML = check.msg;
          else
            el.title = check.msg;
        }

        el.onchange = formCheck.formCheck;
      }
      return false;
    }

    if (emel)
      emel.innerHTML = '';
    else
      delete el.title;
    delete el.onchange;
    el.className = el.className.replace(/(^|\s+)error\b/, '');

    if (check.action) {
      window["formAction_" + check.action] && window["formAction_" +check.action] (el);
      formCheck.actions[check.action] && formCheck.actions[check.action] (el);
    }

    return true;
  },

  formCheck: function (el) {
    el = el ? el.target || el : window.event.srcElement;
    while (el && !el.elements) el = el.parentNode;
    if (!el) return false;

    for (var ok = true, j = el.elements.length; j--;)
      ok = formCheck.fieldcheck (el.elements[j]) && ok;

    if (!formCheck.focussed)
      el.elements[0].focus ();
    delete formCheck.focussed;

    return ok;
  },

  init: function () {
    for (var i = document.forms.length; i--;) with (document.forms[i]) {
      for (var j = elements.length; j--;)
        if (elements[j].getAttribute ('check')) {
          document.forms[i].onsubmit = formCheck.formCheck;
          elements[0].focus ();
          break;
        }
    }
  }
}

window.formCheck && formCheck.init && addEvent (window, 'load', formCheck.init);

