var AjaxNet = new Object();

AjaxNet.READY_STATE_UNINITIALIZED = 0;
AjaxNet.READY_STATE_LOADING = 1;
AjaxNet.READY_STATE_LOADED = 2;
AjaxNet.READY_STATE_INTERACTIVE = 3;
AjaxNet.READY_STATE_COMPLETE = 4;

AjaxNet.GetHttpObject = function() {
   if(window.XMLHttpRequest) {
      return new XMLHttpRequest();
   } else if(window.ActiveXObject) {
      return new ActiveXObject("Microsoft.XMLHTTP");
   }
   return false;
}

// To Call:
// - var someVar = new AjaxNet.LinkLoader("/jsp/jsps/someFile.jsp");
// - var someVar = new AjaxNet.LinkLoader("/jsp/jsps/someFile.jsp", myCallBackFunction);
// - var someVar = new AjaxNet.LinkLoader("/jsp/jsps/someFile.jsp", myCallBackFunction, myCustomErrorHandlingFunction);
AjaxNet.LinkLoader = function(url,callbackFunction,errorFunction) {
   if(arguments.length == 0 || (arguments.length > 0 && (arguments[0] == null || arguments[0] == "") )) {
      alert("AjaxNet.LinkLoader is constructed improperly");
      return;
   }
   
   this.url = url;
   this.httpObj = null;
   this.httpObjResponseText = null;
   this.callbackFunction = (callbackFunction) ? callbackFunction : this.nullCallBackFunction;
   this.errorFunction = (errorFunction) ? errorFunction : this.defaultError;
   this.doLink(url);
}

AjaxNet.LinkLoader.prototype={
   getResponseText:function() {
      return this.httpObjResponseText; // Will be populated after response has completed
   },
   doLink:function(url) {
      this.httpObj = AjaxNet.GetHttpObject();

      if(this.httpObj) {
         try {
            // To prevent caching of response due to no change in in request/request params we append a client timestamp param to make request unique
            var rightNow = new Date();
            var rightNowTime = rightNow.getTime();
            if(url.indexOf("?") == -1) { url += "?" + rightNowTime + "=" + rightNowTime; }
            else { url += "&" + rightNowTime + "=" + rightNowTime; }

            var loader = this;
            this.httpObj.onreadystatechange = function() {
               loader.onReadyState.call(loader);
            }
            this.httpObj.open("GET",url,true);
            this.httpObj.send(null);
         }
         catch(err) { this.errorFunction.call(this); }
      }
   },
   onReadyState:function() {
      var httpObj = this.httpObj;
      var ready = httpObj.readyState;
      if(ready == AjaxNet.READY_STATE_COMPLETE) {
         var httpStatus = httpObj.status;
         if(httpStatus == 200 ||  httpStatus == 0) {
            this.httpObjResponseText = httpObj.responseText;
            this.callbackFunction.call(this);
         }
         else { this.errorFunction.call(this); }
      }
   },
   nullCallBackFunction:function() {;},
   defaultError:function() {
      alert("error fetching data!"
            + "\n\nreadyState: " + this.httpObj.readyState
            + "\nstatus: " + this.httpObj.status
            + "\nheaders: " + this.httpObj.getAllResponseHeaders());
   }
}


// To Call:
// - var someVar = new AjaxNet.FormLoader(document.forms.formName);
// - var someVar = new AjaxNet.FormLoader(document.forms.formName, myCallBackFunction);
// - var someVar = new AjaxNet.FormLoader(document.forms.formName, myCallBackFunction, myCustomErrorHandlingFunction);
AjaxNet.FormLoader = function(form,callbackFunction,errorFunction) {
   if(arguments.length == 0 || (arguments.length > 0 && (arguments[0] == null || arguments[0] == "") )) {
      alert("AjaxNet.FormLoader is constructed improperly");
      return;
   }

   this.form = form;
   this.httpObj = null;
   this.httpObjResponseText = null;
   this.callbackFunction = (callbackFunction) ? callbackFunction : this.nullCallBackFunction;
   this.errorFunction = (errorFunction) ? errorFunction : this.defaultError;
   this.doForm(form);
}

AjaxNet.FormLoader.prototype={
   getResponseText:function() {
      return this.httpObjResponseText; // Will be populated after response has completed
   },
   doForm:function(form) {
      this.httpObj = AjaxNet.GetHttpObject();

      if(this.httpObj) {
         var action = form.action;
         var elements = form.elements;
         var method = form.method.toUpperCase();
         var url = "";
         var params = "";

         for(var j = 0; j < elements.length; j++) {
            var element = elements[j];
            var name = element.name;
            var value = element.value;
            params += name + "=" + value;
            if(j < elements.length - 1) { params += "&"; }
         }
         
         // To prevent caching of response due to no change in in request/request params we append a client timestamp param to make request unique
         var rightNow = new Date();
         var rightNowTime = rightNow.getTime();
         if(params != "") { params += "&"; }
         params += rightNowTime + "=" + rightNowTime;

         try {
            var loader = this;
            this.httpObj.onreadystatechange = function() {
               loader.onReadyState.call(loader);
            }

            if(method == "POST") {
               this.httpObj.open("POST", action, true);
               this.httpObj.setRequestHeader("Content-type","application/x-www-form-urlencoded");
               this.httpObj.setRequestHeader("Content-length",params.length);
               this.httpObj.send(params);
            }

            if(method == "GET") {
               url = action + "?" + params;
               this.httpObj.open("GET",url,true);
               this.httpObj.send(null);
            }
         }
         catch(err) { this.errorFunction.call(this); }
      }
   },
   onReadyState:function() {
      var httpObj = this.httpObj;
      var ready = httpObj.readyState;

      if(ready == AjaxNet.READY_STATE_COMPLETE) {
         var httpStatus = httpObj.status;
         if(httpStatus == 200 ||  httpStatus == 0) {
            this.httpObjResponseText = httpObj.responseText;
            this.callbackFunction.call(this);
         }
         else {
            this.errorFunction.call(this);
         }
      }
   },
   nullCallBackFunction:function() {;},
   defaultError:function() {
      alert("error fetching data!"
            + "\n\nreadyState: " + this.httpObj.readyState
            + "\nstatus: " + this.httpObj.status
            + "\nheaders: " + this.httpObj.getAllResponseHeaders());
   }
}

