// Remap jquery in no conflict
var $j = jQuery.noConflict();

///////////////////////////////////////////////////
// The qcodo Object is used for everything in Qcodo
///////////////////////////////////////////////////
	var qcodo = {

		recordControlModification: function (strControlId, strProperty, strNewValue) {
			if (!qcodo.controlModifications[strControlId])
				qcodo.controlModifications[strControlId] = new Object;
			qcodo.controlModifications[strControlId][strProperty] = strNewValue;
		},

		postBack: function(strForm, strControl, strEvent, strParameter) {
			var strForm = $j("#Qform__FormId").attr("value");
			var objForm = $j('#' + strForm);

			$j('#Qform__FormControl').attr("value", strControl);
			$j('#Qform__FormEvent').attr("value", strEvent);
			$j('#Qform__FormParameter').attr("value", strParameter);
			$j('#Qform__FormCallType').attr("value", "Server");
			$j('#Qform__FormUpdates').attr("value", this.formUpdates());
			$j('#Qform__FormCheckableControls').attr("value", this.formCheckableControls(strForm, "Server"));

			// have $j trigger the submit event (so it can catch all submit events)
			objForm.trigger("submit");
		},

		formUpdates: function() {
			var strToReturn = "";
			for (var strControlId in qcodo.controlModifications)
				for (var strProperty in qcodo.controlModifications[strControlId])
					strToReturn += strControlId + " " + strProperty + " " + qcodo.controlModifications[strControlId][strProperty] + "\n";
			qcodo.controlModifications = new Object;
			return strToReturn;
		},

		formCheckableControls: function(strForm, strCallType) {

			// Select the qcodo Form
			var objFormElements = $j('#' + strForm + ' input,select,textarea');
			var strToReturn = "";

			objFormElements.each(function(i) {
				if ((($j(this).attr("type") == "checkbox") ||
					 ($j(this).attr("type") == "radio")) &&
					((strCallType == "Ajax") ||
					(!$j(this).attr("disabled")))) {

					var strControlId = $j(this).attr("id");

					// CheckBoxList
					if (strControlId.indexOf('[') >= 0) {
						if (strControlId.indexOf('[0]') >= 0)
							strToReturn += " " + strControlId.substring(0, strControlId.length - 3);
					// RadioButtonList
					} else if (strControlId.indexOf('_') >= 0) {
						if (strControlId.indexOf('_0') >= 0)
							strToReturn += " " + strControlId.substring(0, strControlId.length - 2);

					// Standard Radio or Checkbox
					} else {
						strToReturn += " " + strControlId;
					}
				}
			});

			if (strToReturn.length > 0)
				return strToReturn.substring(1);
			else
				return "";
		},

		postAjax: function(strForm, strControl, strEvent, strParameter, strWaitIconControlId) {
			var objForm = $j('#' + strForm);
			var strFormAction = objForm.attr("action");
			var objFormElements = $j('#' + strForm + ' input,#' + strForm + ' select,#' + strForm + ' textarea');

			$j('#Qform__FormControl').attr("value", strControl);
			$j('#Qform__FormEvent').attr("value", strEvent);
			$j('#Qform__FormParameter').attr("value", strParameter);
			$j('#Qform__FormCallType').attr("value", "Ajax");
			$j('#Qform__FormUpdates').attr("value", this.formUpdates());
			$j('#Qform__FormCheckableControls').attr("value", this.formCheckableControls(strForm, "Ajax"));

			var strPostData = '';

			objFormElements.each(function () {
				var strType = this.type;
				var strControlId = $j(this).attr("id");
				switch (strType) {
					case "checkbox":
					case "radio":
						if ($j(this).attr("checked")) {
							var strTestName = $j(this).attr("name") + "_";
							if (strControlId.substring(0, strTestName.length) == strTestName)
								strPostData += "&" + $j(this).attr("name") + "=" + strControlId.substring(strTestName.length);
							else
								strPostData += "&" + strControlId + "=" + $j(this).val();
						};
						break;

					case "select-multiple":
						$j(this).find(':selected').each (function (i) {
							strPostData += "&" + $j(this).parents("select").attr("name") + "=";
							strPostData += $j(this).val();
						});
						break;

					default:
						strPostData += "&" + strControlId + "=";

						// For Internationalization -- we must escape the element's value properly
						var strPostValue = $j(this).val();
						if (strPostValue) {
							strPostValue = strPostValue.replace(/\%/g, "%25");
							strPostValue = strPostValue.replace(/&/g, escape('&'));
							strPostValue = strPostValue.replace(/\+/g, "%2B");
						}
						strPostData += strPostValue;
						break;
				}
			});

			if (strWaitIconControlId) {
				this.objAjaxWaitIcon = this.getControl(strWaitIconControlId);
				if (this.objAjaxWaitIcon)
					this.objAjaxWaitIcon.style.display = "inline";
			};

			$j.ajax({
				url: strFormAction,
				type: "POST",
				data: strPostData,
				error: function (XMLHttpRequest, textStatus, errorThrown) {
					if (XMLHttpRequest.status != 0 || XMLHttpRequest.responseText.length > 0) {
          
// remote log the error [2009-05-27:bpc]
if (window.bugReport && bugReport.submitReport) {
  page_key = location.href.substring(10).replace(/.*?\/([\w\/\-]+).*/, '$1').replace(/[^\w]/, '-');
  bugReport.submitReport('qcodo-ajax_'+ page_key, 'An error occurred during AJAX Response parsing. Server response is:\r\n'+ XMLHttpRequest.responseText);
}
						alert("An error occurred during AJAX Response parsing.\r\n\r\nThe error response will appear in a new popup.");
						var objErrorWindow = window.open('about:blank', 'qcodo_error','menubar=no,toolbar=no,location=no,status=no,scrollbars=yes,resizable=yes,width=1000,height=700,left=50,top=50');
						objErrorWindow.focus();
						objErrorWindow.document.write(XMLHttpRequest.responseText);
						return;
					}
				},
				success: function (json) {
						if (json.controls){
							$j.each(json.controls, function(index, value) {
								if (value != null){
									var strControlId = '#' + value.id;
									var strControlHtml = value.data;
									if (strControlId == "#Qform__FormState") {
										$j(strControlId).val(strControlHtml);
									} else {
										if ($j(strControlId).length){
											$j(strControlId).replaceWith(strControlHtml);
										} else {
											$j(strControlId + '_ctl').replaceWith(strControlHtml);
										}
									}
								}
							});
						}
					eval(json.commands);
					if (qcodo.objAjaxWaitIcon)
						qcodo.objAjaxWaitIcon.style.display = 'none';
				}
			});

		},

		initialize: function() {

			this.loadJavaScriptFile = function(strScript, objCallback) {
				strScript = qc.jsAssets + "/" + strScript;
				$j.getScript(strScript, objCallback);
			};

			this.loadStyleSheetFile = function(strStyleSheetFile, strMediaType) {
				strStyleSheetFile = qc.cssAssets + "/" + strStyleSheetFile;

				$j('head').append('<link rel="stylesheet" href="' + strStyleSheetFile + '" type="text/css" />');

			};
      
      this.registerForm = function() {
        // "Lookup" the QForm's FormId
        var strFormId = document.getElementById("Qform__FormId").value;

        // Register the Various Hidden Form Elements needed for QForms
        this.registerFormHiddenElement("Qform__FormControl", strFormId);
        this.registerFormHiddenElement("Qform__FormEvent", strFormId);
        this.registerFormHiddenElement("Qform__FormParameter", strFormId);
        this.registerFormHiddenElement("Qform__FormCallType", strFormId);
        this.registerFormHiddenElement("Qform__FormUpdates", strFormId);
        this.registerFormHiddenElement("Qform__FormCheckableControls", strFormId);
      };

      this.registerFormHiddenElement = function(strId, strFormId) {
        var objHiddenElement = document.createElement("input");
        objHiddenElement.type = "hidden";
        objHiddenElement.id = strId;
        objHiddenElement.name = strId;
        document.getElementById(strFormId).appendChild(objHiddenElement);
      };

    
      /////////////////////////////
      // QForm-related functionality
      /////////////////////////////

	  this.controls = new Array();
      
      ////////////////////////////////////
      // Window Unloading
      ////////////////////////////////////

      this.unloadFlag = false;
      this.handleBeforeUnload = function() {
        qcodo.unloadFlag = true;
      };
      window.onbeforeunload = this.handleBeforeUnload;
      
      ////////////////////////////////////
      // Color Handling Functionality
      ////////////////////////////////////
  
      this.colorRgbValues = function(strColor) {
        strColor = strColor.replace("#", "");

        try {
          if (strColor.length == 3)
            return new Array(
              eval("0x" + strColor.substring(0, 1)),
              eval("0x" + strColor.substring(1, 2)),
              eval("0x" + strColor.substring(2, 3))
            );
          else if (strColor.length == 6)
            return new Array(
              eval("0x" + strColor.substring(0, 2)),
              eval("0x" + strColor.substring(2, 4)),
              eval("0x" + strColor.substring(4, 6))
            );
        } catch (Exception) {};

        return new Array(0, 0, 0);
      };

      this.hexFromInt = function(intNumber) {
        intNumber = (intNumber > 255) ? 255 : ((intNumber < 0) ? 0 : intNumber);
        intFirst = Math.floor(intNumber / 16);
        intSecond = intNumber % 16;
        return intFirst.toString(16) + intSecond.toString(16);
      };

      this.colorRgbString = function(intRgbArray) {
        return "#" + qcodo.hexFromInt(intRgbArray[0]) + qcodo.hexFromInt(intRgbArray[1]) + qcodo.hexFromInt(intRgbArray[2]);
      };
      
      ////////////////////////////////////
      // Mouse Drag Handling Functionality
      ////////////////////////////////////
      // removed since jquery integration

		}
	};

///////////////////////////////
// Timers-related functionality
///////////////////////////////

		qcodo._objTimers = new Object();

		qcodo.clearTimeout = function(strTimerId) {
			if (qcodo._objTimers[strTimerId]) {
				clearTimeout(qcodo._objTimers[strTimerId]);
				qcodo._objTimers[strTimerId] = null;
			};
		};

		qcodo.setTimeout = function(strTimerId, strAction, intDelay) {
			qcodo.clearTimeout(strTimerId);
			qcodo._objTimers[strTimerId] = setTimeout(strAction, intDelay);
		};

/////////////////////////////////////
// Event Object-related functionality
/////////////////////////////////////

qcodo.terminateEvent = function(objEvent) {
    if (objEvent) {
      // Stop Propogation
      if (objEvent.preventDefault)
        objEvent.preventDefault();
      if (objEvent.stopPropagation)
        objEvent.stopPropagation();
      objEvent.cancelBubble = true;
      objEvent.returnValue = false;
    };

    return false;
  };
  
/////////////////////////////////
// Controls-related functionality
/////////////////////////////////

	qcodo.getControl = function(mixControl) {
		if (typeof(mixControl) == 'string')
			return document.getElementById(mixControl);
		else
			return mixControl;
	};

	qcodo.getWrapper = function(mixControl) {
		return this.getControl(mixControl);
	};



/////////////////////////////
// Register Control - General
/////////////////////////////
	
	qcodo.controlModifications = new Object;
	qcodo.javascriptStyleToQcodo = new Object;
	qcodo.javascriptStyleToQcodo["backgroundColor"] = "BackColor";
	qcodo.javascriptStyleToQcodo["borderColor"] = "BorderColor";
	qcodo.javascriptStyleToQcodo["borderStyle"] = "BorderStyle";
	qcodo.javascriptStyleToQcodo["border"] = "BorderWidth";
	qcodo.javascriptStyleToQcodo["height"] = "Height";
	qcodo.javascriptStyleToQcodo["width"] = "Width";
	qcodo.javascriptStyleToQcodo["text"] = "Text";

	qcodo.javascriptStyleToQcodo["position"] = "Position";
	qcodo.javascriptStyleToQcodo["top"] = "Top";
	qcodo.javascriptStyleToQcodo["left"] = "Left";

	qcodo.recordControlModification = function(strControlId, strProperty, strNewValue) {
		if (!qcodo.controlModifications[strControlId])
			qcodo.controlModifications[strControlId] = new Object;
		qcodo.controlModifications[strControlId][strProperty] = strNewValue;	
	};

	qcodo.registerControl = function(mixControl) {
		var objControl; 
		objControl = qcodo.getControl(mixControl);

		if(!objControl) return;

		// Add the wrapper to the global qcodo wrappers array
		qcodo.controls[objControl.id] = objControl;


		// Create New Methods, etc.
		// Like: objControl.something = xyz;

		// Updating Style-related Things
		objControl.updateStyle = function(strStyleName, strNewValue) {
			    switch (strStyleName) {
				    case "display":
					    if (strNewValue) {
						    this.style.display = "inline";
					    } else {
						    this.style.display = "none";
					    };
					    break;

					case "className":
						this.className = strNewValue;
						qcodo.recordControlModification(this.id, "CssClass", strNewValue);
						break;

					case "parent":
						if (strNewValue) {
							var objNewParentControl = qcodo.getControl(strNewValue);
							objNewParentControl.appendChild(this);
							qcodo.recordControlModification(this.id, "Parent", strNewValue);
						} else {
							var objParentControl = this.parentNode;
							objParentControl.removeChild(this);
							qcodo.recordControlModification(this.id, "Parent", "");
						};
						break;

					case "displayStyle":
						this.style.display = strNewValue;
						qcodo.recordControlModification(this.id, "DisplayStyle", strNewValue);
						break;

					case "enabled":
						if (strNewValue) {
							$j(this).removeAttr('disabled');
							qcodo.recordControlModification(this.id, "Enabled", "1");
						} else {
							$j(this).attr('disabled','disabled');
							qcodo.recordControlModification(this.id, "Enabled", "0");
						};
						break;

					case "width":
					case "height":
						this.style[strStyleName] = strNewValue;
						if (qcodo.javascriptStyleToQcodo[strStyleName])
							qcodo.recordControlModification(this.id, qcodo.javascriptStyleToQcodo[strStyleName], strNewValue);
						break;

					case "text":
						this.innerHTML = strNewValue;
						qcodo.recordControlModification(this.id, "Text", strNewValue);
						break;

					default:
						if (qcodo.javascriptStyleToQcodo[strStyleName]) {
							this.style[strStyleName] = strNewValue;
							qcodo.recordControlModification(this.id, qcodo.javascriptStyleToQcodo[strStyleName], strNewValue);
						} else {
							this.style[strStyleName] = strNewValue;
							if (qcodo.javascriptStyleToQcodo[strStyleName])
								qcodo.recordControlModification(this.id, qcodo.javascriptStyleToQcodo[strStyleName], strNewValue);
						};
						break;
				};
			};


		// Toggle Display / Enabled
		objControl.toggleDisplay = function(strShowOrHide) {
			// Toggles the display/hiding of the entire control (including any design/wrapper HTML)
			// If ShowOrHide is blank, then we toggle
			// Otherwise, we'll execute a "show" or a "hide"
			if (strShowOrHide) {
				if (strShowOrHide == "show")
					this.updateStyle("display", true);
				else
					this.updateStyle("display", false);
			} else
				this.updateStyle("display", (this.style.display == "none") ? true : false);
		};

		objControl.toggleEnabled = function(strEnableOrDisable) {
			if (strEnableOrDisable) {
				if (strEnableOrDisable == "enable")
					this.updateStyle("enabled", true);
				else
					this.updateStyle("enabled", false);
			} else
				this.updateStyle("enabled", (this.disabled) ? true : false);
		};

		objControl.registerClickPosition = function(objEvent) {
			var intX = objEvent.pageX - this.offsetLeft;
			var intY = objEvent.pageY - this.offsetTop;

			$j('#' + this.id + "_x").val(intX);
			$j('#' + this.id + "_y").val(intY);
		};

		// Blink
		objControl.blink = function(strFromColor, strToColor) {
			$j('#' + this.id).css('background-color', '' + strFromColor);
			$j('#' + this.id).animate({ backgroundColor: '' + strToColor }, 500)
		};
	};

	qcodo.registerControlArray = function(mixControlArray) {
		var intLength = mixControlArray.length;
		for (var intIndex = 0; intIndex < intLength; intIndex++)
			qcodo.registerControl(mixControlArray[intIndex]);
	};
  
  
  
////////////////////////////////
// Logging-related functionality
////////////////////////////////

// TODO: This can be modified to use jQuery

  qcodo.logMessage = function(strMessage, blnReset, blnNonEscape) {
    var objLogger = qcodo.getControl("Qform_Logger");

    if (!objLogger) {
      var objLogger = document.createElement("div");
      objLogger.id = "Qform_Logger";
      objLogger.style.display = "none";
      objLogger.style.width = "400px";
      objLogger.style.backgroundColor = "#dddddd";
      objLogger.style.fontSize = "10px";
      objLogger.style.fontFamily = "lucida console, courier, monospaced";
      objLogger.style.padding = "6px";
      objLogger.style.overflow = "auto";

      if (qcodo.isBrowser(qcodo.IE))
        objLogger.style.filter = "alpha(opacity=50)";
      else
        objLogger.style.opacity = 0.5;

      document.body.appendChild(objLogger);
    };

    if (!blnNonEscape)
      if (strMessage.replace)
        strMessage = strMessage.replace(/</g, '&lt;');

    var strPosition = "fixed";
    var strTop = "0px";
    var strLeft = "0px";
    if (qcodo.isBrowser(qcodo.IE)) {
      // IE doesn't support position:fixed, so manually set positioning
      strPosition = "absolute";
      strTop = qcodo.scroll.y + "px";
      strLeft = qcodo.scroll.x + "px";
    };

    objLogger.style.position = strPosition;
    objLogger.style.top = strTop;
    objLogger.style.left = strLeft;
    objLogger.style.height = (qcodo.client.height - 100) + "px";
    objLogger.style.display = 'inline';

    var strHeader = '<a href="javascript:qcodo.logRemove()">Remove</a><br/><br/>';

    if (blnReset)
      objLogger.innerHTML = strHeader + strMessage + "<br/>";
    else if (objLogger.innerHTML == "")
      objLogger.innerHTML = strHeader + strMessage + "<br/>";
    else
      objLogger.innerHTML += strMessage + "<br/>";
  };

  qcodo.logRemove = function() {
    var objLogger = qcodo.getControl('Qform_Logger');
    if (objLogger)
      objLogger.style.display = 'none';
  };

  qcodo.logEventStats = function(objEvent) {
    objEvent = qcodo.handleEvent(objEvent);

    var strMessage = "";
    strMessage += "scroll (x, y): " + qcodo.scroll.x + ", " + qcodo.scroll.y + "<br/>";
    strMessage += "scroll (width, height): " + qcodo.scroll.width + ", " + qcodo.scroll.height + "<br/>";
    strMessage += "client (x, y): " + qcodo.client.x + ", " + qcodo.client.y + "<br/>";
    strMessage += "client (width, height): " + qcodo.client.width + ", " + qcodo.client.height + "<br/>";
    strMessage += "page (x, y): " + qcodo.page.x + ", " + qcodo.page.y + "<br/>";
    strMessage += "page (width, height): " + qcodo.page.width + ", " + qcodo.page.height + "<br/>";
    strMessage += "mouse (x, y): " + qcodo.mouse.x + ", " + qcodo.mouse.y + "<br/>";
    strMessage += "mouse (left, middle, right): " + qcodo.mouse.left + ", " + qcodo.mouse.middle + ", " + qcodo.mouse.right + "<br/>";
    strMessage += "key (alt, shift, control, code): " + qcodo.key.alt + ", " + qcodo.key.shift + ", " +
      qcodo.key.control + ", " + qcodo.key.code;

    qcodo.logMessage("Event Stats", true);
    qcodo.logMessage(strMessage, false, true);
  };

  qcodo.logObject = function(objObject) {
    var strDump = "";

    for (var strKey in objObject) {
      var strData = objObject[strKey];

      strDump += strKey + ": ";
      if (typeof strData == 'function')
        strDump += "&lt;FUNCTION&gt;";
      else if (typeof strData == 'object')
        strDump += "&lt;OBJECT&gt;";
      else if ((strKey == 'outerText') || (strKey == 'innerText') || (strKey == 'outerHTML') || (strKey == 'innerHTML'))
        strDump += "&lt;TEXT&gt;";
      else
        strDump += strData;
      strDump += "<br/>";
    };

    qcodo.logMessage("Object Stats", true);
    qcodo.logMessage(strDump, false, true);
  };

///////////////////////////////
// Event Stats-Releated Objects
///////////////////////////////

  qcodo.key = {
    control: false,
    alt: false,
    shift: false,
    code: null
  };

  qcodo.mouse = {
    x: 0,
    y: 0,
    left: false,
    middle: false,
    right: false
  };

  qcodo.client = {
    x: null,
    y: null,
    width: null,
    height: null
//    width: (qcodo.isBrowser(qcodo.IE)) ? window.document.body.clientWidth : window.innerWidth,
//    height: (qcodo.isBrowser(qcodo.IE)) ? window.document.body.clientHeight : window.innerHeight
  };

  qcodo.page = {
    x: null,
    y: null,
    width: null,
    height: null
//    width: window.document.body.scrollWidth,
//    height: window.document.body.scrollHeight
  };

  qcodo.scroll = {
    x: window.scrollX || (window.document.body) ? window.document.body.scrollLeft : null,
    y: window.scrollY || (window.document.body) ? window.document.body.scrollTop : null,
//    x: null,
//    y: null,
    width: (window.document.body) ? (window.document.body.scrollWidth - qcodo.client.width) : null,
    height: (window.document.body) ? (window.document.body.scrollHeight - qcodo.client.height) : null
//    width: null,
//    height: null
  };

  
////////////////////////////////
// Qcodo Shortcut and Initialize
////////////////////////////////

	var qc = qcodo;
	qc.initialize();

	qc.pB = qcodo.postBack;
	qc.pA = qcodo.postAjax;
  
	qc.getC = qcodo.getControl;
	qc.getW = qcodo.getWrapper;
	qc.regC = qcodo.registerControl;
	qc.regCA = qcodo.registerControlArray;
  
// Attach the formstate and id to the form
$j(document).ready(function() {
  var strFormId = $j('#Qform__FormId').val();
  $j('#' + strFormId).append($j('#qcodo-state-id'));
});
