﻿Type.registerNamespace("Infragistics.Web.UI");

var $IG = Infragistics.Web.UI;

if (typeof ig_controls != "object")
	var ig_controls = new Object();


$IG.ControlMainProps = new function()
{
	/// <summary>For internal use only.</summary>
	this.Flags = [0, 0];
	this.Count = 1;
};



$IG.ControlMain = function(elem)
{
	///<summary>
	/// The client side base class for all Infragistics.Web.UI.Controls.
	///</summary>
	$IG.ControlMain.initializeBase(this, [elem]);
	this._elements = {};
	this._callbackManager = new $IG.ControlCallbackManager(this);
	this._callbackManager.setResponseComplete(this._responseComplete, this);
}
$IG.ControlMain.prototype =
{
	
	initialize: function()
	{
		///<summary>
		/// For Internal Use Only.
		/// Called from the control's constructor, it sets up all information needed by the control.
		///</summary>	    
		this._setupCollections();
		//var now1  = new Date();

		this.__walkThrough(this._element, true);

		this._setupMarkerElements();
		$IG.ControlMain.callBaseMethod(this, 'initialize');
		this.__attachEvents();
		this.__attachOtherEvents();
		this._uniqueID = this._get_clientOnlyValue("uid");
		ig_controls[this._id] = this;

		var clientState = document.getElementById(this._id + "_clientState");
		if (clientState && clientState.value)
		{
			this.__previousClientState = clientState.value;
			clientState.value = "";
		}

		var rm = null;
		try
		{
			rm = Sys.WebForms.PageRequestManager.getInstance();
		} catch (e) { }
		if (rm && !rm._ig_onsubmit)
		{
			rm._ig_onsubmit = rm._onsubmit;
			if (!rm._ig_onsubmit)
				rm._ig_onsubmit = 2;
			var form = rm._form;
			if (form && typeof theForm == 'object')
				form = theForm;
			if (form && !form._ig_submit)
			{
				form._ig_submit = form.submit;
				form.submit = function()
				{
					try
					{
						if (typeof ig_controls == 'object')
							for (var id in ig_controls)
							ig_controls[id]._onIgSubmit();
					} catch (e) { }
					if (this._ig_submit)
						this._ig_submit();
				}
			}
			rm._onsubmit = function()
			{
				if (typeof ig_controls == 'object')
					for (var id in ig_controls)
					ig_controls[id]._onIgSubmit();
				if (typeof this._ig_onsubmit == 'function') try
				{
					if (this._ig_onsubmit() === false)
						return false;
				} catch (id) { }
				return true;
			}
		}
	},

	dispose: function()
	{
		///<summary>
		/// For Internal Use Only.
		/// Disposes of all objects that belong to the control.
		///</summary>
		if (this._objectsManager)
			this._objectsManager.dispose();
		if (this._collectionsManager)
			this._collectionsManager.dispose();
		if (this._callbackManager)
			this._callbackManager.dispose();
		if (this.get_element())
			$clearHandlers(this.get_element());
		this.__clearOtherEvents();

		if (this._flags != null)
			this._flags.dispose();

		this._dataStore = null;
		for (var p in this._elements)
			delete this._elements[p];

		$IG.ControlMain.callBaseMethod(this, 'dispose');
	},
	

	
	__attachEvents: function()
	{
		this._addHandlers();
		if (this._handlers && this._handlers.length > 0)
		{
			var evnts = {};
			for (var i in this._handlers)
			{
				var evnt = this._handlers[i];
				evnts[evnt] = this._onEventHandler;
			}
			$addHandlers(this.get_element(), evnts, this);
		}
	},

	__clearOtherEvents: function()
	{
		for (var array in this._otherHandlers)
		{
			for (var evnt in this._otherHandlers[array])
			{
				var element = this._otherHandlers[array][evnt];
				if (element._events && element._events[evnt] && element._events[evnt].length > 0)
					try
				{
					$removeHandler(element, evnt, this.__otherHandlerDelegate);
				} catch (exc) { }
			}
		}
		this._otherHandlers = null;
	},

	__attachOtherEvents: function()
	{
		this._addOtherHandlers();
		
		this.__otherHandlerDelegate = Function.createDelegate(this, this._onOtherEventHandler);
		if (this._otherHandlers && this._otherHandlers.length > 0)
		{
			for (var array in this._otherHandlers)
			{
				for (var evnt in this._otherHandlers[array])
					$addHandler(this._otherHandlers[array][evnt], evnt, this.__otherHandlerDelegate);
			}
		}
	},

	_handleEvent: function(elem, adrElement, adr, e)
	{
		var func = this["_on" + e.type.substring(0, 1).toUpperCase() + e.type.substring(1) + "Handler"];
		if (func)
			func.apply(this, [e.target, adr, e]);
	},

	__walkThrough: function(elem, topItem)
	{
		if ($util._initAttr(elem))
		
			if (!topItem)
			return;
		var adr = elem.getAttribute("adr");
		var mkr = elem.getAttribute("mkr");
		var obj = elem.getAttribute("obj");

		if (adr)
			this._createItem(elem, adr);
		else if (obj)
			this._createObject(elem, obj);
		else if (mkr)
		{
			
			var mkrAr = mkr.split(',');
			for (var i = 0; i < mkrAr.length; i++)
			{
				mkr = mkrAr[i];
				
				if (typeof (this._elements[mkr]) != "undefined")
				{
					var mkrElem = this._elements[mkr];
					if (typeof (mkrElem.length) == "undefined")
						mkrElem = this._elements[mkr] = [this._elements[mkr]];
					mkrElem[mkrElem.length] = elem;

				}
				else
					this._elements[mkr] = elem;
			}
		}

		// AK - moved down here. The element itself should be counted, but its children should not.
		// donp - added this check to ensure that we don't walk down into other controls using adr tags (as in templates)
		// control must define this attribute on an element that is not meant to be walked.
		var ctl = elem.getAttribute("nw");
		if (ctl)
			return;

		var children = elem.childNodes;
		for (var i = 0; i < children.length; i++)
		{
			var element = children[i];
			if (element.getAttribute)
				this.__walkThrough(element, false);
		}
	},

	__getViewStateEnabled: function()
	{
		var vse = this._get_clientOnlyValue("vse");
		if (vse == null)
			return true;
		else if (vse == 0)
			return false;
		else if (vse == 1)
			return true;
	},

	

	
	_onEventHandler: function(e)
	{
		var obj = $util.resolveMarkedElement(e.target, true);

		if (obj != null)
		{
			
			if (obj[2] == this)
				this._handleEvent(e.target, obj[0], obj[1], e);
		}
	},

	_onIgSubmit: function()
	{
		
		var oldT = this._ig_submit_time, newT = (new Date()).getTime();
		if (oldT && newT < oldT + 99)
			return;
		this._ig_submit_time = newT;
		this._onSubmitOtherHandler();
	},

	_onOtherEventHandler: function(e)
	{
		if (!e)
			return;
		if (e.type == 'submit')
		{
			this._onIgSubmit();
			return;
		}
		if (e.type != null)
		{
			var func = this["_on" + e.type.substring(0, 1).toUpperCase() + e.type.substring(1) + "OtherHandler"];
			if (func)
				func.apply(this, [e.target, e])
		}
	},

	_onSubmitOtherHandler: function(e)
	{
		var clientState = document.getElementById(this._id + "_clientState");
		if (clientState)
		{
			var vse = this.__getViewStateEnabled();
			var state = [[this._clientStateManager.get_serverProps(vse), this._objectsManager.getServerObjects(vse), this._collectionsManager.getServerCollection(vse)]];

			state[1] = [this._clientStateManager.get_transactionList(),
	                     this._collectionsManager.get_allTransactionLists()];

			state[2] = this._saveAdditionalClientState();

			clientState.value = Sys.Serialization.JavaScriptSerializer.serialize(state);
		}

	},

	_onBeforeunloadOtherHandler: function(e)
	{
	},

	

	
	_setupMarkerElements: function()
	{

	},
	_addHandlers: function()
	{
		
	},

	_addOtherHandlers: function()
	{
		this._registerOtherHandlers([{ "submit": theForm, "beforeunload": window}]);
	},

	_createItem: function(element, adr)
	{

	},

	_createObject: function(element, obj)
	{

	},

	_responseComplete: function(callbackObject, responseObject)
	{

	},

	_responseCompleteError: function(callbackObject, responseObject)
	{

	},

	_setupCollections: function()
	{
		this._itemCollection = this._collectionsManager.register_collection(0, $IG.ObjectCollection);
	},

	_saveAdditionalClientState: function()
	{
	},

	


	

	_set_value: function(index, value)
	{
		this._clientStateManager.set_value(index, value);
	},

	_get_value: function(index, isBool)
	{
		return this._clientStateManager.get_value(index, isBool);
	},

	_get_clientOnlyValue: function(propName)
	{
		return this._clientStateManager.get_clientOnlyValue(propName);
	},

	_get_occasionalProperty: function(propName)
	{
		return this._clientStateManager.get_occasionalProperty(propName);
	},

	_set_occasionalProperty: function(propName, val)
	{
		this._clientStateManager.set_occasionalProperty(propName, val);
	},

	_cancelEvent: function(e)
	{
		e.stopPropagation();
		e.preventDefault();
	},

	_registerHandlers: function(handlers)
	{
		if (!this._handlers)
			this._handlers = [];

		this._handlers = this._handlers.concat(handlers);
	},

	_registerOtherHandlers: function(handlers)
	{
		if (!this._otherHandlers)
			this._otherHandlers = [];

		this._otherHandlers = this._otherHandlers.concat(handlers);
	},

	_add_item: function(adr, item)
	{
		this._items[adr] = item;
		this.__itemCount++;
	},

	_remove_item: function(adr)
	{
		if (adr in this._items)
		{
			delete this._items[adr];
			this.__itemCount--;
		}
	},

	_initClientEvents: function(vals)
	{
		this._initClientEventsForObject(this, vals);
	},
	_initClientEventsForObject: function(owner, vals)
	{
		owner._clientEvents = new Object();
		var i = vals ? vals.length : 0;
		while (i-- > 0)
		{
			var evt = vals[i].split(':');
			this.setClientEvent(owner, evt[0], evt[1], evt[2]);
		}
	},
	
	
	
	
	_postAction: function(args, evtName)
	{
		var act = args._props ? args._props[1] : args;
		if (act == 1)
		{
			
			// ??
			
			
			__doPostBack(this._id, evtName + (args._getPostArgs ? args._getPostArgs() : ''));
			this._posted = true;
		}
		if (act == 2)
		{
			
			// ??
			var cb = this._callbackManager.createCallbackObject();
			
			
			cb.serverContext.eventName = evtName;
			
			var i = args._props ? args._props.length : 0;
			while (--i > 1)
				eval('cb.serverContext.props' + (i - 2) + '="' + args._props[i] + '"');
			if (args._context)
			{
				for (var contextProp in args._context)
					cb.serverContext[contextProp] = args._context[contextProp];
			}
			
			if (this._filterAsyncPostBack)
				this._filterAsyncPostBack(cb.serverContext, evtName, args);
			this._callbackManager.execute(cb);
			this._posted = true;
		}
	},

	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	_raiseClientEventStart: function(param)
	{
		var params = param; 
		if (params.substring)
			params = arguments;
		return this._raiseCE_0(this, params[0], this.getClientEventPostBack(params[0]), params[1], params);
	},
	_raiseClientEvent: function(param)
	{
		var args = this._raiseClientEventStart(param.substring ? arguments : param);
		return args ? this._raiseClientEventEnd(args, args._name) : null;
	},
	_raiseClientEventEnd: function(args)
	{
		///<summary>Triggers possible post back to end client event processing.</summary>
		///<param name="args">Event arguments.</param>
		///<returns>First parameter</returns>
		if (args && args._props && !(args.get_cancel && args.get_cancel()))
			this._postAction(args, args._name);
		return args;
	},
	_raiseSenderClientEvent: function(sender, clientEvent, eventArgs)
	{
		///<summary>Raises and triggers post back for a notify event.</summary>
		///<param name="sender">Object that raises the event and contains the clientEvents array.</param>
		///<param name="clientEvent">Client event object.</param>
		///<param name="eventArgs">Event arguments. Generally an object derived from Infragistics.Web.UI.CancelEventArgs.</param>
		///<returns>Event arguments object, the same object that is passed as the third parameter.</returns>
		eventArgs = this._raiseSenderClientEventStart(sender, clientEvent, eventArgs);
		return this._raiseClientEventEnd(eventArgs);
	},
	_raiseSenderClientEventStart: function(sender, clientEvent, eventArgs)
	{
		///<summary>Raises a cancelable before event but does not trigger post back.</summary>
		///<param name="sender">Object that raises the event and contains the clientEvents array.</param>
		///<param name="clientEvent">Client event object.</param>
		///<param name="eventArgs">Event arguments. Generally an object derived from Infragistics.Web.UI.CancelEventArgs.</param>
		///<returns>Event arguments object, the same object that is passed as the third parameter.</returns>
		return this._raiseCE_0(sender, clientEvent.name, clientEvent.postBack, eventArgs);
	},
	_raiseCE_0: function(me, evtName, post, args, params)
	{
		var fnc = me.get_events().getHandler(evtName);
		var str = args && args.substring;
		
		if (!fnc && post == null)
			return str ? null : args;
		if (str)
			eval('try{args = new Infragistics.Web.UI.' + args + 'EventArgs();}catch(ex){args = null;}');
		var i = 1, len = params ? params.length : 0;
		if (!args)
			args = (len < 3) ? new Sys.EventArgs() : new $IG.EventArgs();
		
		if (args._props)
			while (++i < len) if (params[i] != null)
			args._props[i - 2] = params[i];
		
		if (post)
		{
			if (!args._props)
				args._props = new Array();
			if (!args._props[1] || args._props[1] == 0)
				args._props[1] = post;
		}
		
		if (fnc)
			fnc(this, args);
		if (args._props)
			delete args._props[0];
		args._name = evtName;
		return args;
	},

	_getFlags: function()
	{
		if (this._flags == null)
		{
			this.__flagHelper = new $IG.FlagsHelper();
			var key = [$IG.ObjectBaseProps.Count + 0, this.__getDefaultFlags()]
			this._flags = new $IG.FlagsObject(this._get_value(key), this);
		}
		return this._flags;
	},

	_updateFlags: function(flags)
	{
		var key = [$IG.ObjectBaseProps.Count + 0, this.__getDefaultFlags()]
		this._set_value(key, flags)
	},

	_ensureFlags: function()
	{
		this._ensureFlag($IG.ClientUIFlags.Visible, $IG.DefaultableBoolean.True);
		this._ensureFlag($IG.ClientUIFlags.Enabled, $IG.DefaultableBoolean.True);
	},

	__getDefaultFlags: function()
	{
		if (this.__defaultFlags == null)
		{
			this._ensureFlags();
			this.__defaultFlags = this.__flagHelper.calculateFlags();
		}
		return this.__defaultFlags;
	},

	_ensureFlag: function(flag, val)
	{
		this.__flagHelper.updateFlag(flag, val);
	},

	

	

	_get_clientStateManager: function() { return this._clientStateManager; },

	_get_item: function(adr)
	{
		return this._itemCollection._getObjectByAdr(adr);
	},

	

	
	set_id: function(id)
	{
		///<summary>Sets id of control.</summary>
		///<param name="id">Id of control.</param>
		this._id = id;
	},
	get_name: function(name)
	{
		///<summary>
		/// Return's the name of the control. 
		///</summary>
		return this.get_element().name;
	},
	set_name: function(value)
	{
		///<summary>Sets name of html element.</summary>
		///<param name="value">Name for element.</param>
		this.get_element().name = value;
	},
	get_uniqueID: function()
	{
		///<summary>
		/// Return's the Unique ID of the control. 
		///</summary>
		return this._uniqueID
	},

	
	
	addClientEventHandler: function(owner, evtName, fnc)
	{
		///<summary>
		/// Adds a function handler to process a ClientEvent.
		///</summary>
		$util.addClientEvent(owner, evtName, fnc);
	},
	removeClientEventHandler: function(owner, evtName, fnc)
	{
		///<summary>
		/// Removes a function handler of a ClientEvent.
		///</summary>
		$util.removeClientEvent(owner, evtName, fnc);
	},

	getClientEventPostBack: function(name)
	{
		/// <summary>For internal use only.</summary>
		/// <param name="name" type="String" mayBeNull="false">Name of ClienEvent.</param>
		/// <returns type="Number">Postback action.</returns>
		return this.getClientEventPostBackForObject(this, name);
	},
	getClientEventPostBackForObject: function(owner, name)
	{
		/// <summary>For internal use only.</summary>
		/// <param name="owner" type="Object">Reference to owner control.</param>
		/// <param name="name" type="String" mayBeNull="false">Name of ClienEvent.</param>
		/// <returns type="Number">Postback action.</returns>
		var ce = owner._clientEvents[name];
		return ce ? ce.postBack : null;
	},
	setClientEvent: function(owner, evtName, fnc, postBack)
	{
		/// <summary>For internal use only.</summary>
		/// <param name="owner" type="Object">Reference to owner control.</param>
		/// <param name="evtName" type="String" mayBeNull="false">Name of ClientEvent.</param>
		/// <param name="fnc" type="Object">Function to call.</param>
		/// <param name="postBack" type="Number">Postback action.</param>
		
		if (postBack)
			postBack = parseInt(postBack, 10);
		else
			postBack = 0;
		owner._clientEvents[evtName] = { name: evtName, fnc: fnc, postBack: postBack };
		if (evtName && fnc)
			this.addClientEventHandler(owner, evtName, fnc);
	},

	get_props: function()
	{
		///<summary>
		/// For Internal Use Only.
		/// Contains ClientState information for the control.
		///</summary>
		return this._props;
	},
	set_props: function(value)
	{
		/// <summary>Internal use only.</summary>
		/// <param name="value">Properties for subobjects.</param>
		this._dataStore = value;
		this._props = value[0];
		this._clientStateManager = new $IG.ObjectClientStateManager(this._props);
		this._objectsManager = new $IG.ObjectsManager(this, value[1]);
		this._collectionsManager = new $IG.CollectionsManager(this, value[2]);
		this._initClientEvents(value[3]);
	}
	
}
$IG.ControlMain.registerClass('Infragistics.Web.UI.ControlMain', Sys.UI.Control);



$IG.NavControlProps = new function()
{
	this.Count = $IG.ControlMainProps.Count + 0;
};




$IG.NavControl = function(elem)
{
	/// <summary>
	/// Represents a control class for hierarchical data controls. 
	/// </summary>
	$IG.NavControl.initializeBase(this, [elem]);
}

$IG.NavControl.prototype =
{
	initialize: function()
	{
		$IG.NavControl.callBaseMethod(this, 'initialize');
	},

	_setupCollections: function()
	{
		this._itemCollection = this._collectionsManager.register_collection(0, $IG.NavItemCollection);
		this._collectionsManager.registerUIBehaviors(this._itemCollection);
	}
}

$IG.NavControl.registerClass('Infragistics.Web.UI.NavControl', $IG.ControlMain);


