﻿Type.registerNamespace("Infragistics.Web.UI");

var $IG = Infragistics.Web.UI;

if (typeof ig_controls != "object")
	var ig_controls = new Object();

/******************************************ControlMainProps ENUM************************************/
$IG.ControlMainProps = new function()
{
	/// <summary>For internal use only.</summary>
	this.Flags = [0, 0];
	this.Count = 1;
};
/******************************************END ControlMainProps ENUM********************************/

/******************************************CONTROL MAIN********************************************/
$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.__responseCompleteInternal, this);
}
$IG.ControlMain.prototype =
{
	/**********OVERRIDES**************/
	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;
		/* flag to skip creation of ajaxIndicator */
		if (!$util._skip_pi)
		{
			$util.get_ajaxIndicator(this._get_clientOnlyValue('_pi'));
			var pi = this._get_clientOnlyValue('pi');
			if (pi && !this._pi)
				this._pi = new $IG.AjaxIndicator(pi);
		}
		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();
				var rm = this;
				/* VS 05/15/2009 Bug 17647. That can be called by __doPostBack directly while full postback and validators will be skipped */
				if (!rm._ig_onsubmit)
					rm = Sys.WebForms.PageRequestManager.getInstance();
				if (typeof rm._ig_onsubmit == 'function') try
				{
					if (rm._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._pi)
		{
			this._pi.dispose();
			delete this._pi;
		}
		if (this._flags != null)
			this._flags.dispose();

		this._dataStore = null;
		for (var p in this._elements)
			delete this._elements[p];
		
		/* OK 8/19/2009 - deleting the control from ig_controls as the control may not be coming back */
		delete ig_controls[this._id]; 
		$IG.ControlMain.callBaseMethod(this, 'dispose');
	},
	/**********END OVERRIDES**************/

	/********PRIVATE METHODS***********/
	__attachEvents: function()
	{
		this._addHandlers();
		var handlers = this._handlers;
		var i = handlers ? handlers.length : 0;
		if (i > 0)
		{
			var evnts = {};
			while (i-- > 0)
			{
				var evnt = handlers[i];
				evnts[evnt] = this._onEventHandler;
			}
			$addHandlers(this.get_element(), evnts, this);
		}
	},

	__clearOtherEvents: function()
	{
		var handlers = this._otherHandlers;
		var i = handlers ? handlers.length : 0;
		while (i-- > 0)
		{
			for (var evnt in handlers[i])
			{
				var element = handlers[i][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();
		/*SJZ - Need to keep a reference to the delegate, so that we can remove it from the elements later */
		this.__otherHandlerDelegate = Function.createDelegate(this, this._onOtherEventHandler);
		var handlers = this._otherHandlers;
		var i = handlers ? handlers.length : 0;
		while (i-- > 0)
			for (var evnt in handlers[i])
			$addHandler(handlers[i][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))
		/* condition to stop walk: not main element and elem has normal id */
			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)
		{
			/*AK 10/20/2008 Adding ability to have more than one marker. Should be separated by a comma*/
			/* OK 4/28/2009 17043 - changed the splitting character to be a period instead of a comma.*/
			var mkrAr = mkr.split('.');
			for (var i = 0; i < mkrAr.length; i++)
			{
				mkr = mkrAr[i];
				/* AK 1/23/2008 Bunching elements with the same marker */
				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;
	},

	/*********END PRIVATE METHODS*********/

	/*********EVENT HANDLERS***************/
	_onEventHandler: function(e)
	{
		var obj = $util.resolveMarkedElement(e.target, true);

		if (obj != null)
		{
			/* SJZ 9/11/07 - obj[2] is the control object on the element's parent. 
			* We need to make sure that the control this event is firing for
			* is our actual control, and not the control's parent, which could also inherit from ControlMain*/
			if (obj[2] == this)
				this._handleEvent(e.target, obj[0], obj[1], e);
		}
	},

	_onIgSubmit: function()
	{
		/* request for submit may come from different places, to avoid multiple processing set this._ig_submit_time flag */
		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])
		}
	},

	_get_CS: function() { return $get(this._id + '_clientState'); },
	_onSubmitOtherHandler: function(e)
	{
		var clientState = this._get_CS();
		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);
		}

	},

	__bs: ['[[[[]],[],[]],[{},[]],"', '"]'],
	/* build string in format "prefix|key|value|key|value|etc.|suffix" */
	/* where prefix==__bs[0] and suffix==__bs[1] */
	/* Note: prefix/suffix will "protect from exception in JavaScriptSerializer.serialize" */
	/* key - identifier for value (it should not contain | or " characters). In case of null, the '0' is used. */
	/* val - value for key (while saving it will be converted to string) */
	_setBackState: function(key, val)
	{
		var cs = this._ig_submit_time ? null : this._get_CS();
		if (!cs)
			return;
		key = key ? '' + key : '0';
		if (key.indexOf('|') >= 0)
			throw Error.invalidOperation('_setBackState: key can not contain | character');
		key = '|' + key + '|';
		val = '' + val;
		/* hide | and " characters */
		val = val.replace(/\|/g, '&tilda;').replace(/\"/g, '&qout;') + '|';
		var old = cs.value, len0 = this.__bs[0].length;
		var i = old.indexOf(key), empty = old.length < len0 + 3;
		if (empty || i < len0)
		{
			/* build new value or value which does not have key */
			/* new value is inserted as first item */
			cs.value = this.__bs[0] + key + val + (empty ? this.__bs[1] : old.substring(len0 + 1));
			return;
		}
		/* end of string (part behind existing key) */
		var str = old.substring(i += key.length);
		/* find end of value for existing key */
		var end = str.indexOf('|');
		if (end < 0)
			return;
		/* replace old value for existing key */
		cs.value = old.substring(0, i) + val + str.substring(end + 1);
	},
	/* get value for a key */
	/* key - identifier used in _setBackState. In case of null, the '0' is used. */
	/* returns: null or value as string */
	_getBackState: function(key)
	{
		var i = -1, cs = this._get_CS();
		if (cs)
			cs = cs.value;
		if (!cs || cs.indexOf(this.__bs[0]) != 0)
			return null;
		key = key ? '' + key : '0';
		/* remove dummy prefix which "protected from exception in JavaScriptSerializer.serialize" */
		cs = cs.replace(this.__bs[0], '').split('|');
		/* find key and value associated with it */
		/* string was saved in format "key|value|key|value|etc." */
		while ((i += 2) + 2 < cs.length)
			if (cs[i] == key)
		/* restore | and " characters */
			return cs[i + 1].replace(/&tilda;/g, '|').replace(/&qout;/g, '"');
		return null;
	},

	_onBeforeunloadOtherHandler: function(e)
	{
	},

	/*********END EVENT HANDLERS***************/

	/*********PROTECTED VIRTUAL METHODS********/
	_setupMarkerElements: function()
	{

	},
	_addHandlers: function()
	{
		/*TO BE IMPLEMENTED ON DERIVED CLASS*/
	},

	_addOtherHandlers: function()
	{
		this._registerOtherHandlers([{ "submit": theForm, "beforeunload": window}]);
	},

	_createItem: function(element, adr)
	{

	},

	_createObject: function(element, obj)
	{

	},

	__responseCompleteInternal: function(callbackObject, responseObject, browserResponseObject)
	{
		var cssClasses = responseObject.context.shift();
		if (cssClasses)
		{
			var igStyles;
			if ($util.IsIE)
			{
				for (var i = 0; i < document.styleSheets.length; i++)
				{
					var ss = document.styleSheets[i];
					if (ss.id == "igStyles")
					{
						igStyles = ss;
						break;
					}
				}
				if (igStyles)
					igStyles.cssText += cssClasses;
			}
			else
			{
				igStyles = document.styleSheets[document.styleSheets.length - 1];
				var rules = cssClasses.split("}");
				for (var i = 0; i < rules.length - 1; i++)
				{
					igStyles.insertRule(rules[i] + "}", igStyles.cssRules.length);
				}
			}
		}
		this._responseComplete(callbackObject, responseObject, browserResponseObject);
		this._posted = false;
	},

	_responseComplete: function(callbackObject, responseObject, browserResponseObject)
	{
	},

	_responseCompleteError: function(callbackObject, responseObject)
	{

	},

	_setupCollections: function()
	{
		this._itemCollection = this._collectionsManager.register_collection(0, $IG.ObjectCollection);
	},

	_saveAdditionalClientState: function()
	{
		return null;
	},

	/*********END PROTECTED VIRTUAL METHODS********/


	/*********PROTECTED METHODS********/

	_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]);
		}
	},
	/* raise postback */
	/* args - postback-flag (1-full, 2-async) or EventArgs after raising a ClientEvent */
	/*  in this case args._props[1] contains postback-flag and all other _props[i] contain values which can be passed to server */
	/* evtName - name of event to raise */
	_postAction: function(args, evtName, noIndicator)
	{
		var act = args._props ? args._props[1] : args;
		if (act == 1)/* raise full postback */
		{
			/* VS 04/12/2007 adjust view/clent states */
			// ??
			/* VS 04/12/2007 parameters must be fixed */
			/* VS 04/20/2009 check for MS Validators before postback */
			if (this._causeValidation && typeof WebForm_DoPostBackWithOptions == 'function')
			{
				WebForm_DoPostBackWithOptions({ validation: true, validationGroup: this._validationGroup });
				if (typeof Page_IsValid == 'boolean' && !Page_IsValid)
					return;
			}
			/* SJZ 4/28/08 BR32228 - Shouldn't be calling __igDoPostBack, should be calling __doPostBack */
			__doPostBack(this._id, evtName + (args._getPostArgs ? args._getPostArgs() : ''));
			this._posted = true;
		}
		if (act == 2)/* raise async postback */
		{
			/* VS 04/12/2007 adjust view/clent states */
			// ??
			var cb = this._callbackManager.createCallbackObject();
			/* VS 04/12/2007 parameters/members of cbo.serverContext must be fixed */
			/* pass to server name of event */
			cb.serverContext.eventName = evtName;
			/* pass to server all properties used by EventArgs as props0, props1, props2, etc. */
			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];
			}
			/* pass to server all extra parameters which control may wish to */
			if (this._filterAsyncPostBack)
				this._filterAsyncPostBack(cb.serverContext, evtName, args);
			this._callbackManager.execute(cb, null, null, noIndicator);
		}
	},

	/* It raises client side event: notify users and/or adjust postback flag */
	/* 1st param - name of event to fire or array of all parameters */
	/* 2nd param - null, or Xxx prefix of XxxEventArgs, or instance of EventArgs */
	/* 3rd param - original event of browser (optional) */
	/* 4th param - PostBackAction (or null) */
	/* 5th, 6th, ... - additional params to match with order of XxxEventArgs._props array */
	/* return: null or instance of XxxEventArgs */
	/* Examples: */
	/* this._raiseEvent('Initialize'); will raise "Initialize" event. If no listeners, then it returns null, otherwise, it returns Sys.EventArgs */
	/* this._raiseEvent('Click', null, e); will raise "Click" event. If no listerners, then it returns null, otherwise, it returns $IG.EventArgs */
	/* this._raiseEvent('Click', '', e); same as above */
	/* this._raiseEvent('Click', 'PostBack', e); will raise "Click" event. If no listerners and no postback, then it returns null, otherwise, it returns $IG.PostBackEventArgs */
	/* this._raiseEvent('Click', 'Cancel', e); will raise "Click" event. If no listerners and no postback, then it returns null, otherwise, it returns $IG.CancelEventArgs */
	/* this._raiseEvent('Click', new MyObject()); will raise "Click" event. It returns 2nd parameter as it is. */
	/* this._raiseEvent('Resizing', 'Resize', e, null, 1, 2, 3, 4); will raise "Resizing" event.  If no listerners and no postback, then it returns null, otherwise, it returns Infragistics.Web.UI.ResizeEventArgs();, which _props will be filled by 1-value returned by evt.get_height(), 2-value returned by evt.get_height(), etc. */
	/* this._raiseEvent('MyPostAct', null, null, 1); will raise "MyPostAct" event (if it is defined) and raise FullPostBack. It will return $IG.EventArgs. */
	/* this._raiseEvent('MyAsyncAct', 'Cancel', null, 2); will raise "MyAsyncAct" event (if it is defined) and raise AsyncPostBack. It will return $IG.CancelEventArgs. */
	/* this._raiseEvent('MyAsyncAct', new MyObject(), e, 2); will raise "MyAsyncAct" event (if it is defined) and raise AsyncPostBack. It will return 2nd parameter as it is. */
	_raiseClientEventStart: function(param)
	{
		var params = param; /* array of parameters which may come from the Infragistics.Web.UI.Behavior */
		if (params.substring)
			params = arguments;
		var post = this.getClientEventPostBack(params[0]);
		if (!post)
			post = params[3];
		return this._raiseCE_0(this, params[0], post, 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, args._noIndicator);
		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;
		/* nothing to process and no request for autopostback */
		if (!fnc && post == null)/* if 2nd param is EvtArgs object, then return that object as it is */
			return str ? null : args;
		if (str)/* if 2nd param is string, then assume that is prefix for EventArgs */
			eval('try{args = new Infragistics.Web.UI.' + args + 'EventArgs();}catch(ex){args = null;}');
		var i = 1, len = params ? params.length : 0;
		if (!args)/* if EventArgs is missing or invalid, then create default args */
			args = (len < 3) ? new Sys.EventArgs() : new $IG.EventArgs();
		/* if it is our EventArgs object, then initialize its properties */
		if (args._props)
			while (++i < len) if (params[i] != null)
			args._props[i - 2] = params[i];
		/* initialize default postback action */
		if (post)
		{
			if (!args._props)
				args._props = new Array();
			if (!args._props[1] || args._props[1] == 0)
				args._props[1] = post;
		}
		/* fire event (notify listeners) */
		if (fnc)
			fnc(this, args);
		if (args._props)/* if it is our EventArgs object, then delete reference to browser event */
			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);
	},

	/*********END PROTECTED METHODS********/

	/*********PROTECTED PROPERTIES*********/

	_get_clientStateManager: function() { return this._clientStateManager; },

	_get_item: function(adr)
	{
		return this._itemCollection._getObjectByAdr(adr);
	},

	/*********END PROTECTED PROPERTIES*********/

	/*********PUBLIC PROPERTIES************/
	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
	},

	/* add/remove a function-handler to process a ClientEvent */
	/* evtName - name of event, fnc - name of function or reference to function */
	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>
		/* AK if postBack flag is provided convert it to a number */
		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_ajaxIndicator: function()
	{
		///<summary>
		/// Gets reference to instance of Infragistics.Web.UI.AjaxIndicator or null.
		///</summary>
		return this._pi;
	},

	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]);
	}
	/*********END PUBLIC PROPERTIES************/
}
$IG.ControlMain.registerClass('Infragistics.Web.UI.ControlMain', Sys.UI.Control);
/******************************************END ControlMain*****************************************/

/******************************************NavControlProps ENUM************************************/
$IG.NavControlProps = new function()
{
	this.Count = $IG.ControlMainProps.Count + 0;
};
/******************************************END NavControlProps ENUM********************************/

/******************************************Nav Control************************************/

$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);
	},
	
    /// <summary>
    /// Translates an address string specifier into the resolved NavItem object that lives at the specified address.
    /// </summary>
    /// <param name="address">The full address specifier for an item.</param>
    /// <remarks>
    /// For Example: '0.3.2' specifies the item at index 2 whose parent is at index 3 of the collection
    /// who's parent is index 0 of the top-level collection.
    /// </remarks>
    /// <returns>The NavItem object that corresponds to the passed in address specifier.</returns>
	resolveItem: function(address)
	{
	    return this._itemCollection._getObjectByAdr(address);
	}
	
}

$IG.NavControl.registerClass('Infragistics.Web.UI.NavControl', $IG.ControlMain);

/******************************************END Nav Control********************************/

if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();