﻿Type.registerNamespace("Infragistics.Web.UI");


$IG.CallbackRequestHandler = function(manager, callbackObject, async)
{
	/// <summary>
	/// Handles a CallbackObject's request and resposne.
	/// </summary>
	var me = this;
	this._callbackObject = callbackObject;
	this._manager = manager;
	this._async = async;

	this._responseComplete = function()
	{
		if (me._request.readyState === 4 && me._request.status == "200")
		{
			window.clearTimeout(me._timerId);
			var response = me._request.responseText;
			if (response != null && response.length > 0)
			{
				var obj = Sys.Serialization.JavaScriptSerializer.deserialize(response)
				document.getElementById("__VIEWSTATE").value = obj[0];
				var eventValidation = document.getElementById("__EVENTVALIDATION");
				if (eventValidation)
					eventValidation.value = obj[1];
				me._manager._requestCompleted(me, me._callbackObject, obj[2]);
				for (var i in obj[3])
				{
					var id = obj[3][i][0];
					var ctrlObj = $find(id);
					if (ctrlObj && ctrlObj.dispose)
						ctrlObj.dispose();
					var x = eval(obj[3][i][1]);
				}
			}
			else
			{
				me._timedOut();
			}

			me._callbackObject = null;
			me._manager = null;
			me._request = null;
		}
		else if (me._request.readyState === 4)
			me._manager._requestFailed(me, me._callbackObject);		
	}
}

$IG.CallbackRequestHandler.prototype =
{
	execute: function()
	{
		/// <summary>
		/// Executes a XmlHttpRequest to the server
		/// </summary>
		this._request = null;
		if (typeof XMLHttpRequest != "undefined")
			this._request = new XMLHttpRequest();
		else if (typeof ActiveXObject != "undefined")
		{
			try { this._request = ig_createActiveXFromProgIDs(["MSXML2.XMLHTTP", "Microsoft.XMLHTTP"]); } catch (e) { }
		}

		if (this._request)
		{
			this._request.open(this._manager.getHttpVerb(), this._manager.getUrl(), this._async);
			this._request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
			this._request.onreadystatechange = this._responseComplete;
			this._timerId = window.setTimeout(Function.createDelegate(this, this._timedOut), this._manager.getTimeout());
			this._request.send(this._getArgs());
		}
	},

	_getArgs: function()
	{
		var form = this._manager._getForm();
		if (!form) return;

		// Ensures that all Infragistics Controls have their PostData set.
		if (typeof ig_controls == 'object')
			for (var id in ig_controls)
			ig_controls[id]._onIgSubmit();

		var count = form.elements.length;
		var element;
		for (var i = 0; i < count; i++)
		{
			element = form.elements[i];
			if (element.tagName.toLowerCase() == "input" && (element.type == "hidden" || element.type == 'password' || element.type == 'text' || ((element.type == "checkbox" || element.type == 'radio') && element.checked)))
				this._addCallbackField(element.name, element.value);
			else if (element.tagName.toLowerCase() == "textarea")
				this._addCallbackField(element.name, element.value);
			else if (element.tagName.toLowerCase() == "select")
			{
				var o = element.options.length;
				while (o-- > 0)
				{
					if (element.options[o].selected)
						this._addCallbackField(element.name, element.options[o].value);
				}
			}
		}

		var args = this._postdata + "__EVENTTARGET=&__EVENTARGUMENT=&__IGCallback_" + this._manager._control._id + "=";
		args += Sys.Serialization.JavaScriptSerializer.serialize(this._callbackObject._getServerData());
		return args;
	},

	_addCallbackField: function(name, value)
	{
		if (!this._postdata)
			this._postdata = "";
		this._postdata += name + "=" + this._encodeValue(value) + "&";
	},

	_encodeValue: function(uri)
	{
		if (encodeURIComponent != null)
			return encodeURIComponent(uri);
		else
			return escape(parameter);
	},

	_timedOut: function()
	{
		this._manager._requestFailed(this, this._callbackObject, true);
	}
};
$IG.CallbackRequestHandler.registerClass("Infragistics.Web.UI.CallbackRequestHandler");



$IG.ControlCallbackManager = function(control)
{
	/// <summary>
	/// An object in charge of managin all Callbacks for an Infragistics.Web.UI.Control.
	/// </summary>
	this._control = control;
	this._httpVerb = "POST"
	this._async = true;
	this._timeout = 20000;
	this._url = this._getForm().action;

	this._currentRequests = 0;
	this._callbackQueue = [];
}

$IG.ControlCallbackManager.prototype =
{
	createCallbackObject: function(control)
	{
		/// <summary>
		/// Creates a new CallbackObject for the control.
		/// </summary>
		if (!control)
			control = this._control;
		return new $IG.CallbackObject(control);
	},

	execute: function(callback, queue, async)
	{
		/// <summary>
		/// Initiates an XmlHTTPRequest for the specified CallbackObject.
		/// </summary>
		if (callback)
		{
			if (async == null)
				async = this.getAsync();
			var requestHandler = new $IG.CallbackRequestHandler(this, callback, async);

			if (queue && this._currentRequests > 0)
				this._pushCallback(requestHandler)
			else
			{
				this._currentRequests++;
				requestHandler.execute();
			}
		}
	},

	_pushCallback: function(callback)
	{
		this._callbackQueue.push(callback);
	},

	_popCallback: function()
	{
		for (var i = 0; i < this._callbackQueue.length; i++)
		{
			var requestHandler = this._callbackQueue[i];
			if (requestHandler != null)
			{
				delete this._callbackQueue[i];
				this._currentRequests++;
				requestHandler.execute();
			}
		}
	},

	getAsync: function()
	{
		/// <summary>
		/// Get/Sets whether or not the Callback should be Async.
		/// The Default is true.
		/// </summary>
		return this._async;
	},
	setAsync: function(val) { return this._async; },

	getHttpVerb: function()
	{
		/// <summary>
		/// Get/Sets the HTTP Verb for the Callback.
		/// The Default is "Post"
		/// </summary>
		return this._httpVerb;
	},
	setHttpVerb: function(verb) { this._httpVerb = verb; },

	getUrl: function()
	{
		/// <summary>
		/// Get/Sets the url for the Callback. 
		/// The default is the current form's action.
		/// </summary>
		return this._url;
	},
	setUrl: function(url) { this._url = url; },

	getTimeout: function()
	{
		/// <summary>
		/// Get/Sets the amount of time (in ms) that is allowed to pass before failing the Callback.
		/// The default is 20000
		/// </summary>
		return this._timeout;
	},
	setTimeout: function(val) { this._timeout = val; },

	_getForm: function()
	{
		if (!this._form)
		{
			if (document.forms.length > 1)
			{
				for (var i = 0; i < document.forms.length; i++)
				{
					if (document.forms[i].method == "post" && document.forms[i].action != "")
					{
						this._form = document.forms[i];
						break;
					}
				}
				if (!this._form)
					this._form = document.forms[0];
			}
			else
				this._form = document.forms[0];
			if (!this._form)
				this._form = document.form1;
		}
		return this._form
	},

	_endRequest: function()
	{
		this._currentRequests--;
		if (this._callbackQueue.length > 0)
			this._popCallback();
	},

	setResponseComplete: function(func, context)
	{
		/// <summary>
		/// Sets the method that should be called when the Callback has returned from the server. 
		/// </summary>
		this._responseCompleteFunction = func;
		if (!context)
			context = this._control;
		this._responseCompleteContext = context;
	},

	_requestFailed: function(requestHandler, callbackObject, timedOut)
	{
		window.clearTimeout(requestHandler._timerId);
		if (requestHandler._request.readyState == 4)
			callbackObject._responseCompleteError(requestHandler._request, timedOut);
		this._endRequest();
		requestHandler._request.abort();
		requestHandler._request = null;
	},

	_requestCompleted: function(requestHandler, callbackObject, responseObject)
	{
		this._endRequest();
		this._recursiveResponseCompleted(callbackObject, responseObject, requestHandler._request);
	},

	_recursiveResponseCompleted: function(callbackObject, responseObject, browserResponseObject)
	{
		this._responseComplete(callbackObject, responseObject, browserResponseObject);
		for (var i = 0; i < callbackObject._childCallbacks.length; i++)
			this._recursiveResponseCompleted(callbackObject._childCallbacks[i], responseObject.children[i], browserResponseObject);
	},

	_responseComplete: function(callbackObject, responseObject, browserResponseObject)
	{
		if (!callbackObject._responseComplete(responseObject, browserResponseObject))
		{
			if (this._responseCompleteFunction)
				this._responseCompleteFunction.apply(this._responseCompleteContext, [callbackObject, responseObject, browserResponseObject]);
		}
		callbackObject.dispose();
	},

	dispose: function()
	{
		this._control = null;
		this._form = null;
		this._responseCompleteContext = null;
	}

};
$IG.ControlCallbackManager.registerClass("Infragistics.Web.UI.ControlCallbackManager");



$IG.CallbackObject = function(control)
{
	/// <summary>
	/// An object that contains information about a Callback that should be made to the server.
	/// </summary>
	this._control = control;
	this.serverContext = {};
	this.clientContext = {};
	this._childCallbacks = [];
}

$IG.CallbackObject.prototype =
{
	createCallbackObject: function(control)
	{
		/// <summary>
		/// Creates a child CallbackObject of the current CallbackObject
		/// </summary>
		if (!control)
			control = this._control;
		var callbackObject = new $IG.CallbackObject(control);
		this._childCallbacks.push(callbackObject);
		return callbackObject;
	},

	getId: function()
	{
		/// <summary>
		/// Returns the id of the control that is attached to the callback.
		/// </summary>
		return this._control._id;
	},

	getServerContext: function()
	{
		/// <summary>
		/// Returns the JSON object that will be used to pass infomration to the server about the specific Callback
		/// </summary>    
		return this.serverContext;
	},
	getClientContext: function()
	{
		/// <summary>
		/// Returns the JSON object that will be used to pass infomration to the ResponseComplete event of the Callback.
		/// </summary>    
		return this.clientContext;
	},

	setResponseComplete: function(func, context, funcError)
	{
		/// <summary>
		/// Sets an event listener for the ResponseComplete event of the CallbackObject
		/// </summary>    
		this._responseCompleteFunction = func;
		this._responseCompleteErrorFunction = funcError;
		if (!context)
			context = this._control;
		this._responseCompleteContext = context;
	},

	_responseComplete: function(responseObj, browserResponseObject)
	{
		if (this._responseCompleteFunction)
		{
			this._responseCompleteFunction.apply(this._responseCompleteContext, [this, responseObj, browserResponseObject]);
			return true;
		}
		else if (typeof (this._control._responseComplete) != "undefined")
		{
			this._control._responseComplete(this, responseObj, browserResponseObject);
			return true;
		}
		return false;
	},

	_responseCompleteError: function(responseObj, timedOut)
	{
		if (this._responseCompleteErrorFunction)
		{
			this._responseCompleteErrorFunction.apply(this._responseCompleteContext, [this, responseObj, timedOut]);
			return true;
		}
		else if (typeof (this._control._responseCompleteError) != "undefined")
		{
			this._control._responseCompleteError(this, responseObj, timedOut);
			return true;
		}
		return false;
	},

	_getServerData: function()
	{
		var data = { id: this._control.get_uniqueID(), context: this.serverContext, children: [] };
		for (var i = 0; i < this._childCallbacks.length; i++)
			data.children[i] = this._childCallbacks[i]._getServerData();
		return data;
	},

	dispose: function()
	{
		this._control = null;
		this.serverContext = null;
		this.clientContext = null;
	}

};
$IG.CallbackObject.registerClass("Infragistics.Web.UI.CallbackObject");

if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();