/**
 * class for debugging purposes to accumulate debug message and display them
 * 
 */ 
var debugInfo = new function() {
  this.info = "";
  this.append = function(str) {
    this.info += str + "<br/>";
  };
  
  this.print = function() {
	  var body = document.getElementsByTagName("body")[0];
	  if (body) {
		  var divObj = document.getElementById("debugDiv");
		  if (divObj == null || divObj == undefined) {
			  divObj = document.createElement("DIV");
			  divObj.id = "debugDiv";
			  body.appendChild(divObj);
		  }
		  divObj.innerHTML = "<hr><h3>Debug Info: </h3><hr>" + this.info + "<br/><hr>"
	  }
  };
};

//put in separate file
/**
 * class to request json and call callback function to pass responseData
 * 
 */ 
var jsonHelper = {
  timeout: 200,
  callback: null,
  callBackParam: null, 
  errorFunction: null, 
  requestIsDone: false,
  timeoutId: null,
  isTimeout: false,
  
  /**
   * sends request to url with possible data and if successfull - call callBackFunction
   * 
   * @param {String} url url, to which to send a request
   * @param {String} data name value pairs separated by "&"
   * @param {Function} callBackFunction reference to the function to call when request is completed
   * @param {Function} errorFunction reference to the function to call when request is failed
   * @param {Boolean} sync - if true wait for completion, doesn't work in firefox
   */ 
  sendData: function(url, data, callBackFunction, errorFunction, sync, callBackParam) {
	this.clearTimeout();
	jsonHelper.isTimeout = false;
    debugInfo.append("begin to send data, timeout: " + this.timeout);
    this.callback = callBackFunction;
    this.errorFunction = errorFunction;
    this.callBackParam = callBackParam;
    
    try {
      url += (url.match(/\?/) ? "&" : "?") + "callbackFunction=jsonHelper.complete";
      if (data) {
        url += "&" + data;
      }
      debugInfo.append("whole url to request: " + url);
      
      var head = document.getElementsByTagName("head")[0];
      var script = document.createElement("script");
      script.src = url;
      script.type = 'text/javascript';
      if (this.scriptCharset) {
        script.charset = this.scriptCharset;
      }
    
      jsonHelper.requestIsDone = false;
        // Attach handlers for all browsers
      script.onload = script.onreadystatechange = function(){
          if ( (jsonHelper.requestIsDone === false) && (jsonHelper.isTimeout === false) && (!this.readyState ||
              this.readyState == "loaded" || this.readyState == "complete") ) {
            debugInfo.append("finished loading");
            
            jsonHelper.success();

            jsonHelper.removeScript(head, script);
          }
      };

      head.appendChild(script);
    
     
      // Timeout checker
      if ( this.timeout > 0 ) {
        this.timeoutId = window.setTimeout(function(){
          // Check to see if the request is still happening
          if (jsonHelper.requestIsDone === false) {
            debugInfo.append("WARNING: timeout happened");
            
            jsonHelper.isTimeout = true;
            
            jsonHelper.removeScript(head, script);
            
            jsonHelper.handleError(url, new Error("timeout"));
          }
        }, this.timeout);
      }
      if (sync === true) {
    	  debugInfo.append("synchronized, will wait for json to fully load");
    	  jsonHelper.waitForJsonGet(this.timeout);
    	  debugInfo.append("in sync mode finished statement should be before this");
      }
      
    } catch(e) {
      this.handleError(url, e);
    }
  },
  removeScript: function(parentObj, scriptObj) {
    // Handle memory leak in IE
    scriptObj.onload = scriptObj.onreadystatechange = null;
    parentObj.removeChild( scriptObj );
  },
  

  complete: function(responseData){
	 debugInfo.append("complete the request");
     if (!responseData || responseData["error"]) {
       this.handleError("", new Error(((responseData["error"]) ? responseData["error"]: "")));
     } else if (jsonHelper.isTimeout === false) { //catch situation in firefox, it continues to load script even when we delete script tag
       this.success();
       jsonHelper.callback.call(this, responseData, this.callBackParam);
     }
  },

  handleError: function(url, e) {
    this.requestIsDone = true;
    this.clearTimeout();
    debugInfo.append("ERROR: in handleError: " + url + " exception: " + e.message);
    
    if (jsonHelper.errorFunction) {
      jsonHelper.errorFunction.call(this, "");
    }
  },
  
  success: function() {
	this.clearTimeout();
    this.requestIsDone = true;
    debugInfo.append("successfully finished request");
  }, 
  
  waitForJsonGet: function(timeoutMillis)
  {
  	var date = new Date();
  	var curDate = null;

  	do { 
  		curDate = new Date(); 
  	}while( (curDate - date) < timeoutMillis && (jsonHelper.requestIsDone === false));
  }, 
  
  clearTimeout: function() {
	  if (this.timeoutId) {
		  window.clearTimeout(this.timeoutId);
	  }	  
  }

};
