// validate Funktionen
var  validateVersion= 1.0,                // die aktuelle Version
	 setJSVal = 1,						  // validation ausführen
     validatorShowInitErrors= false,      // interne Fehler anzeigen ?
     validateForm= document.formular;     // die zu validierende Form,
                                          // sollte nach dem Einbinden angepasst werden
/*
  bei den nachfolgenden validateXXX - Funktionen sind die ersten beiden Parameter immer
  gleich und werden darum nur einmal beschrieben:
    isValid - hier kann ein anderer Validator sein Ergebniss zurückgeben. Bei false
              wird der Validator auch false zurückgeben.
              Bei 'useFieldName' wird der Wert aus fieldName validiert.
    fieldName - der Formularname aus dem Formular validateForm (s.o.) oder ein zu
                validierender Wert siehe isValid
  Zusätzlich gibt es für jeden Validator noch individuelle Parameter, die dann auch immer
  einen weiteren xxxErrMsg-Parameter haben, der den Fehlertext enthält.
  Achtung! Sollte xxxErrMsg leer sein, wird ein Validator immer true zurückgeben!
*/
/* ------------------------ Zeichenanzahlvalidator --------------------------------------
Input: [min, max] - die mindest-Anzahl Zeichen, bzw. die maximal-Anzahl
*/
function validateSign(isValid, fieldName, min, minErrMsg, max, maxErrMsg)
{
   if (setJSVal==0)
   	return true;
   var elem,
       value= '',
       errorMsg= false;
   if ( isValid == 'useFieldName' )       // nur validieren?
      value= fieldName;          // dann steht in fieldName der Wert
   else
   {
      if ( !isValid )
         return false;
      elem= validateForm.elements[fieldName];
      if ( !elem )
         return validatorShowInitError('validateSign -> formular-field not found', true);
      value= elem.value;
   }
   if ( typeof value == 'string' )
   {
      min= parseInt(min, 10);
      if ( !isNaN(min) && min > 0 )
      {
         if ( value.length < min )
            errorMsg= minErrMsg;
      }
      max= parseInt(max, 10);
      if ( !isNaN(max) && max > 0 )
      {
         if ( value.length > max )
            errorMsg= maxErrMsg;
      }
   }
   return validatorShowError(errorMsg, elem);
}

/* -------------------------------- Datumsvalidator --------------------------------------
Input: pattern - Das Ausgabeformat und die Reihenfolge, wie die Eingabe interpretiert
                 werden soll, zb. "dd.mm.yy" -> 30.04.03 oder "m/d/yyyy" -> 4/30/2003
       patternErrMsg - der ensprechende Fehlertext
       [min, max] - Wenn ein Datum(als String) eingegeben wird, wird min oder max bei
//                  einem gültigen Datum auf dieses gesetzt, bei einer Zahl wird
//                  das aktuelle Datum + min bzw. max (tage) genommen.
       
*/
function validateDate(isValid, fieldName, pattern , patternErrMsg, min, minErrMsg, max, maxErrMsg)
{
   if (setJSVal==0)
	return true;
   var elem,
       value= '',
       errorMsg= false;
   if ( isValid == 'useFieldName' )       // nur validieren?
      value= fieldName;          // dann steht in fieldName der Wert
   else
   {
      if ( !isValid )
         return false;
      elem= validateForm.elements[fieldName];
      if ( !elem )
         return validatorShowInitError('validateDate -> formular-field not found', true);
      value= elem.value;
   }
   if ( typeof value == 'string' )
   {
     if ( value )
     {
        var   rexp= /^(\d{1,4})(.)(\d{1,4})(.)(\d{1,4})$/,
              day, iDay,
              mon, iMon,
              year, iYear,
              maxday= 31,
              len= new Array (),
              patts= pattern.match(/^(D{1,2}|M{1,2}|Y{2,4})([^DMY])(D{1,2}|M{1,2}|Y{2,4})([^DMY])(D{1,2}|M{1,2}|Y{2,4})$/);
        if ( patts )
        {
           for ( var i=1; i< patts.length; i+= 2 )
              switch ( patts[i].charAt(0) )
              {
                case 'D':
                  iDay= i;
                  patts[i]= patts[i].length == 2 ? 100 : ' ';
                  len[i]= 2;
                break;
                case 'M':
                  iMon= i;
                  patts[i]= patts[i].length == 2 ? 100 : ' ';
                  len[i]= 2;
                break;
                case 'Y':
                  iYear= i;
                  len[i]= (i == 1 ? patts[i].length : 4);
                break;
                default:
                  return validatorShowInitError('validateDate -> Error in Datumspattern', true);
              }
        }
        else
           return validatorShowInitError('validateDate -> Error in Datumspattern', true);
        eval("rexp= /^(\\d{1," + len[1] + "})(\\D)?(\\d{1," + len[3]
             + "})(\\D)?(\\d{1," + len[5] + "})$/;");
        var elems= value.match(rexp);
        if ( elems == null )
           errorMsg= patternErrMsg;
        else
        {
           day= parseInt(elems[iDay],10);
           mon= parseInt(elems[iMon],10);
           year= parseInt(elems[iYear],10);
           if ( isNaN(year) || year < 0 )
              errorMsg= patternErrMsg;
           else
           {
             if ( year < 50 )
                year= 2000 + year;
             else
                if ( year < 100 )
                   year= 1900 + year;
             if ( isNaN(mon) || mon < 1 || mon > 12 )
                errorMsg= patternErrMsg;
             else
             {
                switch ( mon )
                {
                   case 4:
                   case 6:
                   case 9:
                   case 11:
                     maxday= 30;
                   break;
                   case 2:
                     if ((year % 4 == 0) || (year % 100 == 0) || (year % 400 == 0))
                        maxday= 29;
                     else
                        maxday= 28;
                   break;
                }
                if ( day > maxday )
                   errorMsg= patternErrMsg;
                else
                {
                   patts[0]= '';
                   patts[iDay] = String(patts[iDay] + day).slice(1);
                   patts[iMon] = String(patts[iMon] + mon).slice(1);
                   if ( isValid == 'useFieldName' )       // nur Datumswandlung?
                   {
                      patts[iYear] = String(year);
                      return patts.join('');
                   }
                   else
                      patts[iYear] = String(year).slice(4 - patts[iYear].length );
                   elem.value= patts.join('');
                   if ( (min= validateDate_getMinMax(min, pattern)) )
                   {
                     if ( typeof min == 'string' && (elems= min.match(rexp)) )
                     {
                        var  myear= parseInt(elems[iYear], 10);
                        if ( year <= myear )
                        {
                           if ( year == myear )
                           {
                             var mmon= parseInt(elems[iMon],10);
                             if ( mon < mmon ||
                                 ( mon == mmon && day <  parseInt(elems[iDay],10) ) )
                                errorMsg= minErrMsg;
                           }
                           else
                             errorMsg= minErrMsg;
                        }
                     }
                   }
                   if ( (max= validateDate_getMinMax(max, pattern)) )
                   {
                     if ( typeof max == 'string' && (elems= max.match(rexp)) )
                     {
                        var  myear= parseInt(elems[iYear],10);
                        if ( year >= myear )
                        {
                           if ( year == myear )
                           {
                             var mmon= parseInt(elems[iMon],10);
                             if ( mon > mmon ||
                                 ( mon == mmon && day >  parseInt(elems[iDay],10) ) )
                                errorMsg= maxErrMsg;
                           }
                           else
                              errorMsg= maxErrMsg;
                        }
                     }
                   }
                }
             }
          }
        }
     }
   }
   else
      errorMsg= patternErrMsg;
   return validatorShowError(errorMsg, elem);
}
//wird intern von validateDate genutzt
function validateDate_getMinMax(value, pattern)
{
   if ( !value )
      return false;
   var ret= validateDate('useFieldName',value, pattern);
   if ( ret === true )
   {
      if ( !isNaN(value) )
      {
        var now= new Date();
        now.setDate(now.getDate() + parseInt(value,10));
        ret= pattern.replace(/D{1,2}/, String(100 + now.getDate()).slice(1)).replace(/M{1,2}/, String(101 + now.getMonth()).slice(1)).replace(/Y{1,4}/, now.getFullYear());
      }
      else
         return validatorShowInitError('validateDate_getMinMax -> wrong Value!', false);
   }
   return ret;
}
/* ------------------------------ Numbervalidator ---------------------------------------
Input: decimalDigit - Trennzeichen '.' oder ','
       [min, max] - ein mindestWert, bzw. maximalWert
*/
function validateNumber(isValid, fieldName, invalidErrMsg, decimalDigit , min, minErrMsg, max, maxErrMsg)
{
   if (setJSVal==0)
	return true;
   var elem,
       value= '',
       errorMsg= false;
   if ( isValid == 'useFieldName' )       // nur validieren?
      value= fieldName;          // dann steht in fieldName der Wert
   else
   {
      if ( !isValid )
         return false;
      elem= validateForm.elements[fieldName];
      if ( !elem )
         return validatorShowInitError('validateNumber -> formular-field not found', true);
      value= elem.value;
   }
   if ( value != "" )
   {
       value= value.replace(",", ".");
       var dblValue= parseFloat(value);
       if ( !isNaN(dblValue) )
       {
          if ( isValid == 'useFieldName' )
             return dblValue;
          var intValue= parseInt(dblValue, 10);
          if ( decimalDigit )
          {
              decimalDigit += "||";
              var f = decimalDigit.split("|", 4),
                  cnt,
                  m= value.match(/^[-+]?(0*)([0-9]*)(\.([0-9]*[1-9])?(0*))?$/);
              decimalDigit = f[0];
              if (m)
              {
                 value = intValue;
                 f[1] = parseInt(f[1], 10);
                 if ( !isNaN(f[1]) )
                 {
                    if ( f[1] > 0 )
                    {
                       cnt = f[1] - m[2].length;
                       if ( cnt > 0 )
                          value = str_repeat(cnt, 48) + intValue;
                    } 
                    else if ( f[1] < 0 )
                    {
                       cnt = f[1] + m[2].length;
                       if ( cnt < 0 )
                          value = intValue + str_repeat(-cnt, 48);
                    }
                 }
                 else
                    value = m[1] + intValue;
                 if ( decimalDigit != "" )
                 {
                    decimalDigit += m[4] || '';
                    f[2]= parseInt(f[2], 10);
                    if ( !isNaN(f[2]) )
                    {
                       cnt = f[2] - m[4].length;
                       if ( cnt > 0 )
                          decimalDigit += str_repeat(cnt, 48);
                    }
                    else
                       decimalDigit += m[5] || '';
                    if ( decimalDigit.length > 1 )
                       value += decimalDigit;
                 }
                 else
                    dblValue = intValue;
                 elem.value= value;
              }
              else
                 validatorShowError(invalidErrMsg, elem);
           }
           else
           {
               dblValue = intValue;
               elem.value= intValue;
           }
           if ( min != "" && !isNaN(min= parseFloat(min)) )
           {
              if ( dblValue < min )
                 errorMsg= minErrMsg;
           }
           if ( max != "" && !isNaN(max= parseFloat(max)) )
           {
              if ( dblValue > max )
                 errorMsg= maxErrMsg;
           }
       }
       else
          errorMsg= invalidErrMsg;
   }
   return validatorShowError(errorMsg, elem);
}
function validateRegExp(isValid, fieldName, pattern, flags ,patternErrMsg)
{
   if (setJSVal==0)
	return true;
   var elem,
       value= '',
       errorMsg= false;
   if ( isValid == 'useFieldName' )       // nur validieren?
      value= fieldName;          // dann steht in fieldName der Wert
   else
   {
      if ( !isValid )
         return false;
      elem= validateForm.elements[fieldName];
      if ( !elem )
         return validatorShowInitError('validateRegularExpression -> formular-field not found', true);
      value= elem.value;
   }
   if ( value != "" )
   {
      eval("pattern= /" + pattern.replace(/%22/g, '"').replace(/%27/g, "'") + "/i");
      if ( !value.match(pattern) )
         errorMsg= patternErrMsg;
   }
   return validatorShowError(errorMsg, elem);
}
function validateList(isValid, fieldName, min, minErrMsg, max, maxErrMsg)
{
   if (setJSVal==0)
	   return true;
   var elem,
       value= '',
       errorMsg= false;
   if ( isValid == 'useFieldName' )       // nur validieren?
      value= fieldName;          // dann steht in fieldName der Wert
   else
   {
      if ( !isValid )
         return false;
      elem= validateForm.elements[fieldName];
      if ( !elem )
         return validatorShowInitError('validateSign -> formular-field not found', true);
      value=0
      if ( !elem.type && elem.length )//checkboxes oder radiobutton
      {
		  for ( var i= 0; i < elem.length; i++) 
		     if (elem[i].checked)
			    value++;
 	  }
	  else							  // select oder 1 checkbox oder 1 radiobutton
	  {
	      if ( elem.type.indexOf('select') == 0 )
		  {
			for ( var i= 0; i < elem.length; i++) 
				if (elem[i].selected && elem[i].value != '-')
					value++;
		  }
		  else
		     if ( elem.type.indexOf('text') == 0 )
		     {
				if (elem.value!="")
					value++;
			 }
			 else
		     {
				if (elem.checked)
					value++;
			 }
				
	  }
   }
   if (value<min)
     errorMsg= minErrMsg;
   else if (max>0 && value>max)
       errorMsg= maxErrMsg;
   return validatorShowError(errorMsg, elem[0]);
}

// -------------------------- allgemeine Funktiontn -------------------------------------
// wird von jedem Validator nach der Validation aufgerufen und gibt ggf. die Fehlermeldung
// aus und versucht dann das Element zu fokussieren
// Rückgabewert true oder false
function validatorShowError(errMsg, elem)
{
   if ( !errMsg )
      return true;
   if ( typeof errMsg == 'string' )
      alert(errMsg.replace(/%22/g, '"').replace(/%27/g, "'"));
   if ( elem )
      window.setTimeout("validatorFocusElem('" + elem.name + "')",100);
   return false;
}
function validatorFocusElem(elemName)
{
   var elem= validateForm.elements[elemName];
   if ( !elem )
      return;
   if ( elem.length )
      elem[0].focus();
   else
      elem.focus();
}
function validatorCheckValue(fieldName, value, op, failedValue ,successValue )
{
   var elem= validateForm.elements[fieldName];
   if ( !elem )
      return validatorShowInitError('validatorGetValue -> formular-field "' + fieldName + '"not found', failedValue);
   value= value.replace(/%22/g, '"').replace(/%27/g, "'");
   var allValues= new Array();
   switch ( elem.type )
   {
      case 'select-one':
         if ( elem.selectedIndex >= 0 )
            allValues[allValues.length]= elem.options[elem.selectedIndex].value;
      break;
      case 'select-multiple':
         for (var j= 0; j < elem.length; j++ )
            if ( elem.options[j].selected )
               allValues[allValues.length]= elem.options[j].value;
      break;
      case 'radio':
      case 'checkbox':
         if (elem.checked )
		       allValues[allValues.length]= elem.value;
		break;       
      default:
         if ( elem.length )
         {
	         for ( var i= 0; i < elem.length; i++) 
		         if (elem[i].checked )
		            allValues[allValues.length]= elem[i].value;
		   }
         else
            allValues[allValues.length]= elem.value;
   }
   switch ( op )
   {
      case 'eq': for( var i=0; i < allValues.length; i++) if ( allValues[i] == value ) return successValue; break;
      case 'ne': for( var i=0; i < allValues.length; i++) if ( allValues[i] != value ) return successValue; break;
      case 'c': for( var i=0; i < allValues.length; i++) if ( allValues[i].indexOf(value) >= 0 ) return successValue; break;
      case 'cn': for( var i=0; i < allValues.length; i++) if ( allValues[i].indexOf(value) == -1 ) return successValue; break;
      case 'lt': for( var i=0; i < allValues.length; i++) if ( allValues[i] < value ) return successValue; break;
      case 'le': for( var i=0; i < allValues.length; i++) if ( allValues[i] <= value ) return successValue; break;
      case 'gt': for( var i=0; i < allValues.length; i++) if ( allValues[i] > value ) return successValue; break;
      case 'ge': for( var i=0; i < allValues.length; i++) if ( allValues[i] >= value ) return successValue; break;
      default:
         return validatorShowInitError('validatorGetValue -> invalid op "' + op + '"', failedValue);
   }
   return failedValue;   
}
// wenn ein interner Fehler aufgetreten ist und validatorShowInitErrors= true, wird
// eine Fehlermeldung ausgegeben
function validatorShowInitError(errMsg, returnValue)
{
   if ( validatorShowInitErrors )
      alert(errMsg);
   return returnValue;
}
function str_repeat(cnt, charCode)
{
   charCode= charCode || 32;
   var ret= '';
   for( var i=0; i < cnt; i++)
      ret+= String.fromCharCode(charCode);
   return ret;   
}

