var validations = 
[
  // validation functions, add these as attributes to the element to be validated
  'valIfCheckedAll',      // valIfCheckedAll="radio1;radio2;radio3"
  'valIfCheckedOne',      // valIfCheckedOne="radio1;radio2;radio3"
  'valIfSelect',          // valIfSelect="dropdownlist1:1,2,8;dropdownlist2:3,a,value3;dropdownlist3:1->8"
  'valRadioGroup',        // validate if at least one of a specific radiobutton group members is checked
  'valCheckbox',          // validate if a checkbox has been checked
  'valEmpty',             // not "" || null
  'valInt',               // 2 || 2.00
  'valDecimal',           // 2.00
  'valDate',              // 24-03-97 || 03-24-97 || 24-03-1997 || 03-24-1997
  'valPhoneNumber',       // in this version only dutch phone numbers are supported (valPhoneNumber="NL")
                          // [10 digits in any format] 012-34 56 789 || [country code + 9 digits in any format] +31 6 1234 5678 / 0031 6 1234 5678
  'valZip',               // in this version only dutch zips are supported (valZip="NL")
                          // 1234AA || 1234 AA
  'valEmail',             // anyone@internet.com ([...]@[...].[...])
  'valRange',             // [[min]-[max]] ==> valRange="1-10" : 5 || 5.00
  'valCurrency',          // TODO: implemented partially -> needs thorough testing
  'valDropdown'           // [any selected item except the first one]
];

var currentLang = '1043';
var wronginput = '';

// main validation functions
function validateCurrentForm()
{
  if (__validateSpecific(null))
    return true;
  else
    return false;
}

function validateCurrentContainer(container)
{
  return __validateSpecific(container);
}


function __validateSpecific(container)
{
  var temp = 0;
  var allElements;
  if(container == null)
    allElements = document.forms[0].elements;
  else
    allElements = __da(container).getElementsByTagName('*');

  for(i = 0; i < allElements.length; i++)
  {
    var validated = false;
    // validate data type
    for(j = 0; j < validations.length; j++)
    {
      if(!validated)
        validated = __validateElement(allElements[i], validations[j]);
    }
  }
  // all input of appropriate data type?
  if(wronginput != '')
  {
    __alertWrongInput();
    return false;
  }
  
  // all went well, return true
  return true;
}

function __validateElement(e,l)
{
  var attr = e.getAttribute(l);
  if(attr != null)
  {
    var msg = e.getAttribute('msg');
    switch(currentLang.toLowerCase())
    {
      case 'nl':
      case '1043':
        msg = msg.substring(0,msg.indexOf('//'));
        break;
      case 'en':
      case '1031':
        msg = msg.substr(msg.indexOf('//') + 2);
        break;
      default:
        msg = msg.replace('//',' / ');
        break;
    }
    var val;
    if(l == 'valDropdown' && e.type == 'select-one')
      val = e.selectedIndex;
    else
      val = (e.value == null) ? '' : e.value;

    if(l == 'valIfCheckedAll')
      return !valIfCheckedAll(attr);

    if(l == 'valIfCheckedOne')
      return !valIfCheckedOne(attr);

    if(l == 'valRadioGroup')
      return !valRadioGroup(e,msg);

    if(l == 'valIfSelect')
      return !valIfSelect(attr);

    switch(l)
    {
      case 'valRange':
        if(!(eval(l+'("'+e.id+'", "'+attr+'", "'+msg+'", "'+val+'")')))
          return true;
        break;
      case 'valPhoneNumber':
        if(!(eval(l+'("'+e.id+'", "'+attr+'", "'+msg+'", "'+val+'")')))
          return true;
        break;
      case 'valZip':
        if(!(eval(l+'("'+e.id+'", "'+attr+'", "'+msg+'", "'+val+'")')))
          return true;
        break;
      default:
        if(!(eval(l+'("'+e.id+'", "'+msg+'", "'+val+'")')))
          return true;
        break;
    }
  }
  return false;
}



function __da(e)
{
  if(typeof(e) == 'string')
    return document.getElementById(e);

  return e;
}

function __alertWrongInput()
{
  if(wronginput != '')
  {
    switch(currentLang.toLowerCase())
    {
      case 'nl':
      case '1043':
        wronginput = 
          'De volgende velden zijn niet correct ingevuld:\n' + 
          '_______________________________________\n\n' + 
          wronginput + 
          '_______________________________________\n\n' +
          'Vul deze goed in';
        break;
      case 'en':
      case '1031':
        wronginput = 
          'The following fields have not been correctly filled in:\n' + 
          '_______________________________________\n\n' + 
          wronginput + 
          '_______________________________________\n\n' +
          'Please fill in these fields appropriately\n';
        break;
      default:
        wronginput = 
          'De volgende velden zijn niet correct ingevuld /\n' + 
          ' The following fields have not been correctly filled in:\n' + 
          '_______________________________________\n\n' + 
          wronginput + 
          '_______________________________________\n\n' +
          'Vul deze goed in /\n' +
          ' Please fill in these fields appropriately\n';
        break;
    }
    alert(wronginput);
  }
  wronginput = '';
}

function __addWrongInput(msg)
{
  wronginput += ' - ' + msg + '\n';
}

function valCheckbox(e,msg,val)
{
  if(!__da(e).checked)
  {
    __addWrongInput(msg);
    return false;
  }
  return true;
}


// specific validation functions
function valEmpty(e,msg,val)
{
  if((val == '') || (val == null))
  {
    __addWrongInput(msg);
    return false;
  }
  return true;
}

function valInt(e,msg,val)
{
  var value = parseInt(val);
  var str1 = '' + val;
  var str2 = '' + value;
  if(isNaN(value) || (str1.length > str2.length))
  {
    __addWrongInput(msg);
    return false;
  }
  return true;
}

function valDecimal(e,msg,val)
{
  val = val.replace(',','.');
  var value = parseFloat(val.replace(',','.'));
  if(isNaN(value))
  {
    __addWrongInput(msg);
    return false;
  }
  __da(e).value = value;
  return true;
}

function valDate(e,msg,val)
{
  var supported = true;
  if(isNaN(Date.parse('1-1-2000')))
    supported = false;

  if(supported)
  {
    var value = Date.parse(val);
    if(isNaN(value) && val != '')
    {
      __addWrongInput(msg);
      return false;
    }
  }
  else
  {
    // especially for you, dear firefox... thank you....... ><
    var patternDDMMYYYY = /^((((0?[1-9]|[12]\d|3[01])[\.\-\/](0?[13578]|1[02])[\.\-\/]((1[6-9]|[2-9]\d)?\d{2}))|((0?[1-9]|[12]\d|30)[\.\-\/](0?[13456789]|1[012])[\.\-\/]((1[6-9]|[2-9]\d)?\d{2}))|((0?[1-9]|1\d|2[0-8])[\.\-\/]0?2[\.\-\/]((1[6-9]|[2-9]\d)?\d{2}))|(29[\.\-\/]0?2[\.\-\/]((1[6-9]|[2-9]\d)?(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)|00)))|(((0[1-9]|[12]\d|3[01])(0[13578]|1[02])((1[6-9]|[2-9]\d)?\d{2}))|((0[1-9]|[12]\d|30)(0[13456789]|1[012])((1[6-9]|[2-9]\d)?\d{2}))|((0[1-9]|1\d|2[0-8])02((1[6-9]|[2-9]\d)?\d{2}))|(2902((1[6-9]|[2-9]\d)?(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)|00))))$/;
    var patternMMDDYYYY = /^(?=\d)(?:(?:(?:(?:(?:0?[13578]|1[02])(\/|-|\.)31)\1|(?:(?:0?[1,3-9]|1[0-2])(\/|-|\.)(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})|(?:0?2(\/|-|\.)29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))|(?:(?:0?[1-9])|(?:1[0-2]))(\/|-|\.)(?:0?[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{2}))($|\ (?=\d)))?(((0?[1-9]|1[012])(:[0-5]\d){0,2}(\ [AP]M))|([01]\d|2[0-3])(:[0-5]\d){1,2})?$/;
    if((val.search(patternDDMMYYYY) == -1) && (val.search(patternMMDDYYYY) == -1) && val != '')
    {
      __addWrongInput(msg);
      return false;
    }
  }
  return true;
}

function valPhoneNumber(e,attr,msg,val)
{
  if(attr == null)
  {
    switch(currentLang.toLowerCase())
    {
      case 'nl':
      case '1043':
        attr = 'NL';
        break;
      case 'en':
      case '1031':
        attr = 'EN';
        break;
      default:
        attr = 'UNDEFINED';
        break;
    }
  }
  switch(attr)
  {
    case 'NL':
      var value = val;
      if (val!="")
      {
        while((value.indexOf('-') > -1) || (value.indexOf(' ') > -1) || (value.indexOf(/\+[\d]{2,2}/) > -1))
          value = value.replace('-', '').replace(' ', '').replace(/\+[\d]{2,2}/, '0');
        if(value.indexOf('00') == 0)
          value = value.replace(/00[\d]{2,2}/, '0');
        if(value.search(/\d{10,10}/) == -1)
        {
          __addWrongInput(msg);
          return false;
        }
      }
      break;
    case 'EN':
      var value = val;
      if (val!="")
      {
        while((value.indexOf('-') > -1) || (value.indexOf(' ') > -1) || (value.indexOf(/\+[\d]{2,2}/) > -1))
          value = value.replace('-', '').replace(' ', '').replace(/\+[\d]{2,2}/, '0');
        if(value.indexOf('00') == 0)
          value = value.replace(/00[\d]{2,2}/, '0');
        if(value.search(/\d{10,10}/) == -1)
        {
          __addWrongInput(msg);
          return false;
        }
      }
      break;
    case 'UNDEFINED':
      var value = val;
      if (val!="")
      {
        while((value.indexOf('-') > -1) || (value.indexOf(' ') > -1) || (value.indexOf(/\+[\d]{2,2}/) > -1))
          value = value.replace('-', '').replace(' ', '').replace(/\+[\d]{2,2}/, '0');
        if(value.indexOf('00') == 0)
          value = value.replace(/00[\d]{2,2}/, '0');
        if(value.search(/\d{10,10}/) == -1)
        {
          __addWrongInput(msg);
          return false;
        }
      }
      break;
    default:
      break;
  }
  return true;
}

function valZip(e,attr,msg,val)
{
  switch(attr)
  {
    case 'NL':
      var value = val.replace(' ', '');
      var pattern = /\b[\d]{4,4}[\w]{2,2}\b/;
      if(value.search(pattern) < 0)
      {
        __addWrongInput(msg);
        return false;
      }
      __da(e).value = value.toUpperCase();
      break;
    default:
      break;
  }
  return true;
}

function valEmail(e,msg,val)
{
  var pattern = /.*\@.*\..*/;
  var result = val.match(pattern);
  if(result == null)
  {
    __addWrongInput(msg);
    return false;
  }
  __da(e).value = val.toLowerCase();
  return true;
}

function valRange(e,range,msg,val)
{
  val = val.replace(',','.')
  if(isNaN(val))
  {
    __addWrongInput(msg);
    return false;
  }
  var min = parseFloat(range.substring(0, range.indexOf(':')));
  var max = parseFloat(range.substr(range.indexOf(':') + 1));
  if(isNaN(min) && isNaN(max))
    return true;
  if(isNaN(min) && !isNaN(max))
  {
    if(parseFloat(val) > max)
    {
      __addWrongInput(msg);
      return false;
    }
  }
  if(!isNaN(min) && isNaN(max))
  {
    if(parseFloat(val) < min)
    {
      __addWrongInput(msg);
      return false;
    }
  }
  if(!isNaN(min) && !isNaN(max))
  {
    if(min > max)
      return true;
    else if(parseFloat(val) < min || parseFloat(val) > max)
    {
      __addWrongInput(msg);
      return false;
    }
  }
  __da(e).value = val;
  return true;
}

function valDropdown(e,msg,val)
{
  if(val == 0)
  {
    __addWrongInput(msg);
    return false;
  }
  return true;
}

function valIfCheckedAll(arr)
{
  var requiredRadios = arr.split(';');
  for(x = 0; x < requiredRadios.length; x++)
  {
    if(__da(requiredRadios[x]))
    {
      if(!__da(requiredRadios[x]).checked)
      {
        return false;
      }
    }
    else
    {
      return false;
    }
  }
  return true;
}

function valIfCheckedOne(arr)
{
  var requiredRadios = arr.split(';');
  for(x = 0; x < requiredRadios.length; x++)
  {
    if(__da(requiredRadios[x]))
    {
      if(__da(requiredRadios[x]).checked)
      {
        return true;
      }
    }
  }
  return false;
}
function valIfSelect(arr)
{
  var subsets = arr.split(';');
  for(y = 0; y < subsets.length; y++)
  {
    var dropdown = subsets[y].substring(0, subsets[y].indexOf(':'));
    var expr = subsets[y].substr(arr.indexOf(':') + 1);
    var validSelections = expr.split(',');
    if(validSelections.indexOf('->') > -1)
    {
      var min = validSelections.substring(0, validSelections.indexOf('->'));
      var max = validSelections.substr(validSelections.indexOf('->') + 1);
      for(z = min; z <= max; z++)
      {
        validSelections[validSelections.length] = z;
      }
    }
    for(x = 0; x < validSelections.length; x++)
    {
      if(__da(dropdown).value == validSelections[x])
        return true;
    }
  }
  return false;
}

function valRadioGroup(e,msg)
{
  toReturn = false ;
  var gr = document.getElementsByName(e.name)

  for(x = 0; x < gr.length; x++)
  {
    if(gr[x].name)
    {
      if(gr[x].checked)
        toReturn = true;    // return true if at least one is checked
    }
  }
  if (!toReturn)
    __addWrongInput(msg);

  return toReturn;
}

function valCurrency(e,msg,val)
{
  var abs;
  var dec;
  if(val.indexOf(',-') > -1)
  {
    abs = val.replace(',-','');
    dec = '.00';
  }
  else if(val.indexOf(',') > -1)
  {
    abs = val.substring(0,val.indexOf(','));
    dec = val.substr(val.indexOf(','));
  }
  else
  {
    abs = val;
    dec = '.00';
  }

  // DOES THIS WORK? => NEEDS TESTING
  var ctrl = ((abs.indexOf(',') > -1) || (abs.indexOf('.') > -1) || (abs.indexOf('-') > -1));
  while(ctrl)
  {
    abs = abs.replace(',','').replace('.','').replace('-','');
    ctrl = ((abs.indexOf(',') > -1) || (abs.indexOf('.') > -1) || (abs.indexOf('-') > -1));
  }

  var value = abs + '' + dec;
  value = parseFloat(value.replace(',','.'));
  if(isNaN(value))
  {
    __addWrongInput(msg);
    return false;
  }
  return true;
}

