//v1.0
//utils form

/* Próby dodania toString
function getName() {
  return this.name;
}
HTMLInputElement.prototype.toString = getName();
*/

function UtilsForm(id, formName, formRegAlerts, toplayerId) {
  this.debug = false;
  this.id = id;
  this.formName = formName;
  this.formRegAlerts = formRegAlerts;
  this.form = document.forms[formName];
  this.toplayerId = (toplayerId == undefined ? false : toplayerId);
  this.uniqueElements = new Array();
  
  this.uniqueCheckURL = 'index.php?page=sprawdz_pola';
  this.uniqueCheckParamNames = 'name[]';
  this.uniqueCheckParamValues = 'value[]';
  this.repeatedNameSuffix = '_Repeat';
  this.classNameObligatory = 'obligatory';
  this.classNameOptional = 'optional';
  this.classNameUnique = 'unique';
  this.classNameHiddenValue = 'hiddenValue';
  this.classNameMissing = 'missing';
  this.classNameError = 'error';
  this.classNameDuplicated = 'duplicated';
  this.classNameMisrepeated = 'misrepeated';
  this.classNameAlert = 'alert';
  this.fieldValueNl = '<br />';
  this.valueSeparator = '|';
  this.timeoutAlert = 3000;
  this.errorAlert = false;
  this.helpTexts = false;
  this.sep1 = "#|#|#";
  this.sep2 = "#=#=#";
  this.sep1c = "";
  this.sep2c = "";

  this.packFormParamName = null; // Jeśli ma wartość różną od null, to cały formularz pakuje do parametru o tej nazwie
  this.ajaxSubmit = true;
  this.finalAsAlert = false;
  this.valid = true;
  this.checking = false;
  this.checkAndSubmitAlrt = null;

  this.nop = nop;
  this.init = init;
  this.initAlerts = initAlerts;
  this.setUpUniques = setUpUniques;
  this.fieldValue = fieldValue;
  this.checkField = checkField;
  this.checkAndSubmit = checkAndSubmit;
  this.checkUnique = checkUnique;
  this.fillRelativeSelect = fillRelativeSelect;
  this.addSameField = addSameField;
  this.initValues = initValues;
  this.packForm = packForm;
  this.encodeForSend = encodeForSend;
  this.initInfoRemainingLength = initInfoRemainingLength;
  this.guardLength = guardLength;

//nic
  function nop() {}

//inicjuje formularz
  function init() {
    var n;
    this.initAlerts();
    this.setUpUniques();
    for(var i = 0; i < this.form.elements.length; i++) {
      n = this.form.elements[i];
      if(n.tagName.toLowerCase() == 'textarea')
        this.initInfoRemainingLength(n);
    }
    if(this.helpTexts && this.helpTexts.length > 1) {
      n = 0;
      while(this.helpTexts[n] != 0) {
        var help = document.createElement('div');
        help.className = 'help';
        help.innerHTML = this.helpTexts[n+1];
        var element = this.form.elements[this.helpTexts[n]];
        if(element && element.length > 0)
          element = element[0];
        while(element && (!element.className || (element.className.indexOf(this.classNameObligatory) == -1 && element.className.indexOf(this.classNameOptional) == -1)))
          element = element.parentNode;
        if(element)
          element.insertBefore(help, element.childNodes[0]);
        n += 2;
      }
    }
  }

//inicjuje pola komunikatów w formularzu
  function initAlerts() {
    if(this.formRegAlerts != undefined) {
      var divs = this.form.getElementsByTagName('div');
      for(var i = 0; i < divs.length; i++)
        for(var j = 0; j < 2*Math.floor(formRegAlerts.length/2); j+=2)
          if(divs[i].className == formRegAlerts[j] && divs[i].innerHTML == '')
            divs[i].innerHTML = formRegAlerts[j+1];
    }
  }

//inicjuje pola komunikatów w formularzu
  function setUpUniques() {
    this.uniqueElements = new Array();
    for(var i = 0; i < this.form.elements.length; i++) {
      n = this.form.elements[i];
      while(n = getParentTag(n, 'div'))
        if(n.className.indexOf(this.classNameObligatory) == 0 || n.className.indexOf(this.classNameOptional) == 0) {
          if(n.className.indexOf(this.classNameUnique) != -1) {
            if(n.className.indexOf(this.classNameHiddenValue) == -1) {
              this.uniqueElements[this.uniqueElements.length] = this.form.elements[i];
            } else if(this.form.elements[i].tagName.toLowerCase() == 'input' && this.form.elements[i].type.toLowerCase() == 'hidden') {
              this.uniqueElements[this.uniqueElements.length] = this.form.elements[i];
            }
          }
          break;
        }
    }
  }

//zwraca wartość pola do podsumowania
  function fieldValue(f, getText) {
    try {
      if(this.form.elements[f] != undefined)
        f = this.form.elements[f];
    } catch(ex) {}
    try {
      if(f.tagName.toLowerCase() == 'input') {
        if(f.type.toLowerCase() == 'radio')
          return radioValue(this, f, getText);
        else if(f.type.toLowerCase() == 'checkbox') {
          return checkboxValue(this, f, getText);
        } else if(f.type.toLowerCase() == 'text')
          return textValue(this, f, getText);
        else if(f.type.toLowerCase() == 'password')
          return textValue(this, f, getText);
        else if(f.type.toLowerCase() == 'file')
          return textValue(this, f, getText);
      } else if(f.tagName.toLowerCase() == 'select') {
        return selectValue(this, f, getText);
      } else if(f.tagName.toLowerCase() == 'textarea') {
        return textareaValue(this, f, getText);
      } else {
        return null;
      }
    } catch(ex) {
      if(this.debug) alert('fieldValue('+f+','+getText+')\n'+ex);
      return null;
    }
  }

//sprawdza poprawność wypełnienia pola
  function checkField(f) {
    var n;
    try {
      if(this.form.elements[f] != undefined)
        f = this.form.elements[f];
    } catch(ex) {}
  //  try {
      var valid = true;
      var misrepeated = false;
      if(f.tagName.toLowerCase() == 'input') {
        if(f.type.toLowerCase() == 'radio')
          valid = radioValue(this, f);
        else if(f.type.toLowerCase() == 'checkbox')
          valid = checkboxValue(this, f);
        else if(f.type.toLowerCase() == 'text')
          valid = textValue(this, f);
        else if(f.type.toLowerCase() == 'password')
          valid = textValue(this, f);
        else if(f.type.toLowerCase() == 'hidden')
          valid = textValue(this, f);
        else if(f.type.toLowerCase() == 'file')
          valid = textValue(this, f);
      } else if(f.tagName.toLowerCase() == 'select') {
        valid = selectValue(this, f);
      } else if(f.tagName.toLowerCase() == 'textarea') {
        valid = textareaValue(this, f);
      }
      if(valid
        && f.name.length > this.repeatedNameSuffix.length
        && f.name.substr(f.name.length - this.repeatedNameSuffix.length) == this.repeatedNameSuffix
        && f.form.elements[f.name.replace(this.repeatedNameSuffix, '')]
        && f.value != f.form.elements[f.name.replace(this.repeatedNameSuffix, '')].value)
          misrepeated = true;
      if(!valid || misrepeated) {
        this.valid = false;
        n = f;
        while(n = getParentTag(n, 'div'))
          if(misrepeated && (n.className.indexOf(this.classNameObligatory) == 0 || n.className.indexOf(this.classNameOptional) == 0)) {
            n.className = getCleanClassName(this, n)+' '+this.classNameMisrepeated;
            break;
          } else if(n.className.indexOf(this.classNameObligatory) == 0) {
            if(this.fieldValue(f, true))
              n.className = getCleanClassName(this, n)+' '+this.classNameError;
            else
              n.className = getCleanClassName(this, n)+' '+this.classNameMissing;
            break;
          } else if(n.className.indexOf(this.classNameOptional) == 0) {
            n.className = getCleanClassName(this, n)+' '+this.classNameError;
            break;
          }
      } else {
        n = f;
        while(n = getParentTag(n, 'div'))
          if(n.className.indexOf(this.classNameObligatory) == 0 || n.className.indexOf(this.classNameOptional) == 0) {
            if(n.className.indexOf(this.classNameDuplicated) != -1)
              this.valid = false;
            n.className = getCleanClassName(this, n);
            break;
          }
      }
/*
    } catch(ex) {
      if(this.debug) {
        var fieldInfo = null;
        try { fieldInfo = getHTMLInputElementInfo(f); } catch (ex2) { }
        if (fieldInfo==null) fieldInfo = f;
         alert('checkField('+fieldInfo+')\n'+ex);
      }
    }
*/
  }

//sprawdza poprawność wypełnienia formularza i wysyła jeśli formularz poprawny
  function checkAndSubmit(alrt) {
    if(this.checking) {
      this.checking = false;
      alrt = this.checkAndSubmitAlrt;
    } else {
      this.checkAndSubmitAlrt = alrt;
    }
    if(this.uniqueElements.length > 0) {
      var unique = this.uniqueElements.shift();
      try {
        this.checking = true;
        eval(unique.name+'UniqueCheck();');
      } catch(ex) {
        if(unique.tagName.toLowerCase() == 'select') {
          this.checking = true;
          this.checkUnique([unique.name], [unique.options[unique.selectedIndex].value]);
        } else if(unique.tagName.toLowerCase() == 'input' && unique.type.toLowerCase() == 'text') {
          this.checking = true;
          this.checkUnique([unique.name], [unique.value]);
        } else if(unique.tagName.toLowerCase() == 'textarea') {
          this.checking = true;
          this.checkUnique([unique.name], [unique.value]);
        }
      }
    } else {
      this.setUpUniques();
      var en = this.valueSeparator;
      if(alrt != undefined && !alrt)
        this.finalAsAlert = false;
      this.valid = true;
      for(var i = 0; i < this.form.elements.length; i++)
        if(en.indexOf(this.valueSeparator+this.form.elements[i].name+this.valueSeparator != -1)) {
          en += this.form.elements[i].name+this.valueSeparator;
          this.checkField(this.form.elements[i]);
        }
      if(this.valid) {
        if(this.ajaxSubmit)
          advAJAX.submit(this.form, {
            tag: this
            , onSuccess: function(obj) {
              try {
                if(obj.tag.finalAsAlert) {
                  alert(obj.responseText.replace(/<[^>]+>/g, ''));
                } else {
                  var alrt = document.createElement('div');
                  alrt.id = obj.tag.id+'Alert';
                  alrt.className = obj.tag.classNameAlert;
                  alrt.innerHTML = obj.responseText;
                  document.body.appendChild(alrt);
                  alrt.style.left = ((document.all?document.documentElement.clientWidth:window.innerWidth) - alrt.offsetWidth) / 2 + 'px';
                  alrt.style.top = ((document.all?document.documentElement.clientHeight:window.innerHeight) - alrt.offsetHeight) / 2 + 'px';
                  alrt.style.visibility = 'visible';
                  setTimeout('document.body.removeChild(document.getElementById("'+alrt.id+'"));', obj.tag.timeoutAlert);
                }
                if(obj.tag.toplayerId)
                  eval(obj.tag.toplayerId+'.destroy(true);');
              } catch(ex) {}
            }
            , onError: function(obj) { try { alert('Błąd: ' + obj.status); } catch(ex) {} }
          });
        else {
          if(this.packFormParamName == null)
            try {
              eval(this.formName + 'Submit();');
            } catch(ex) {
              this.form.submit();
            }
          else {
            var submitForm = document.createElement('form');
            var inputElem = document.createElement('input');
            inputElem.name = this.packFormParamName;
            inputElem.value = this.packForm();
            submitForm.appendChild(inputElem);
            submitForm.method = this.form.method;
            submitForm.action = this.form.action;
            document.body.appendChild(submitForm);
            submitForm.submit();
          }
        }
      } else if(this.errorAlert) {
        alert(this.errorAlert);
      }
    }
  }

//sprawdzanie unikalności pola
  function checkUnique(n, v, noPl, excId) {
    if(n && v && n.length == v.length) {
      var url = this.uniqueCheckURL;
      var vc = '';
      for(var i = 0; i < n.length; i++) {
        url += '&'+this.uniqueCheckParamNames+'='+n[i];
        url += '&'+this.uniqueCheckParamValues+'='+v[i];
        if(noPl == undefined)
          url += '&_noPl[]=0';
        else
          url += '&_noPl[]='+(noPl[i] ? '1' : '0');
        if(excId == undefined)
          url += '&_excId[]=0';
        else
          url += '&_excId[]='+(excId[i] ? excId[i] : '0');
        vc += v[i];
      }
      if(vc != '') {
        disableForm(this);
        advAJAX.get ({
          url : url
          , tag : this
          , parameters : {
            '_name' : n[0]
          }
          , onSuccess: function(obj) {
            try {
              var n = obj.tag.form.elements[obj.parameters._name];
              while(n = getParentTag(n, 'div'))
                if(n.className.indexOf(obj.tag.classNameObligatory) == 0 || n.className.indexOf(obj.tag.classNameOptional) == 0) {
                  if(obj.responseText > 0) {
                    n.className = getCleanClassName(obj.tag, n)+' '+obj.tag.classNameDuplicated;
                  } else {
                    n.className = getCleanClassName(obj.tag, n).replace(new RegExp(' ' + obj.tag.classNameDuplicated, 'g'), '');
                  }
                  break;
                }
              enableForm(obj.tag);
              var i = obj.tag.form.elements.length - 1;
              while(--i >= 0)
                if(obj.parameters._name == obj.tag.form.elements[i].name) {
                  obj.tag.form.elements[i+1].blur();
                  obj.tag.form.elements[i+1].focus();
                }
            } catch(ex) {}
            if(obj.tag.checking)
              obj.tag.checkAndSubmit(obj.tag.checkAndSubmitAlrt);
          }
          , onError: function(obj) {
            try {
              alert('Błąd: ' + obj.status);
              enableForm(obj.tag);
            } catch(ex) {}
          }
        });
      } else {
        n = this.form.elements[n[0]];
        while(n = getParentTag(n, 'div'))
          if(n.className.indexOf(this.classNameObligatory) == 0 || n.className.indexOf(this.classNameOptional) == 0) {
            n.className = getCleanClassName(this, n);
            break;
          }
        if(this.checking)
          this.checkAndSubmit(this.checkAndSubmitAlrt);
      }
    }
  }

//wypełnia zależny select opcjami
function fillRelativeSelect(o, n, d) {
  n = this.form.elements[n];
  if(n) {
    var s = n.options[n.selectedIndex].value;
    n.options.length = 1;
    var i = 0;
    while(d[i] != 0) {
      if(d[i] == o.options[o.selectedIndex].value) {
        n.options[n.options.length] = new Option(d[i+2], d[i+1]);
        if(d[i+1] == s)
          n.options[n.options.length - 1].selected = true;
      }
      i += 3;
    }
    
  }
}

//dodaje takie samo pole
function addSameField(o, m) {
  var add = 0;
  var c = 0;
  if(o.value == '')
    add++;
  for(var i = 0; i < this.form.elements.length; i++)
    if(this.form.elements[i].name == o.name) {
      if(this.form.elements[i].value == '' && this.form.elements[i] != o) {
        add++;
        if(add > 1)
          o.parentNode.removeChild(this.form.elements[i]);
        else
          c++;
      } else {
        c++;
      }
    }
  if(add == 0 && c < m) {
    add = document.createElement(o.tagName.toLowerCase());
    add.type = o.type;
    add.name = o.name;
    add.size = o.size;
    add.className = o.className;
    add.onchange = o.onchange;
    o.parentNode.appendChild(add);
  }
}

//inicjalizacja wartości
function initValues(v) {
  var i = 0;
  var e;
  if(v) {
    while(i < v.length) {
      e = this.form.elements[v[i++]];
      if(e) {
        if(e.length && e.length > 0) {
          if(e.tagName) {
            if(e.tagName.toLowerCase() == 'select') {
              for(var j = 0; j < e.options.length; j++)
                if((','+v[i]+',').indexOf(','+e.options[j].value+',') != -1)
                  e.options[j].selected = true;
            }
          } else if(e[0].tagName) {
            if(e[0].tagName.toLowerCase() == 'input') {
              if(e[0].type.toLowerCase() == 'radio') {
                if(!e.length) {
                  if((','+v[i]+',').indexOf(','+e.value+',') != -1)
                    e.checked = true;
                } else {
                  for(var j = 0; j < e.length; j++)
                    if((','+v[i]+',').indexOf(','+e[j].value+',') != -1)
                      e[j].checked = true;
                }
              } else if(e[0].type.toLowerCase() == 'checkbox') {
                if(!e.length) {
                  if((','+v[i]+',').indexOf(','+e.value+',') != -1)
                    e.checked = true;
                } else {
                  for(var j = 0; j < e.length; j++)
                    if((','+v[i]+',').indexOf(','+e[j].value+',') != -1)
                      e[j].checked = true;
                }
              }
            }
          }
        } else {
          if(e.tagName.toLowerCase() == 'input') {
            if(e.type.toLowerCase() == 'text') {
              e.value = v[i];
            } else if(e.type.toLowerCase() == 'hidden') {
              e.value = v[i];
            }
          } else if(e.tagName.toLowerCase() == 'textarea') {
            e.value = v[i];
          }
        }
      }
      i++;
    }
  }
}

//inicjalizacja licznika znaków
function initInfoRemainingLength(t) {
  var o = document.getElementById(t.name + 'InfoRemainingLength');
  if(o && o.innerHTML && !isNaN(o.innerHTML)) {
    if(!t.onkeyup)
      t.onkeyup = new Function(this.id + '.guardLength(this, ' + o.innerHTML + ');');
    if(t.value != '')
      o.innerHTML = parseFloat(o.innerHTML) - t.value.length;
  }
}

//ograniczanie długości pól do wpisywania
function guardLength(o, l) {
  if(o.value.length > l)
    o.value = o.value.substr(0, l);
  try {
    document.getElementById(o.name + 'InfoRemainingLength').innerHTML = l - o.value.length;
  } catch(ex) {}
  try {
    document.getElementById(o.name + 'InfoWrittenLength').innerHTML = o.value.length;
  } catch(ex) {}
}

// prywatne --------------------------------------------
//zwraca wartość dla wybranego radio lub false jeżeli niewybrane
  function radioValue(o, f, getText) {
    var v = false;
    f = o.form.elements[f.name];
    for(var i = 0; i < f.length; i++)
      if(f[i].checked)
        if(getText != undefined && getText)
          v = f[i].title;
        else
          v = f[i].value;
    return getText!=undefined ? v : obligatoryValue(o, f, v);
  }
  
//zwraca wartości dla wybranych checkboxów lub false jeżeli niewybrane
  function checkboxValue(o, f, getText) {
//alert('checkboxValue() BEGIN '||f.name);
    var v = '';
    f = o.form.elements[f.name];
    if(f.length == undefined) {
      if(f.checked) {
        if(getText != undefined && getText)
          v = f.title;
        else
          v = f.value;
      }
    } else {
      for(var i = 0; i < f.length; i++)
        if(f[i].checked) {
          if(getText != undefined && getText) {
            v += (v==''?'':o.fieldValueNl) + f[i].title;
          } else {
            v += (v==''?'':o.valueSeparator) + f[i].value;
          }
        }
    }
    var retVal = getText!=undefined ? (v==''?false:v) : obligatoryValue(o, f, v==''?false:v);
//alert('checkboxValue() END '||retVal);
    return retVal;
  }
  
//zwraca wartość dla wybranego selecta lub false jeżeli niewybrany
  function selectValue(o, f, getText) {
    var v = false;
    f = o.form.elements[f.name];
    if(f.options[f.selectedIndex].value != '')
      if(getText != undefined && getText)
        v = f.options[f.selectedIndex].text;
      else
        v = f.options[f.selectedIndex].value;
    return getText!=undefined ? v:obligatoryValue(o, f, v);
  }
  
//zwraca wartość dla wybranego input text lub false jeżeli pusty
  function textValue(o, f, getText) {
    var v = false;
    if(f.value.length != 0)
      v = f.value;
    return getText!=undefined ? v : obligatoryValue(o, f, v);
  }

//zwraca wartość dla wybranego textarea lub false jeżeli pusty
  function textareaValue(o, f, getText) {
    var v = false;
    if(f.value.length != 0)
      v = f.value;
    return getText!=undefined&&getText?v:obligatoryValue(o, f, v);
  }

//zwraca false jeśli pole jest obowiązkowe i puste
  function obligatoryValue(o, f, v) {
    var n = f;
    if(n.length != undefined)
      n = n[0];
    while(n = getParentTag(n, 'div'))
      if(n.className.indexOf(o.classNameObligatory) == 0) {
        if(!v)
          return false;
        break;
      } else if(n.className.indexOf(o.classNameOptional) == 0) {
        break;
      }
    if(v != false) {
      try {
        if(!eval(f.name.replace(/[\[\]]/g, '')+'RE').test(v))
          return false;
      } catch(ex) {}
      try {
        if(!eval(f.name.replace(/[\[\]]/g, '')+'Validate("'+v+'");'))
          return false;
      } catch(ex) {}
    }
    return true;
  }

//parent tag 'tag' węzła n
  function getParentTag(n, tag) {
    if(n == null || n.parentNode == undefined) return null;
    n = n.parentNode;
    while(n.parentNode != undefined && n.nodeName.toLowerCase() != tag.toLowerCase())
      n = n.parentNode;
    return (n.nodeName != undefined && n.nodeName.toLowerCase() == tag.toLowerCase())?n:null;
  }

//czyści classname z modułów informujących o błędach
  function getCleanClassName(o, n) {
    return n.className.replace(new RegExp(' ' + o.classNameMissing, 'g'), '').replace(new RegExp(' ' + o.classNameError, 'g'), '').replace(new RegExp(' ' + o.classNameMisrepeated, 'g'), '');
  }

//blokuje formularz
  function disableForm(o) {
    for(var i = 0; i < o.form.elements.length; i++)
      o.form.elements[i].disabled = 'disabled';
  }

//odblokowuje formularz
  function enableForm(o) {
    for(var i = 0; i < o.form.elements.length; i++)
      o.form.elements[i].disabled = null;
  }

//enkodowanie warości na okoliczność separatorów
  function encodeForSend(v) {
    return v.replace(this.sep1, this.sep1c).replace(this.sep2, this.sep2c);
  }

  function packForm() {
    var elementName = "";
    var bigValue = "";
    for(var i = 0; i < this.form.elements.length; i++)
      if(elementName != this.form.elements[i].name) {
        elementName = this.form.elements[i].name;
        fieldVal = this.fieldValue(this.form.elements[i], false);
        if (fieldVal==undefined) fieldVal = '';
        else if (fieldVal==null) fieldVal = '';
        else if (fieldVal==false) fieldVal = '';
//alert('fieldVal='+fieldVal+'\n '+elementName);
        bigValue += this.sep1 + this.encodeForSend(elementName) + this.sep2 + this.encodeForSend(fieldVal);
      }
    bigValue = bigValue.substr(this.sep1.length);
alert('bigValue\n'+bigValue);
    return bigValue;
  }

  // Próbuje odczytać informacje o obiekcie INPUT
  // Jeśli się nie uda, zwraca obiekt, który dostał
  function getHTMLInputElementInfo(o) {
    var s = null;
    try {
      if (!(o instanceof HTMLInputElement)) return o;
      var s = '[HTMLInputElement';
      if (o.type!=null) s+=':'+o.type;
      if (o.name!=null) s+=',name='+o.name;
      if (o.value!=null) s+=',value='+o.value;
      if (o.title!=null) s+=',title='+o.title;
      //if (o.id!=null) s+=',value='+id;
      //if (o.style!=null) s+=',style='+o.style;
      s+=']';
    } catch (ex) { }
    return s!=null ? s : o;
  }

}
