//-------------------------------------------------------------------
// Define WxGui.Form module
//-------------------------------------------------------------------

if (typeof(JSAN) != 'undefined') {
  JSAN.use('MochiKit.Base');
  JSAN.use('MochiKit.Async');
  JSAN.use('MochiKit.DOM');
  JSAN.use('WxGui.Input',[]);

  try {
      if (typeof(WxGui.Input) == 'undefined') {
          throw "";
      }
  } catch (e) {
      throw "WxGui.Form depends on WxGui.Input!";
  }
}

if (typeof(WxGui) == 'undefined') {
  WxGui = {};
}

WxGui.Form = {};
WxGui.Form.NAME = 'WxGui.Form';
WxGui.Form.VERSION = '1.0';
WxGui.Form.cssDir = "/libjs/intraxxion/WxGui/styles/";
WxGui.Form.imagesDir =  "/libjs/intraxxion/WxGui/images/";
WxGui.Form.EXPORT = ['Form'];

WxGui.Form.__repr__ = function () {
    return "[" + this.NAME + " " + this.VERSION + "]";
};
WxGui.Form.toString = function () {
    return this.__repr__();
};

//-------------------------------------------------------------------
// WxGui.Form.Form
//-------------------------------------------------------------------
WxGui.Form.Form = function() { 
  this.callwhenready = null; 
  this.formelement = null;
  this.errorelement = null;
  this.fields = 0;  
  this.formOK = true;
  this.widgets = new Array();
  this.hasFileUpload = false;
  this.formaction = location.href+'/action';
  this.use_assistant = true;
  this.formmessage = '';
  this.submitstatus = 'OK';
  MochiKit.Base.bindMethods(this);

  return this;
};

WxGui.Form.Form.prototype = {
  "init": function(id, element, url, use_assistant, callwhenready) {
    this.use_assistant = (use_assistant != undefined) ? use_assistant : false;
    this.id = id;
    this.url = url;           
    this.callwhenready = callwhenready;
    this.element = (element=='body') ? document.getElementsByTagName('body')[0] : $(element);
    this.fields = null;
    this.loadFormDef(); 
  }, 
  useAssistant: function(val) {
    this.use_assistant = val;
  },
  loadFormDef: function() {
    d = MochiKit.Async.loadJSONDoc(this.url);
    d.addCallbacks(this.loadFormFetched, this.loadFormFailed);
  }, 
  loadFormFetched:function(data) {
    this.fields = data[0].fields;
    this.render();
    this.callwhenready(this.formelement, this.errorelement);
  },             
  loadFormFailed:function(err) {
    alert(err.req.responseText);
  },
  setFormAction: function(url) {
    this.formaction = url;
  },

  render: function() {                           
    this.formelement = MochiKit.DOM.FORM(
      {'name':this.id,
       'id':this.id,
       'action':'action',
       'method':'GET'},null); // ,'style':'margin-top:60px;'
    this.errorelement = DIV({'id':'formerror'});
    MochiKit.DOM.appendChildNodes(this.element, this.formelement); 
    
    for (ix = 0; ix < this.fields.length; ix++) {
      fld = this.fields[ix];  
      switch (fld.type) {
        case 'String':
          fdef = new WxGui.Input.String();
          break;
        case 'Email':
          fdef = new WxGui.Input.Email();
          break;
        case 'Password':
          fdef = new WxGui.Input.Password();
          break;
        case 'Text':
          fdef = new WxGui.Input.Text();
          break;
        case 'Integer':
          fdef = new WxGui.Input.Integer();
          break;
        case 'Date':
          fdef = new WxGui.Input.Date();
          break;
        case 'Checkbox':
          fdef = new WxGui.Input.Checkbox();
          break;
        case 'RadioGroup':
          fdef = new WxGui.Input.RadioGroup();
          break;
        case 'Select':
          fdef = new WxGui.Input.Select();
          break;
        case 'File':
          fdef = new WxGui.Input.File();
          this.hasFileUpload = true;
          break;
      }
      fdef.init(fld.id, this.formelement, fld.options, this);
      this.widgets.push(fdef);
    }
  },
  getField: function(id) {
    // Get the field by name
    for (fv = 0; fv < this.widgets.length; fv++) {
      wdg = this.widgets[fv];
      if (wdg.id == id) {
        return wdg;
      }
    }                     
    throw "WxGui.Form.Form.getField(): Veld met id "+id+" is niet gedefinieerd";
  },
  setFieldValue: function(id, val) {
    fld = this.getField(id);
    fld.setValue(val);
  },
  getFieldValue: function(id) {
    fld = this.getField(id);
    fld.syncValue();
    return fld.value;
  },
  getFieldValues: function() {
    vals = new Array();
    for (fv = 0; fv < this.widgets.length; fv++) {
      wdg = this.widgets[fv];
      wdg.syncValue();
      vals.push({ 'id' : wdg.id, 'value': wdg.value });
    }                     
    return vals;
  },
  serializeValues: function() {
    log('WxGui.Form.serializeValues is deprecated');
  },
  checkForm: function() {
    vals = new Array();
    this.formOK = true;
    vals = filter(this.checkField, this.widgets);
    return vals;    
  },
  checkField: function (ob) {
    fldOK = ob.checkValue();                                                   
    if (!fldOK) {
      this.formOK = false;                                           
      return true;
    } else {
      return this.userCheck(ob)
    }
                                                                                             
  },
  userCheck: function(ob) {
    // Do usercheck
    if (ob.leaveField!=null) {                                      
      lfOK = ob.leaveField();
      if (!lfOK) {
        this.formOK = false;
        return true;          
      }
    }
  },
  showErrors: function() {
    vals = this.checkForm();
    if (vals.length>0) {
      return DIV(null, DIV(null,'De volgende velden bevatten invoerfouten, corrigeer deze en verzend het formulier opniew:'),
        UL(null, map(this.addErrorMessage, vals)));                   
    } else {
      return null;
    }
  },
  addErrorMessage: function(ob) {
    return LI(null, ob.errorMessage);
  },
  submit: function() {                    
    var self = this;          
    nErrs = this.checkForm().length;
    if (nErrs == 0) {
      // No errors, proceed
      if (this.hasFileUpload) {
        this.submitAjaxFormWithAttachments(
          function(evt) {
            src = evt.src();
            rec = {'status':'OK', 'responseText':evt.src().contentWindow.document.body.innerHTML};
            self.submitAjaxReady(rec);
          }
        );
      } else {
        d = this.submitAjaxForm();
        d.addCallbacks(this.submitAjaxReady, this.submitAjaxFailed);
      }
    } else {
      // There are errors in the form, show a message
      this.errorelement = DIV({'id':'formerror','class':'error','style':'display:none;width:auto;height:auto'},this.showErrors());
      swapDOM($('formerror'),this.errorelement)                                      
      slideDown(this.errorelement);
      callLater(nErrs*2.0, slideUp, this.errorelement);
    }    
  },
  submitAjaxForm: function() {
    req = MochiKit.Async.getXMLHttpRequest();       
    req.open('POST', this.formaction, true);
    req.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 
    postBody = MochiKit.Base.queryString(this.formelement);
    return MochiKit.Async.sendXMLHttpRequest(req, postBody); 
  },
  submitAjaxFormWithAttachments: function(callback) {
    this.formelement.setAttribute('target','dummyajax');
    this.formelement.setAttribute('action',this.formaction);
    this.formelement.setAttribute('method','post');
    this.formelement.setAttribute('enctype','multipart/form-data');
    this.formelement.enctype='multipart/form-data';
    this.formelement.target='dummyajax';
    this.formelement.action=this.formaction;

    if (!$('dummyajax')) {
      da = document.createElement('iframe');
      da.setAttribute('id','dummyajax');
      da.setAttribute('name','dummyajax');
      da.name = 'dummyajax';
      da.style.display='none';

      document.getElementsByTagName('body')[0].appendChild(da);
      connect(da, 'onload', callback);
    }
    this.formelement.submit();  
  },
  submitAjaxReady: function(data) {
    mydata = evalJSONRequest(data);
    this.submitstatus = mydata.status;
    this.responsedata = mydata;
    try {
      this.formmessage = mydata.message;
    } catch(e) {}
//    if (mydata.status == 'OK') {
//      map(this.updateSheetValues,mydata.data)
//    }
    signal(this, 'afterformsubmit');
  },
  submitAjaxFailed: function (err) {
    signal(this, 'formsubmitfailed', err);
  },
  updateSheetValues: function(ob) {
    map(this.updateFieldValue, ob.fields)    
  },
  updateFieldValue: function(ob) {
    this.setFieldValue(ob.id, ob.value);
  }
};   

WxGui.Form.__new__ = function () {
    MochiKit.Base.nameFunctions(this);
    this.EXPORT_TAGS = {
      ":common": this.EXPORT,
      ":all": this.EXPORT
    };
};

//WxGui.Form.__new__();
//MochiKit.Base._exportSymbols(this, WxGui.Form);

// Setup the stylesheet for Form                                                                          
/*
FormCss = createDOM('link', {'rel':'stylesheet','type':'text/css','href':WxGui.Form.cssDir+'widgets.css'});
document.getElementsByTagName('head')[0].appendChild(FormCss); 
*/
