/* 
 * form handler for modboxen 
 * by georg zimmer 
 * see mb_dispatch.php for more documentation.
 * 
 *  depends on jQuery
 *  depends on JSON2
*/
 
//boxlist contains a list of all the boxes.  it is used by notify system, as well as by post handler.
var boxList=new Array();

function FormHandler(xid,xclassname){
  var seq=0;
  var f = function(xid,xclassname){  
      //private vars     
      var id=xid;
      var classname=xclassname;
      var errorCallback=function (box,message,exception){
           //alert("errorCallback:" + box.id());
           };
      var postCallback=function (box,action,data){
           //alert("postCallback:" + box.id() + ":" + box.name()+" has no post event");
           };
      var notifyCallback=function(box,event,data){
           //alert("notifyCallback:" + box.id() + ":" + box.name()+" has no notify event");
          };

      function urlencode(s) {
              s = encodeURIComponent(s);
              return s.replace(/~/g,'%7E').replace(/%20/g,'+');
            }          
      //private methods       
      function makePost(fields){
          var j='';       
          jQuery.each(fields, function(i, field){
            if (j) j=j+',';
            j=j+'"'+field.name+'":"'+escape(field.value)+'"';
          });     
    
          return '{'+j+'}';      
      }
      
      function dispatchError(XMLHttpRequest,textStatus,errorThrown){
         errorCallback(box,textStatus,errorThrown);
      }
      
      //public methods
      return {
          init : function(){ 
             alert("replace me with your own");
          },
          //use to override default callback
          setPostCallback : function (callback){
            postCallback=callback;
          },
          //use to set notify function
          setNotifyCallback : function (callback){
            notifyCallback=callback;
          },
          //use to set error callback function
          setErrorCallback : function (callback){
            errorCallback=callback;
          },
          name : function () {
             return classname;
          },
          id : function() {
             return id;
          },
          notify : function(box,event,data){
              // replace this with your own notify handler.
              notifyCallback(box,event,data);
          },
          postData : function (_classname,remoteMethod,fields){
               box=boxList[id];              
               myGetJSON('/mb_dispatch.php',"json="+escape(JSON.stringify({'classname': _classname, 'method': remoteMethod,'args': fields })), 
                  function(data){
                    postCallback(box,remoteMethod,data);
                    if (data['notify']){
                      box.notifyAll(data['notify']['event'],data);
                    }
                  },
                  dispatchError
                  );    
               return false;     
          },
          //pass 'method' and optionally, a css class that should be used to gather elements for posting.
          post : function (remoteMethod,gatherclass) {
            if ((typeof gatherclass)=='undefined'){
              gatherclass="mb"; 
            }
            //top level
            var fields={};
            $("#"+id+" ."+gatherclass).each(function (){
               if ($(this).attr("type")=='checkbox' || $(this).attr("type")=='radio'){
                 fields[this.name]=($(this).attr("checked"))?(this.value):("")   
               }else{
                 //fix for ie6 nulls, test value first. if no value, set to empty string.
                 if (this.value){
                   fields[this.name]=this.value;
                 }else{
                   fields[this.name]="";
                 }
               }
            });
            //subforms can be used to group data.  put the master id into the form id attribute
            $("#"+id).find("form").each(function (a){    
              if (this.id){
                form=this;
                if (fields[form.name]==undefined){
                  fields[form.name]= {};
                }
                fields[form.name][form.id]={};
                $("#"+this.id+" ."+this.className).each(function (){
                  fields[form.name][form.id][this.name]={};
                  fields[form.name][form.id][this.name]=this.value;
                  });
              }
            });
            this.postData(classname,remoteMethod,fields);
          },
          //call this method to notify the other boxes that something happened.  The boxes interested in an event
          //should register a notifycallback and respond to it.  
          //This method is called automatically if a php method requests it by passing an event name 
          notifyAll : function (event,data){
             for (var xid in boxList){
               box=boxList[xid];
               box.notify(box,event,data);
             }
          }
       }    
    }(xid,xclassname);
    //save this handler in boxlist.
    boxList[xid]=f;     
    return f;
}

//like getJSON but has onError event handler
function myGetJSON(url,jdata,onSuccess,onError){
 $.ajax({
        type : "POST",
        url : url,
        cache: false,
        dataType: "json",
        data : jdata,
        success : onSuccess,
        error: onError
        });
      return true;
}

function dumpObj (obj, str) {
  msg = "";
  for (var i in obj) {
    if (typeof obj[i] == 'object' ) {
      msg += (str + i + " = object" + "\n");
      msg += dumpObj(obj[i], str + "  ");
    } else {
      msg += (str + i + " = " + obj[i] + "\n");
    }
  }
  return msg;
}

function trim(s){
  return s.replace(/^\s+|\s+$/g, '');
}

//convert to integer hack
function int(i){
  return i-0;
}
