/* form.js (c) by Eduard Gode 28.10.2005

 This module offers functions to
 1. access form values
 2. check form field input
 3. check email addressform input field 'mailfrom' (for mailinglists)
 4. preset form field values

 Include by:
 <script type="text/javascript" scr="/js-pool/wdss/form.js"></script>
*/



// 1. methods to access form field values

function _wdss_funcname(f) {
 var s = f.toString().match(/function (\w*)/)[1];
 if ((s == null) || (s.length==0)) return "anonymous";
 return s;
}
var _wdss_caller;
function _wdss_stacktrace() {
 _wdss_caller = {};
 var s = "";
 for (var a = _wdss_stacktrace.caller; a !=null; a = a.caller) {
   var n = _wdss_funcname(a);
   s += "->" + n + "\n";
   if ( null != _wdss_caller[n] ) return s;
   _wdss_caller[n] = 1;
   if (a.caller == a) {s+="*"; break;}
 }
 return s;
}

function wdss_getFieldValue (field) {
  if ( null == field.type && null != field.item ) field = field.item(0);
  var type = field.type;
  if ( type == 'text' || type == 'textarea' || type == 'password' || type == 'hidden' ) return field.value;
  if ( type == 'radio' ) {
    var form  = field.form;
    var name  = field.name;
    var value = null; 
    for ( var i = 0; i < form.elements.length; i++ ) {
      var f = form.elements[i];
      if ( f.name &&
           f.name == name &&
	   f.type == type &&
	   f.checked ) return f.value;
    }
    return null;
  }
  if ( type == 'select-one' ) {
    var idx = field.selectedIndex;
    if ( 0 > idx ) return null;
    return field.options[idx].value;
  }
  if ( type == 'checkbox' ) {
    return field.checked ? 1 : 0;
  }

  alert("field '"+field.name+"' has unknown type '"+type+"'");
  return null;
}


function wdss_getOptionIndexByValue( field, value ) {
  var type = field.type;
  if ( type == 'select-one' || type == 'select-multiple'   ) {
    for ( var i = 0; i < field.options.length; i++ ) {
      if ( field.options[i].value == value ) return i;
    }
    return -1;
  }
  return null;
}


function wdss_handleDisabledSelectOptions(box,b) {
  if ( null == window.wdss_handleDisabledSelectOptions.last ) window.wdss_handleDisabledSelectOptions.last = {};
  var last = window.wdss_handleDisabledSelectOptions.last;
  var options = box.options;
  if ( 'select-multiple' == box.type ) {
    for ( var i = 0; idx < options.length; idx ++ ) {
      if ( options[i].disabled && options[i].selected ) options[i].selected = false;
    }
  } else {
    var idx = box.selectedIndex;
    if ( null == b ) b = box.id;
    if ( null == b ) b = box.name;
    if ( null != idx && options[idx].disabled ) {
      var n = last[b];
      for ( var i = idx-1; n == null && idx >= 0; idx -- ) {
        if ( !options[i].disabled ) n = i;
      }
      for ( var i = idx+1; n == null && idx < options.length; idx ++ ) {
        if ( !options[i].disabled ) n = i;
      }
      if ( null != n ) {
        last[b] = n;
        box.selectedIndex = n;
        options[idx].selected = false;
        options[n  ].selected = true;
      } else {
        last[b] = null;
        box.selectedIndex = -1;
      }
    } else {
      last[b] = idx;
    }
  }
}


function wdss_setFieldValue (field,value) {
  if ( null == field.type && null != field.item ) field = field.item(0);
  var type = field.type;
  if ( type == 'text' || type == 'textarea' || type == 'password'  || type == 'hidden' ) {
    field.value = value;
  } else if ( type == 'radio' ) {
    var form = field.form;
    var name = field.name;
    for ( var i = 0; i < form.elements.length; i++ ) {
      var f = form.elements[i];
      if ( f.name &&
	   f.name  == name &&
	   f.type  == type &&
           f.value == value ) {
        f.checked = true;
      }
    }
  } else if ( type == 'select-one' ) {
    for ( var i = 0; i < field.options.length; i++ ) {
      var option = field.options[i];
      if ( option.value == value ) {
	option.selected = true;
	field.selectedIndex = i;
      }
    }
  } else if ( type == 'checkbox' ) {
    if ( 'undefined' != typeof(value) ) {
      field.checked = value ? true : false;
    }
  } else {
    alert("field '"+field.name+"' has unknown type '"+type+"' while setting value '"+value+"'\n\nstack2:\n"+_wdss_stacktrace());
    if ( arguments.length > 2 ) alert(arguments[2]);
  }
}


// general helping functions to handle selectboxes 
function wdss_clearSelectBox( field ) {
  while ( field.length ) {
    field.options[field.length-1] = null;
  }
}


function wdss_addSelectOption( field, text, value, defSel, sel ) {
  var newOpt = new Option( text, value, defSel, sel );
  var idx    = field.length;
  field.options[idx] = newOpt;
  if ( defSel ) field.options[idx].defaultSelected = true;
  if ( sel ) {
    field.options[idx].selected = true; // for opera 6
    field.selectedIndex         = idx;  // for opera 5
  }
}


function wdss_delSelectOption( field, value ) {
  var options = field.options;
  for ( i = options.length; i--; ) { if ( options[i].value == value ) options[i] = null; }  
}



// 2. methods to check form field input


// common input type patterns
var _form_patTLD           = '[a-z]{2,4}';
var _form_patHOSTNAME      = '[a-zA-Z\\d\\-]+';
var _form_patHOSTNAME_IDNA = '[a-zA-Z\\d\\-äöüÄÖÜß]+';
var _form_patDOMAIN        = _form_patHOSTNAME+     '(\\.'+_form_patHOSTNAME+     ')*\\.'+_form_patTLD;
var _form_patDOMAIN_IDNA   = _form_patHOSTNAME_IDNA+'(\\.'+_form_patHOSTNAME_IDNA+')*\\.'+_form_patTLD;
var _form_patUSERNAME      = '[\\w\\-\\.]+';  

// standard check patterns
var _form_chkEMAIL_Pattern      = '^'+_form_patUSERNAME+'\\@'+_form_patDOMAIN     +'$';
var _form_chkEMAIL_IDNA_Pattern = '^'+_form_patUSERNAME+'\\@'+_form_patDOMAIN_IDNA+'$';
//var _form_chkINTEGER_Pattern    = /^(\+|\-)?\d+$/;
//var _form_chkZIP_DE_Pattern     = /^\d{5}$/;

var _form_patternNames = {
  DOMAINNAME:      '^'+_form_patDOMAIN     +'$',
  DOMAINNAME_IDNA: '^'+_form_patDOMAIN_IDNA+'$',
  EMAIL:           _form_chkEMAIL_Pattern,
  EMAIL_IDNA:      _form_chkEMAIL_IDNA_Pattern,
  REAL:            /^(\+|\-)?\d*((\.|,)\d+)?((E|e)(\+|-)?\d+)?$/,
  INTEGER:         /^(\+|\-)?\d+$/,
  POSITIVE:        /^\d+$/,
  CURRENCY:        /^\d+(\.\d\d\d)*(,\d\d)?|\d+(\,\d\d\d)*(.\d\d)?$/,
  CURRENCY_DE:     /^\d+(\.\d\d\d)*(,\d\d)?$/,
  CURRENCY_EN:     /^\d+(\,\d\d\d)*(.\d\d)?$/,
  DATE_DE:         /^\d{1,2}\.\d{1,2}\.\d\d\d\d$/,
  ZIP:             /^\S$/,
  ZIP_DE:          /^\d{5}$/,
  STRING:          /\S/
}

// Examples:
//
//function checkForm() {
//  var form = document.formName;
//  var def = [ //formFieldDefinitions:
//              // name       mandatory, pattern, errorMand, errorPat
//              [ fieldname1, true       INTEGER, 'fieldname1 ist nicht ausgefuellt!', 'fieldname1 ist falsch!' ],
//              [ fieldname2, true       INTEGER, 'fieldname1 ist nicht ausgefuellt!', 'fieldname1 ist falsch!' ],
//              ...
//            ];
//  return checkFormFields(form,defs);
//  or:
//  return false if !checkFormField(form.fieldname1,'fieldname1 ist nicht ausgefuellt!', 'INTEGER', 'fieldname1 ist falsch!' );
//  return false if !checkFormField(form.fieldname1,'fieldname1 ist nicht ausgefuellt!', 'INTEGER', 'fieldname1 ist falsch!' );
//  return true;
//}
// <form onsubmit="return checkForm()">
// ..
function wdss_checkFormField (field,errorMand,pattern,errorPat) {
  var value = wdss_getFieldValue(field);
  var error = null;
  if ( value == null || !value.toString().match(/\S/) ) {
    if ( errorMand ) error = errorMand;
  } else {
    if ( pattern ) {
      if ( 'string' == typeof(pattern) ) {
        var p = _form_patternNames[pattern];
	if ( p ) pattern = p;
      }
      if ( !value.toString().match( pattern ) ) error = errorPat;
    }
  }
  if ( error ) {
    alert( error );
    field.focus();
    return false;
  }
  return true;
}


function sprintf(format,arg) {
  return format.replace(/%s/,arg);
}
function wdss_checkFormFields (form,defs,args) {
  if ( null == args ) args = {};
  if ( null == args.ERR_FORMAT_MANDATORY ) args.ERR_FORMAT_MANDATORY = 'Bitte füllen Sie das Feld %s aus!';
  if ( null == args.ERR_FORMAT_PATTERN   ) args.ERR_FORMAT_PATTERN   = 'Fehler in Feld %s!';

  var handledRadios = {};
  for ( var i = 0; i < form.elements.length; i++ ) {
    var field = form.elements[i];
    var def   = defs[field.name];
    if ( field.type == 'radio' ) {
      if ( handledRadios[field.name] ) continue;
      handledRadios[field.name] = true;
      // field.form = form;
    }
    if ( null != def )  {
      var name      = def[0];
      var mandatory = def[1];
      var pattern   = def[2];
      var errorMand = null;
      var errorPat  = null;
      if ( mandatory ) errorMand = sprintf( args.ERR_FORMAT_MANDATORY, name );
      if ( pattern   ) errorPat  = sprintf( args.ERR_FORMAT_PATTERN,   name );
      if ( !wdss_checkFormField(field,errorMand,pattern,errorPat) ) return false;
    }
  }
  return true;
}


	

// 3. check email addressform input field (for mailinglists)
//
// Examples:
// * <form name="mlist" ... onsubmit="return checkEMailFormField(document.mlist.address)">
// * <form name="mlist" ... onsubmit="return checkEMailFormField(document.mlist.address,'E-Mail')">
function wdss_checkEMailFormField(field,optFieldName) {
  var errorMand = 'Bitte geben Sie Ihre E-Mail-Adresse an!';
  var errorPat  = 'Das E-Mail-Adressfeld enthält keine gültige E-Mail-Adresse. Bitte korrigieren Sie dieses!';
  if ( null != optFieldName ) {
    errorMand = "Bitte füllen Sie das Feld '"+optFieldName+"' aus!"
    errorPat  = "Das Feld '"+optFieldName+"' enthält keine gültige E-Mail-Adresse. Bitte korrigieren Sie dieses!";
  }
  return wdss_checkFormField(field,errorMand,_form_chkEMAIL_IDNA_Pattern,errorPat);
}



// 4. methods to preset form field values

// internal function!
// returns first field for radio button groups
function wdss_getFormField (form,name) {
  var field = form[name];
//alert( name+": length = "+field.length );
//alert( name+": type = "+field.type );
  if ( field && !field.type && field.length ) return field[0];
  return field;
}

// internal data destination and base data access functions
function _getPresetStorage () {
  var win = window.top;
  if ( !win || win == window ) win = window.parent;
  if ( !win._presetStorage_ ) win._presetStorage_ = {};
  return win._presetStorage_;
}
function _storePresetValues (form,defs) { var s = _getPresetStorage(); s[form.name] = defs; }
function _readPresetValues (form) { var s = _getPresetStorage(); return s[form.name]; }


function wdss_setFormPresetValues (form,values) {
  _storePresetValues(form,values);
}

function wdss_saveFormPresetValues (form,fieldnames) {
  var defs = {};

  if ( !fieldnames ) {
    fieldnames = [];
    var names = {};
    for ( var i = 0; i < form.elements.length; i++ ) {
      var field = form.elements[i];
      if ( field ) {
        var name = field.name;
	var type = field.type;
        if ( type && type.match( /^(text|textarea|password|radio|checkbox|select-one)$/ ) ) {
          //alert( name + ' : ' + type );
          if ( !names[name] ) {
            fieldnames[fieldnames.length] = name;
	    names[name] = 1;
          }
        }
      }
    }
    //alert( "fieldnames: "+fieldnames );
  }

  for ( var i = 0; i < fieldnames.length; i++ ) {
    var name  = fieldnames[i];
    var field = wdss_getFormField(form,name);
    if ( !field ) alert( "could not find field '"+name+"'");
     defs[name] = wdss_getFieldValue(field);
  }

  _storePresetValues(form,defs);
}

function wdss_presetFormFields (form,fieldnames) {
  var defs = _readPresetValues(form);
  
  if ( !fieldnames ) {
    fieldnames = [];
    for ( var name in defs ) {
      fieldnames[fieldnames.length] = name;
    }
    //alert( "fieldnames: "+fieldnames );
  }

  for ( var i = 0; i < fieldnames.length; i++ ) {
    var name  = fieldnames[i];
    var field = wdss_getFormField(form,name);
    if ( !field ) alert( "could not find field '"+name+"'");
    var val = wdss_getFieldValue(field);
    if ( val == null || val == '' ) {
      val = defs[name];
      if ( 'undefined' != typeof(val) ) wdss_setFieldValue(field,val);
    }
  }
}


/* 3. */
function wdss_openTarget(url,target,method,params) {
  //alert('open('+url+','+target+','+method+')');
  if ( null == method || !method.match(/^get$/i) ) method = 'post';
  var form = document.createElement('form');
  if ( null != url    ) form.setAttribute('action',url);
  if ( null != target ) form.setAttribute('target',target);
  form.setAttribute('method',method);
  form.setAttribute('enctype','multipart/form-data');
  for ( var name in params ) {
    var node = document.createElement('input');
    node.setAttribute('type','hidden');
    node.setAttribute('name',name);
    node.setAttribute('value',params[name]);
    form.appendChild(node); 
  }
  document.getElementsByTagName('body')[0].appendChild(form); 
  form.submit();
}



// compatibility
window.getFieldValue         = wdss_getFieldValue;
window.setFieldValue         = wdss_setFieldValue;
window.getOptionIndexByValue = wdss_getOptionIndexByValue;
window.clearSelectBox        = wdss_clearSelectBox;
window.addSelectOption       = wdss_addSelectOption;
window._wdss_getFieldValue         = wdss_getFieldValue;
window._wdss_getOptionIndexByValue = wdss_getOptionIndexByValue;
window._wdss_setFieldValue         = wdss_setFieldValue;
window._wdss_clearSelectBox        = wdss_clearSelectBox;
window._wdss_addSelectOption       = wdss_addSelectOption;
window._wdss_openTarget            = wdss_openTarget;
window.checkFormField              = wdss_checkFormField;
window.checkFormFields             = wdss_checkFormFields;
window.checkEMailFormField         = wdss_checkEMailFormField;
window.getFormField                = wdss_getFormField;
window.setFormPresetValues         = wdss_setFormPresetValues;
window.saveFormPresetValues        = wdss_saveFormPresetValues;
window.presetFormFields            = wdss_presetFormFields;

