﻿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) { }
					/* VS 12/09/2009. Access denied can happen. */
					try
					{
						if (this._ig_submit)
							this._ig_submit();
					} catch (e) { }
				}
			}
			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) { }
				/* VS 11/04/2009. Bug 23360. Exception in Sys$WebForms$PageRequestManager$_onFormSubmit when page has only one WebTextEditor */
				if (!rm._postBackSettings)
					rm._postBackSettings = {};
				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];
		var elem = this._element;
		$IG.ControlMain.callBaseMethod(this, 'dispose');
		if (elem && typeof(elem.control) != "undefined") /* OK Feb-3-2010 the elem is undefined sometimes, so I'll check for that here to avoid js exceptions */
			elem.control = undefined; /*AK Feb-3-2010 working around a bug in the new Ajax library. They are looking for "undefined" control. The fact that they assign null to it themselves does not matter for them. Have to delete the control.*/
	},
	/**********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();

			var val = Sys.Serialization.JavaScriptSerializer.serialize(state), bs = this.__backState;
			/* insert backState in front of ClientState: work around for possible fullPostBack+redirect */
			/* in this case the _clientState.value will contain _backState */
			/* NOTE: on server that _backState will be removed within RunBot.HandleOnInit */
			if (bs && bs.length > 2)
				val = bs + val;
			clientState.value = val;
		}

	},

	/* build string in format "|key|value|key|value|key|value||" */
	/* 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 cant have |');
		key = '|' + key + '|';
		val = '' + val;
		/* hide | and " characters */
		val = val.replace(/\|/g, '&tilda;').replace(/\"/g, '&qout;') + '|';
		var old = this._fixCS(cs);
		var i = old.indexOf(key), empty = old.length < 3;
		if (empty || i < 0)
		{
			/* build new value or value which does not have key */
			/* new value is inserted as first item */
			this.__backState = cs.value = key + val + (empty ? '|' : old);
			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 */
		this.__backState = 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 = this._fixCS(cs);
		if (!cs || cs.indexOf('|') != 0)
			return null;
		key = key ? '' + key : '0';
		/* remove dummy prefix which "protected from exception in JavaScriptSerializer.serialize" */
		cs = cs.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;
	},
	/* validate that backState does not contain ClientState, which may happen after redirect */
	/* if it does, then cut it off */
	_fixCS: function(cs)
	{
		var val = cs ? cs.value : '';
		var len = val ? val.length : 0;
		if (this.__backState != null || len < 3)
			return val;
		/* verify that it is backState */
		if (val.indexOf('|') != 0)
			val = '';
		/* find end of backState */
		var end = val.indexOf('||');
		/* if there is something behind backState, then cut it off */
		if (end > 0 && end + 2 < len)
			cs.value = val = val.substring(0, end + 2);
		return this.__backState = val;
	},

	_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)
		{
			this.__appendStyles(cssClasses);
		}
		this._responseComplete(callbackObject, responseObject, browserResponseObject);
		this._posted = false;
	},

	__appendStyles: function(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 = document.styleSheets[document.styleSheets.length - 1];
			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);
			}
		}
	},

	_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);
	},

	// A.T. used for generating IDs on the client, in the same way they are generated on the server
	// this._id is the ID of the control itself, such as WebDataGrid1 
	_getHashCode: function()
	{
		var attributeCounter = 10000;
		var hash = 0;
		for (var i = 0; i < this._id.length; i++)
		{
			hash = hash << 2;
			hash += this._id.charCodeAt(0);
		}

		return "x:" + hash + '.' + attributeCounter;
	},

	/*********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;
	},

	/* AK CLIENTBINDING get_clientbindingprops: function()
	{
		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]);
	}
	/* AK CLIENTBINDING 
	// note that we shouldn't do this for the WDG ! 
	set_clientbindingprops: function(value)
	{
	if (this._usesCollectionsClientState && this._supportsClientRendering)
	{
	this._dataStore = value;
	this._props = value[0];
	this._clientStateManager = new $IG.ObjectClientStateManager(this._props);
	this._objectsManager = new $IG.ObjectsManager(this, value[1]);
	// instantiate the new $IG.MSAjaxCollectionManager
	this._collectionsManager = new $IG.MSAjaxCollectionsManager(this, value[4], this._bindings, this._parentBinding);
	this._initClientEvents(value[3]);

	} else
	{
	this.set_props(value);
	}
	}*/
	/*********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********************************/
