/* NOTE: This file depends on showHide.js */
/*******************************************************************************
 * Defines a form to be submitted through Ajax
 *  - action: The action to invoke
 *  - formId: The ID of the form to submit.
 *  - popupDivId: The ID of popup division that contains the form
 *  - progessDivId: The ID of the division to show while the form is being submitted
 *  - statusDivId: The ID of the status division where progress and success is presented
 *  - successDivId: The ID of the division to show if the submission is successful.
 *******************************************************************************/
var PopupFormData = Class.create({
   initialize: function(action, formId, popupDivId, progressDivId, statusDivId, successDivId) {
      this.ERROR_FLAG = "ERROR";
      this.NEW_CAPTCHA_FLAG = "NEW CAPTCHA:";

      this.action = action;
      this.formId = formId;
      this.popupDivId = popupDivId;
      this.progressDivId = progressDivId;
      this.statusDivId = statusDivId;
      this.successDivId = successDivId;
      this.errorHash = new Hash();
   },
   /* Method invoked to close the popup division */
   close: function() {
      this.resetForm();
      hideElementSlideEffect(this.popupDivId);
   },
   /* Method invoked to hide the popup division */
   hide: function() {
      hideElement(this.popupDivId);
   },
   /* Method invoked to hide the popup division */
   hideAndReset: function() {
      this.resetForm();
      hideElement(this.popupDivId);
   },
   /* Method invoked to reset the form */
   resetForm: function() {
      resetVisibility(this.formId);
      var div = document.getElementById(this.statusDivId)
      if (div) {
         div.innerHTML = ''
      }
      var formObj = document.getElementById(this.formId);
      if (formObj) {
         formObj.reset();
      }
   },
   /* Method invoked when the operation failed on the server
    *    htmlText - The data received from the server without the ERROR_FLAG
    */
   processError: function(htmlText) {
//      alert('processError called');
      this.updateStatus(htmlText);
      resetVisibility(this.formId);
   },
   /* Method invoked to fill the errorHash based on the data received.
    */
   parseErrors: function(htmlText) {
      var lines = htmlText.split("\r");
      if (lines) {
        for (var i = 0; i < lines.length; i++) {
           var index = lines[i].indexOf('=');
           if (index != -1) {
              var key = trim(lines[i].substring(0, index));
              var value = trim(lines[i].substring(index+1));
              this.errorHash.set(key, value);
           }
        }
      } else {
         alert('NO ERROR FOUND');
      }
   },
   /* Method invoked when the operation was a success 
    *    htmlText - The data received from the server
    */
   processSuccess: function(htmlText) {
//      alert('processSuccess called');
      var successDiv = document.getElementById(this.successDivId);
      if (successDiv) {
	      this.updateStatus(successDiv.innerHTML);
      } else {
         var statusDiv  = document.getElementById(this.statusDivId);
         if (statusDiv) {
            this.updateStatus(htmlText);
	      } else {
            this.close();
	      }
      }
   },
   /* Method invoked when the form is submitted to show some progress to the
    * user.
    */
   showProgress: function() {
      var progressDiv = document.getElementById(this.progressDivId);
      if (progressDiv) {
         this.updateStatus(progressDiv.innerHTML);
      } else {
	 this.updateStatus('Your request is being sent...');
      }
      hideElement(this.formId);
   },
   /* Method invoked to update the status division with some HTML text. 
    *    htmlText - The data received from the server
    */
   updateStatus: function(htmlText) {
      var statusDiv  = document.getElementById(this.statusDivId);
      if (statusDiv) {
         statusDiv.innerHTML = htmlText;
      }
   },
   /* Method invoked when the captcha on the page needs to be refreshed as a
    * result of the form submission.
    *    captchaFile - The new file to use for the captcha.
    */
   updateCaptcha: function(captchaFile) {
   },
   /* Method invoked to perform validation before submitting the form to the
    * server.
    *    Must return true in order for the form to be submitted and false if
    *    there is an error in the form.
    */
   validateForm: function() {
      return true;
   },
   /* Method invoked to submit the form to the server.
    */
   submit: function() {
      if (this.validateForm() == true) {
         this.showProgress();
         submitAjaxForm(this);
      }
   }
});

/*******************************************************************************
 * This method is used to send the form data to the server and call the proper
 * methods based on the result of the action
 ******************************************************************************/
function submitAjaxForm(formInfo) {
   new Ajax.Request(formInfo.action, {
      method: 'post',
      parameters: $(formInfo.formId).serialize(true),
     
      onSuccess: function(transport) {
//	 alert(transport.responseText);
         var htmlText = transport.responseText;
   
         // Check if a new captcha was provided
         var index = htmlText.indexOf(formInfo.NEW_CAPTCHA_FLAG);
         if (index > -1) {
            // We need to refresh the captcha...
            var temp = htmlText.substring(index + formInfo.NEW_CAPTCHA_FLAG.length);
            var endIndex = temp.indexOf(" ");
            if (endIndex > -1) {
	       var captchaFile = temp.substring(0, endIndex);
	       formInfo.updateCaptcha(captchaFile);
	       htmlText = temp.substring(endIndex);
            } else {
	       htmlText = temp;
            }
         } else {
            // No new captcha provided
            // Remove the status word
            index = htmlText.indexOf(" ");
            if (index > -1) {
	       htmlText = htmlText.substring(index);
            }
         }

         if (transport.responseText.startsWith(formInfo.ERROR_FLAG)) {
	    // The request was rejected by the server
	    formInfo.processError(htmlText);
         } else {
	    // The request succeeded
	    formInfo.processSuccess(htmlText);
         }
      },	
  
      onFailure: function(reason) {
         formInfo.processError('An error occurred while submitting the request:<br/> ' + reason.status + ' - ' + reason.statusText + '.<br/>Please try again later');
         logAjaxError(formInfo.action, reason);
      }
   });
}

function logAjaxError(action, error) {
   var value = 'AJAX ERROR while trying action ' + action;
   if (error.status) {
      value = value + ': ' + error.status + ' - ' + error.statusText;
   } else {
      value = value + ': ' + error;
   }
   
   new Ajax.Request("/creator/logClientError.shtml", {
      method: 'post',
      parameters: {data: value},
		
      onComplete: function(transport) {
      }
  	});
}

function logAjaxErrorMessage(action, error) {
   var value = 'AJAX ERROR while trying action ' + action + ': ' + error;
   
   new Ajax.Request("/creator/logClientError.shtml", {
      method: 'post',
      parameters: {data: value},
		
      onComplete: function(transport) {
      }
  	});
}

function trim(value) {
   var startIndex = 0;
   for (var i = 0; i < value.length; i++) {
      var c = value.charAt(i);
      if ( (c == ' ') || (c == '\t') || (c == '\n') || (c == '\r')) {
         startIndex++;
      } else {
         break;
      }
   }
   var endIndex = value.length;
   for (i = value.length-1; i >= 0; i--) {
      var c = value.charAt(i);
      if ( (c == ' ') || (c == '\t') || (c == '\n') || (c == '\r')) {
         endIndex--;
      } else {
         break;
      }
   }
   
   return value.substring(startIndex, endIndex);
}
