var validationsToAskFor = new Array();
var inValidationRefresh = false;
var validationUrl;
var validationCommand = "view=getValidationErrors";
var validationControl;

function initValidation (url)
  {
  validationUrl = url;
  }

function ValidationEntry (fld, validator)
  {
  this.fld = fld;
  this.validator = validator;
  this.wrapperDiv = fld.parentNode;
  this.attname = fld.parentNode.getAttribute("attname");
  this.msgDiv = fld.parentNode.getElementsByTagName("div")[0];
  if (this.msgDiv == null)
    {
    this.row = findAppendRow (fld.parentNode, "appendMessageRows", "true");
    if (!this.row)
      this.row = findAppendRow (fld.parentNode, null, null);
    }
  if (this.row)
    this.localError = true;
  else
    this.localError = false;
  
  this.text = fld.value;
  this.version = 0;
  this.status = 0;
  
  this.incVersion = 
    function ()
      {
      var oldvar = parseInt(this.wrapperDiv.getAttribute("version"));
      this.version = 1;
      if (oldvar)
        this.version += parseInt(oldvar);
      this.wrapperDiv.setAttribute ("version", "" + this.version);
      };
      
  this.lineup = 
    function ()
      {
      this.incVersion();
      this.status = 1;
      var hit = findFieldAsValidationEntry (this.fld);
      if (hit == -1)
        hit = validationsToAskFor.length;
      validationsToAskFor[hit] = this;
      setTimeout ("validationsRefresh()", 10);
      };
      
  this.clearMsg =
    function ()
      {
      this.status = 0;
      if (this.localError)
        removeValidatorText (this.fld.name, this.attname, this.row);
      else
        {  
        this.msgDiv.style.display = "none";
        this.msgDiv.innerHTML = "";
        }
      };
      
  this.setMsg =
    function (msg)
      {        
      this.status = 3;
      if (this.localError)
        makeValidatorText (this.fld.name, this.attname, this.row, msg);
      else
        {  
        this.msgDiv.style.display = "block";
        this.msgDiv.innerHTML = msg;
        }
      };
      
  this.setNewText =
    function (text)
      {
      this.fld.value = text;
      };
      
  this.getAskForParam =
    function (i)
      {
      var text = this.text;
      if (text.indexOf("/") != -1)
        text = text.split("/").join("%252F");
      if (text.indexOf("|") != -1)
        text = text.split("|").join("%257C");
      var par = "" + i + "/" + this.attname + "/" + this.version + "/" + this.validator +"/" + text;
      return par;
      };
  }

function findAppendRow (node, needsAttrib, attribValue)
  {
  if (node.tagName.toLowerCase() == "tr" && (!needsAttrib || node.getAttribute (needsAttrib) == attribValue))
    return node;
  else if (node.parentNode)
    return findAppendRow (node.parentNode);
  return null;
  }

function hasValidationMessages ()
  {
  for (var i = 0; i < validationsToAskFor.length; ++i)
    if (validationsToAskFor[i].fld == fld)
      return i;
  return -1;
  }

function findFieldAsValidationEntry (fld)
  {
  for (var i = 0; i < validationsToAskFor.length; ++i)
    if (validationsToAskFor[i].fld == fld)
      return i;
  return -1;
  }

function createValidationControl()
  {
  if (typeof XMLHttpRequest != 'undefined')
    return new XMLHttpRequest();
  var C = null;
  try
    {
    C = new ActiveXObject("Msxml2.XMLHTTP")
    }
  catch (e)
    {
    try
      {
      C = new ActiveXObject("Microsoft.XMLHTTP")
      }
    catch (sc)
      {
      C = null
      }
    }
  return C
  }

function hasOpenValidations()
  {
  for (var i = 0; i < validationsToAskFor.length; ++i)
    if (validationsToAskFor[i].status == 3)
      return true;
  return false;
  }
  
function hasRunningValidations()
  {
  return inValidationRefresh;
  }
  
function triggerValidation (fld, validator)
  {
  var ve = new ValidationEntry (fld, validator);
  ve.clearMsg();
  ve.lineup();
  }

function validationsRefresh ()
  {
  if (inValidationRefresh)
    {
    setTimeout ("validationsRefresh()", 500);
    return;
    }
  inValidationRefresh = true;
  var param = null;
  for (var i = 0; i < validationsToAskFor.length; ++i)
    {
    var ve = validationsToAskFor[i];
    if (ve.status == 1)
      {
      ve.status = 2;
      if (param)
        param += "|" + ve.getAskForParam (i);
      else
        param = ve.getAskForParam (i);
      }
    }
  if (!param)
    {
    inValidationRefresh = false;
    return;
    }
  askForValidations (param);
  }

function askForValidations (param)
  {
  if (validationControl && validationControl.readyState != 0)
    validationControl.abort();
  validationControl = createValidationControl();
  if (!validationControl)
    return;
  param = encodeURIComponent(param); 
  var cmd = validationCommand + "&umlauts=ä ö ü Ä Ö Ü ß&validate=" + param;
  if (!validationUrl)
    validationUrl = location.protocol + "//" + location.host + location.pathname;
  validationControl.open ("POST", validationUrl, true);
  validationControl.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  validationControl.setRequestHeader("Content-length", cmd.length);
  //validationControl.setRequestHeader("Connection", "close");
  validationControl.onreadystatechange = function()
    {
    if (validationControl.readyState == 4)
      {
      var result = validationControl.responseText;
      if (result.charAt(0) != "<")
        distributeValidationResult (result);
      inValidationRefresh = false;
      }
    };
  validationControl.send (cmd);
  }

function distributeValidationResult (result)
  {
  if (!result || result == "")
    return;
  var results = result.split("|");
  for (var i = 0; i < results.length; i ++)
    {
//alert ("received: " + results[i]);
    var pars = results[i].split("/");
    var nr = parseInt (pars[0]);
    if (validationsToAskFor.length <= nr)
      continue;
    var version = parseInt (pars[1]);
    var ve = validationsToAskFor[nr];
    if (ve.status != 2 || ve.version != version)
      continue;
    var msg = decodeURIComponent (pars[2]);
    if (msg != "")
      ve.setMsg (msg);
    else
      ve.clearMsg (msg);
    var text = decodeURIComponent (pars[3]);
//alert ("new text: " + text);
    if (text && text != "")
      ve.setNewText (text);
    }
  }


