// HEADER START
// This file is part of the wdss system.
// Author: Eduard Gode
// Copyright by the author
// Copying, distribution, inclusion (execution) without explicit permission is denied.
// Permissions granted to <wdss> websites of customers of:
//    Weitblick Internetwerkstatt, Erhard Klein or
//    Weitblick <wdss> Services, Eduard Gode
//
// Coding conventions:
// * All functions, methods and data has to be coded within the global object WDSS
// * All functions, methods and data named with a stating '_' is internal and may be change in future revisions 
if(null==window.WDSS)window.WDSS={module:{},requireModule:function(m){if(!this.module[m]){this.module[m]=1;document.write('<script type="text/javascript" src="/js-pool/wdss/'+m+'.js"></script>');}}};
// HEADER END

// WDSS.requireModule('form');

WDSS.module.form = '$Revision: 1.46 $';


//#####################################################

if ( null == WDSS.form ) {

  WDSS.form = {};

/*
 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;
  }


  WDSS.form.getFieldValue = function (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;
  };


  WDSS.form.getOptionIndexByValue = function ( 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;
  };


  WDSS.form.handleDisabledSelectOptions = function ( box, b ) {
    if ( null == WDSS.form.handleDisabledSelectOptions.last ) WDSS.form.handleDisabledSelectOptions.last = {};
    var last = WDSS.form.handleDisabledSelectOptions.last;
    var ret = false;
    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;
	  ret = true;
	}
      }
    } else {
      var idx = box.selectedIndex;
      if ( null == b ) b = box.id;
      if ( null == b ) b = box.name;
      if ( null != idx && options[idx].disabled ) {
	ret = true;
	var n = null;
	if ( !options[last[b]].disabled ) 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;
      }
    }
    return ret;
  };


  WDSS.form.setFieldValue = function ( 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 

  WDSS.form.clearSelectBox = function ( field ) {
    while ( field.length ) {
      field.options[field.length-1] = null;
    }
  };


  WDSS.form.addSelectOption = function ( 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
    }
  };


  WDSS.form.delSelectOption = function ( 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}$/;

  WDSS.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 WDSS.form.checkFormFields(form,defs);
  //  or:
  //  return false if !WDSS.form.checkFormField(form.fieldname1,'fieldname1 ist nicht ausgefuellt!', 'INTEGER', 'fieldname1 ist falsch!' );
  //  return false if !WDSS.form.checkFormField(form.fieldname1,'fieldname1 ist nicht ausgefuellt!', 'INTEGER', 'fieldname1 ist falsch!' );
  //  return true;
  //}
  // <form onsubmit="return checkForm()">
  // ..
  WDSS.form.checkFormField = function (field,errorMand,pattern,errorPat) {
    var value = WDSS.form.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 = WDSS.form.patternNames[pattern];
	  if ( p ) pattern = p;
        }
        if ( !value.toString().match( pattern ) ) error = errorPat;
      }
    }
    if ( error ) {
      alert( error );
      field.focus();
      return false;
    }
    return true;
  };


  var sprintf = function (format,arg) {
    return format.replace(/%s/,arg);
  };


  WDSS.form.checkFormFields = function (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.form.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')">
  WDSS.form.checkEMailFormField = function (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.form.checkFormField(field,errorMand,_form_chkEMAIL_IDNA_Pattern,errorPat);
  };



  // 4. methods to preset form field values

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

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


  WDSS.form.setFormPresetValues = function (form,values) {
    _storePresetValues(form,values);
  };

  WDSS.form.saveFormPresetValues = function (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 = _getFormField(form,name);
      if ( !field ) alert( "could not find field '"+name+"'");
      defs[name] = WDSS.form.getFieldValue(field);
    };

    _storePresetValues(form,defs);
  };

  WDSS.form.presetFormFields = function (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 = _getFormField(form,name);
      if ( !field ) alert( "could not find field '"+name+"'");
      var val = WDSS.form.getFieldValue(field);
      if ( val == null || val == '' ) {
        val = defs[name];
        if ( 'undefined' != typeof(val) ) WDSS.form.setFieldValue(field,val);
      }
    }
  };

}


// compatibility functions
window._wdss_getFieldValue         = WDSS.form.getFieldValue;
window._wdss_setFieldValue         = WDSS.form.setFieldValue;
window._wdss_getOptionIndexByValue = WDSS.form.getOptionIndexByValue;
window._wdss_clearSelectBox        = WDSS.form.clearSelectBox;
window._wdss_addSelectOption       = WDSS.form.addSelectOption;
window._wdss_handleDisabledSelectOptions = WDSS.form.handleDisabledSelectOptions;

window.wdss_getFieldValue         = WDSS.form.getFieldValue;
window.wdss_setFieldValue         = WDSS.form.setFieldValue;
window.wdss_getOptionIndexByValue = WDSS.form.getOptionIndexByValue;
window.wdss_clearSelectBox        = WDSS.form.clearSelectBox;
window.wdss_addSelectOption       = WDSS.form.addSelectOption;
window.wdss_handleDisabledSelectOptions = WDSS.form.handleDisabledSelectOptions;

window.getFieldValue               = WDSS.form.getFieldValue;
window.setFieldValue               = WDSS.form.setFieldValue;
window.getOptionIndexByValue       = WDSS.form.getOptionIndexByValue;
window.clearSelectBox              = WDSS.form.clearSelectBox;
window.addSelectOption             = WDSS.form.addSelectOption;

	
window.wdss_checkFormField         = WDSS.form.checkFormField;
window.wdss_checkFormFields        = WDSS.form.checkFormFields;

window.checkFormField              = WDSS.form.checkFormField;
window.checkFormFields             = WDSS.form.checkFormFields;


window.wdss_checkEMailFormField    = WDSS.form.checkEMailFormField;

window.checkEMailFormField         = WDSS.form.checkEMailFormField;


window.setFormPresetValues         = WDSS.form.setFormPresetValues;
window.saveFormPresetValues        = WDSS.form.saveFormPresetValues;
window.presetFormFields            = WDSS.form.presetFormFields;

window.wdss_setFormPresetValues    = WDSS.form.setFormPresetValues;
window.wdss_saveFormPresetValues   = WDSS.form.saveFormPresetValues;
window.wdss_presetFormFields       = WDSS.form.presetFormFields;



/* 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._wdss_openTarget            = wdss_openTarget;


