/******************************************************************************
*   Gestion des Formulaire AJAX / JSON
*   Copyright (C) 2006 David PHAM-VAN
*
*   This program is free software; you can redistribute it and/or modify
*   it under the terms of the GNU General Public License as published by
*   the Free Software Foundation; either version 2 of the License, or
*   (at your option) any later version.
*
*   This program is distributed in the hope that it will be useful,
*   but WITHOUT ANY WARRANTY; without even the implied warranty of
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*   GNU General Public License for more details.
*
*   You should have received a copy of the GNU General Public License
*   along with this program; if not, write to the Free Software
*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
******************************************************************************/

window.onerror=function(e, f, g) {
  logError("ligne", g, ":", e, "(", f, ")");
}

//addLoadEvent(function () { createLoggingPane(true); });

if (typeof(dadForm)=="undefined") {
  dadForm={};
}

dadForm.VERSION="0.1.2"

dadForm.getFieldContent = function (elemName) {
  var self=dadForm;
  var value="";
  var elems=self.getElementsByName(elemName);
  for (var i=0;i<elems.length;i++) {
    var elem = elems[i];
    var name = elem.name;
    var tagName = elem.nodeName;
    if (tagName == "INPUT" && (elem.type == "radio" || elem.type == "checkbox") && !elem.checked ) {
      continue;
    } else if (tagName == "SELECT") {
      if (elem.selectedIndex >= 0) {
        var opt = elem.options[elem.selectedIndex];
        value = ((opt.value) ? opt.value : opt.text);
      }
      return value;
    }
    return elem.value || "";
  }
  return value;
}

dadForm.getElementsByName = function (elemName) {
  var ret = document.getElementsByName(elemName);
  if (ret.length==0) {
    var id=getElement('ID_'+elemName);
    if (id!=null && id.name==elemName) {
        return Array(id);
      }
    return Array();
  } else
    return ret;
}

dadForm.scrollIntoView = function (elem) {
  if (typeof(elem.scrollIntoView)!='undefined') {
    elem.scrollIntoView(true);
  }
}

dadForm.setFieldContent = function (elemName, value, scroll) {
  var self=dadForm;
  var elems=self.getElementsByName(elemName);
  for (var i=0;i<elems.length;i++) {
    var elem = elems[i];
    var name = elem.name;
    var tagName = elem.nodeName;
    if (scroll) {
      self.scrollIntoView(elem);
    }
    if (tagName == "INPUT" && (elem.type == "button" || elem.type == "submit" || elem.type == "reset"))
      return;
    if (tagName == "INPUT" && (elem.type == "radio" || elem.type == "checkbox")) {
      elem.checked=elem.value==value;
    } else if (tagName == "DIV" ) {
      elem.innerHTML=value;
      return null;
    } else {
      elem.value=value;
      return null;
    }
  }
  //logError('setFieldContent', elemName, value);
}

dadForm.formContents = function (formObj) {
  var self=dadForm;
  var values = {};
  var oform = MochiKit.DOM.getElement(formObj);
  if (typeof(oform.params)!="undefined") {
    elems=keys(oform.params);
    for (var i=0;i<elems.length;i++) {
      values[elems[i]]=self.getFieldContent(elems[i]);
    }
    values["JS"]=oform.id;
  }
  return values;
}

dadForm.checkRegExp = function (re, text) {
  var self=dadForm;
  var filter=RegExp(re);
  //log("RegExp:", re, text, filter.test(text));
  return filter.test(text);
}

dadForm.isInputEmpty = function (elemObj) {
  var self=dadForm;
  return self.getFieldContent(getElement(elemObj).name)=="";
}

dadForm.showFormMessage = function (elemObj, level, icon, info) {
  var self=dadForm;
  var elem=MochiKit.DOM.getElement(elemObj);
  var einfo=MochiKit.DOM.getElement(elem.name+"_info");
  if (einfo!=null) {
    MochiKit.DOM.setElementClass(einfo, "info info_"+icon);
    if (level==2)
      einfo.innerHTML=info;
    else
      einfo.innerHTML="&nbsp;";
  } else {
    //logDebug(elem.name, level, icon, info);
  }
}

dadForm.validInput = function (elemObj, event) {
  var self=dadForm;
  var elem=MochiKit.DOM.getElement(elemObj);
  var info="";
  var nom="";
  var level=0;
  var icon="std";
  var params=elem.form.params[elem.name];
  if (typeof(params)!="undefined") {
    if (params.nom)
      nom=params.nom;
    else
      nom=elem.name;
    if (self.isInputEmpty(elem, params)) {
      if (params.required==1) {
        icon="req_nak";
        if (params.rqerr)
          info=params.rqerr;
        else if (params.nom)
          info="est obligatoire";
        else
          info="est obligatoire";
        level=1;
      }
    } else {
      if (params.required==1) {
        icon="req_ack";
      }
      if (params.filtre) {
        if (!self.checkRegExp(params.filtre, elem.value)) {
          icon="flt_nak";
          if (params.flterr)
            info=params.flterr;
          else if (params.nom)
            info="n'est pas valide";
          else
            info="n'est pas valide";
          level=2;
        } else {
          icon="flt_ack";
        }
      }
    }
    self.showFormMessage(elem, level, icon, info, nom);
  }
  return [level==0, nom, info];
}

dadForm.lookupSearch = function (elemObj, event) {
  var self=dadForm;
  var delSearch = function() {
    if (typeof(self.lookupSearchDiv)!="undefined") {
      swapDOM(self.lookupSearchDiv, null);
      delete self.lookupSearchDiv;
    }
  }
  var elem=MochiKit.DOM.getElement(elemObj);
  var params=elem.form.params[elem.name];
  if (typeof(self.lookupSearchAsync)!="undefined") {
    self.lookupSearchAsync.cancel();
    delSearch();
  }
  if (typeof(params)!="undefined") {
    if (event.keyCode==27) {
      delSearch();
      return null;
    }
    if (elem.value.length>0) {
      self.lookupSearchAsync=MochiKit.Async.callLater(0.5, function() {
        var d = loadJSONDoc(params.lookup.url+"?find="+elem.value);
        var lookupCallBack = function (data) {
          self.lookupSearchDiv=DIV({'class':'lookupBox'});
          for (i=0;i<data.length;i++) {
            appendChildNodes(self.lookupSearchDiv, SPAN({'onclick':function() { elem.value=this.innerHTML; delSearch(); }}, data[i]));
          }
          var nmax=10;
          if (data.length>nmax)
            updateNodeAttributes(self.lookupSearchDiv, {'style': {'height':+(nmax*16)+'px', 'overflow':'auto'}});
          appendChildNodes(elem.parentNode, self.lookupSearchDiv);
        }
        d.addCallbacks(lookupCallBack, dadForm.failedCallBack);
      } )
    } else {
      delSearch();
    }
  }
}

dadForm.validForm = function (formObj) {
  var self=dadForm;
  var oform=MochiKit.DOM.getElement(formObj);
  var formElems=keys(self.formContents(oform));
  var hasErr=false;
  var message={};
  for (var i=0;i<formElems.length;i++) {
    var el=self.getElementsByName(formElems[i]);
    for (var j=0;j<el.length;j++) {
      if (objEqual(el[j].form, oform)) {
        var r=self.validInput(el[j], null);
        if (!r[0]) {
          hasErr=true;
          message[el[j].name]=r[1]+" "+r[2];
        }
      }
    }
  }
  if (hasErr) {
    var k=keys(message);
    var m="Impossible de valider le formulaire\ncar il contient les erreurs suivantes :\n"
    for (var i=0;i<k.length;i++) {
      m+=" - "+message[k[i]]+"\n";
    }
    return [hasErr, m];
  } else
    return [hasErr, ""];
}

dadForm.failedCallBack = function (err) {
  alert("Une erreur interne est surenue :\n"+err.message);
}

dadForm.replaceForm = function (formObj, message) {
  var self=dadForm;
  var oform=MochiKit.DOM.getElement(formObj);
  var div=DIV({'class':oform.className, 'id':oform.id}, message);
  swapDOM(oform, div);
  self.scrollIntoView(div);
}

dadForm.submitForm = function (formObj, faction) {
  var self=dadForm;
  var oform=MochiKit.DOM.getElement(formObj);
  var r=self.validForm(oform);
  if (r[0]) {
    alert(r[1]);
  } else {
    var content=self.formContents(oform);
    var xmlHttpReq = getXMLHttpRequest()
    if (typeof(faction)=='undefined')
      faction=oform.action;
    xmlHttpReq.open( "POST", faction, true);
    xmlHttpReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    var d=sendXMLHttpRequest(xmlHttpReq, MochiKit.Base.queryString(content));
    d = d.addCallback(evalJSONRequest);

    var submittedCallBack = function (data) {
      if (isArrayLike(data)) {
        for (var di=0;di<data.length;di++) {
          var idata=data[di];
          if (idata.debug) {
            logDebug(idata.debug);
          } else if (idata.call) {
            try {
              eval(idata.call);
            } catch(e) {
              logError(e);
            }
          } else if (idata.message) {
            alert(idata.message);
          } else if (idata.rmessage) {
            self.replaceForm(oform, idata.rmessage);
            logDebug(idata.rmessage);
          } else {
            logDebug('Inconnu:', serializeJSON(idata));
          }
        }
      } else {
        logDebug(serializeJSON(data));
      }
    }

    d.addCallbacks(submittedCallBack, dadForm.failedCallBack);
    //logDebug("Submit ", formObj.name, MochiKit.Base.queryString(content));
  }
  return false;
}

dadForm.resetForm = function (formObj) {
  var self=dadForm;
  var oform=MochiKit.DOM.getElement(formObj);
  var formElems=keys(self.formContents(oform));
  for (var i=0;i<formElems.length;i++) {
    self.setFieldContent(formElems[i], '');
  }
  setTimeout(function () { self.validForm(oform); }, 1);
  return true;
}

dadForm.setFormValidator = function (formObj, validator) {
  var self=dadForm;
  var oform=MochiKit.DOM.getElement(formObj);
  //hideElement(MochiKit.DOM.getElement(oform.id+"_error"));
  //showElement(oform);
  oform.params=validator;
  //log(serializeJSON(validator));
  //appendChildNodes(oform, createDOM("input", {"type":"hidden", "name":"JS", "value":oform.name}));
  self.validForm(oform);
}

