$IG.Activation = function(obj, objProps, control, parentCollection, hierarchical)
{
	/// <summary>
	/// Activation behavior object of the grid.
	/// </summary>
	$IG.Activation.initializeBase(this, [obj, objProps, control, parentCollection]);
	this._hierarchical = hierarchical;
	this._rows = this._owner.get_rows();

	this._container = control._elements["container"];

	this._activeCellCssClass = this._get_clientOnlyValue("acc");
	this._activeColCssClass = this._get_clientOnlyValue("ahc");
	this._activeRowCssClass = this._get_clientOnlyValue("arc");
	this._activeRowSelectorImgCssClass = this._get_clientOnlyValue("arsi");
	this._activeRowSelectorCssClass = this._get_clientOnlyValue("arsc");

	this._gridElement = this._grid._element;

	this._gridElementMouseDownHandler = Function.createDelegate(this, this._onMousedownHandler);
	this._gridElementKeyDownHandler = Function.createDelegate(this, this._onKeydownHandler);

	this._grid._addElementEventHandler(this._gridElement, "mousedown", this._gridElementMouseDownHandler);
	this._grid._addElementEventHandler(this._gridElement, "keydown", this._gridElementKeyDownHandler);

	this._onHideColumnHandler = Function.createDelegate(this, this._onHideColumn);
	this._grid._gridUtil._registerEventListener(this._grid, "HideColumn", this._onHideColumnHandler);

	if (this._hierarchical)
	{
		this._onRowCollapsingHandler = Function.createDelegate(this, this._onRowCollapsing);
		this._grid._gridUtil._registerEventListener(this._grid, "RowCollapsing", this._onRowCollapsingHandler);
	}

	if ($util.IsOpera)
	{
		this._gridElementKeyPressHandler = Function.createDelegate(this, this._onKeypressHandler);
		this._grid._addElementEventHandler(this._gridElement, "keypress", this._gridElementKeyPressHandler);
	}
}

$IG.Activation.prototype =
{
	/************************************PROPERTIES******************************/
	__activeCell: null,

	get_activeCell: function()
	{
		/// <summary>
		/// Returns/sets the Active cell in the WebDataGrid.
		/// </summary>

		if (this.__activeCell)
			return this.__activeCell;

		var activeCell = null;
		var activeCellIDPair = this._get_value($IG.GridActivationProps.ActiveCell);
		if (activeCellIDPair != null)
		{
			activeCell = this._rows.get_cellFromIDPair(activeCellIDPair);
		}
		return activeCell;
	},
	get_activeCellResolved: function()
	{
		if (!this._hierarchical)
			return this.get_activeCell();

		var mainGrid = this._grid._get_mainGrid();
		var lastActiveGridId = mainGrid._get_lastActiveGridId();
		if (lastActiveGridId)
		{
			var lastActiveGrid = ig_controls[lastActiveGridId];
			if (lastActiveGrid)
			{
				var activation = lastActiveGrid.get_behaviors().get_activation();
				if (activation)
					return activation.get_activeCell();
			}
		}
		return null;
	},
	_set_activeCell: function(cell, fireEvent, shiftKey, ctrlkey, keyCode, howInvoked)
	{
		var activeCell = this.get_activeCell()
		if (cell == activeCell && cell != null)
		{
			if (this._hierarchical)
				this.__focusCell(activeCell);
			return;
		}

		if (cell && cell.get_column().get_hidden())
			return;

		if (fireEvent)
		{
			var args = this.__raiseClientEvent("ActiveCellChanging", $IG.ActiveCellChangingEventArgs, [activeCell, cell]);
			if (args != null && args.get_cancel())
			{
				if (this.__rowCollapsing)
					this.__rowCollapsing = false;
				return;
			}
		}
		this._grid._gridUtil._fireEvent(this, "ActiveCellChanging", { activeCell: activeCell, cell: cell, shiftKey: shiftKey, ctrlKey: ctrlkey, keyCode: keyCode, howInvoked: howInvoked});		

		if (this._hierarchical)
			this._set_activeGrid();
		this.__activeCell = cell;

		if (activeCell)
		{
			var old = activeCell.get_element();
			if (old)
				old.tabIndex = -1;
			this.__removeCssClass(activeCell);
		}

		var key = null;
		if (cell != null)
		{
			var row = cell.get_row();
			if (row != null)
			{
				key = cell.get_idPair();
				var elem = cell.get_element();
				this.__addCssClass(cell);
				/* VS 01/13/2008 element can be null (from report on forum) */
				if (elem)
					elem.tabIndex = this._grid._element.tabIndex;
				this.__focusCell(cell);
			}
		}
		this._set_value($IG.GridActivationProps.ActiveCell, key);

		if (fireEvent)
			this.__raiseClientEvent("ActiveCellChanged", $IG.ActiveCellChangedEventArgs, [this, cell, true]);

		this._grid._gridUtil._fireEvent(this, "ActiveCellChanged", { cell: cell, shiftKey: shiftKey, ctrlKey: ctrlkey, howInvoked: howInvoked, rowCollapsing: this.__rowCollapsing });
		this.__rowCollapsing = false;
	},
	_set_activeGrid: function()
	{
		var mainGrid = this._grid._get_mainGrid();
		if (mainGrid._lastActiveGridIdLock)
			return;

		var lastGridId = mainGrid._get_lastActiveGridId();
		var currentGridId = this._grid.get_id();
		if (lastGridId != null && lastGridId != currentGridId)
		{
			mainGrid._lastActiveGridIdLock = true;
			/* remove active cell */
			var lastActiveGrid = ig_controls[lastGridId];
			if (lastActiveGrid)
			{
				var activation = lastActiveGrid.get_behaviors().get_activation();
				if (activation.get_activeCell() != null)
					activation.set_activeCell(null, true);
			}
			mainGrid._lastActiveGridIdLock = false;
		}
		mainGrid._set_lastActiveGridId(currentGridId);

	},
	set_activeCell: function(cell, fireEvent)
	{
		if (this._hierarchical && cell)
		{
			if (cell._owner != this._grid)
				return
			var parentRow = this._grid.get_parentRow();
			var cellElement = cell.get_element();
			if (parentRow && !parentRow.get_expanded() || cellElement && cellElement.offsetWidth <= 0)
				return;
		}
		this._set_activeCell(cell, fireEvent, false, false, null, "code");
	},
	/*********************************END PROPERTIES******************************/

	/************************************EVENTHANDLERS******************************/

	_onMousedownHandler: function(evnt)
	{
		if (evnt.button == 0)
		{
			var cell = this._grid._gridUtil.getCellFromElem(evnt.target);
			/*D.M. Bug 9356 10/21/2008 - Removed the setTimeout.*/
			if (cell != null)
				this._set_activeCell(cell, true, evnt.shiftKey, evnt.ctrlKey, evnt.keyCode, "mousedown");
		}
	},

	_onKeydownHandler: function(evnt)
	{
		var util = this._grid._gridUtil;
		var cell = util.getCellFromElem(evnt.target);
		var key = evnt.keyCode;
		/* upDown is used to obtain more rows from VirtualScrolling */
		var upDown = 0;
		/* row in hirarchical grid */
		var row = null;
		if (this._hierarchical && this.__activeCell != null && !this._grid._cellInEditMode &&
			(!$util.IsOpera && ((!evnt.shiftKey && key == 189) || key == 107 || key == 109 || (evnt.shiftKey && key == 187)) ||
			$util.IsOpera && (key == 43 || key == 45 || (evnt.shiftKey && key == 61) || (!evnt.shiftKey && key == 109))))
		{
			row = this.__activeCell.get_row();
			/* validate that row of active cell belongs to hierarchical grid (not add-new-row or another part of grid) */
			if (!row.set_expanded)
				row = null;
		}
		/* that key entry belongs to a row in hierarchical grid */
		if (row)
		{
			var expand = ((key == 189 || key == 109 || key == 45) ? false : true);
			row.__fireExpndColEvnt = true;
			row.set_expanded(expand);
			this._operaCancelKeyPress = true;
			$util.cancelEvent(evnt);
		}
		else if (cell != null)
		{
			var nextCell = null;
			if (key == Sys.UI.Key.tab && evnt.shiftKey || key == Sys.UI.Key.left)
			{
				var allowRowMove = true;
				if (evnt.shiftKey && key == Sys.UI.Key.left)
					allowRowMove = false;

				if (this._hierarchical && allowRowMove && cell.get_column().get_visibleIndex() == 0)
				{
					var prevGridInfo = util._getPrevRowForPrevGrid(cell._row);
					/* OK 10/16/2009 22479 - this is a temporary fix for this issue, which will just prevent the excepion. */
					if (prevGridInfo != null && prevGridInfo.prevRow != null)
					{
						var prevGrid = prevGridInfo.prevGrid;
						var prevActivation = prevGrid.get_behaviors().get_activation();
						var lastCellIndex = prevGrid._gridUtil._findLastVisibleColumn().get_index();

						this._operaCancelKeyPress = true;
						
						prevActivation._set_activeCell(prevGridInfo.prevRow.get_cell(lastCellIndex), true, evnt.shiftKey, evnt.ctrlKey, evnt.keyCode, "keydown");
						$util.cancelEvent(evnt);

						return;
					}
				}

				nextCell = util.getPrevCell(cell);
				if (!allowRowMove && nextCell && nextCell._row.get_index() != cell._row.get_index())
					nextCell = null;
			}
			else if (key == Sys.UI.Key.up || (key == Sys.UI.Key.enter && evnt.shiftKey))
			{
				upDown = 1;
				if (this._hierarchical)
				{
					var prevGridInfo = util._getPrevRowForPrevGrid(cell._row);
					if (prevGridInfo != null)
					{
						var prevGrid = prevGridInfo.prevGrid;
						var prevRow = prevGridInfo.prevRow;
						if (prevRow != null)
						{
							var prevActivation = prevGrid.get_behaviors().get_activation();
							var cellCount = prevRow.get_cellCount() - 1;
							var cellIndex = cell.get_index();
							var visibleIndex = this._grid.get_columns().get_column(cellIndex).get_visibleIndex();
							visibleIndex = (visibleIndex > cellCount ? cellCount : visibleIndex);
							var previousGridCellIndex = prevGrid._gridUtil._getColumnAdrFromVisibleIndex(visibleIndex);


							this._operaCancelKeyPress = true;
							prevActivation._set_activeCell(prevRow.get_cell(previousGridCellIndex), true, evnt.shiftKey, evnt.ctrlKey, evnt.keyCode, "keydown");
							$util.cancelEvent(evnt);
							return;
						}
					}
				}
				nextCell = util.getPrevCellVert(cell);
			}
			else if (key == Sys.UI.Key.right || (key == Sys.UI.Key.tab && !evnt.shiftKey))
			{
				var allowRowMove = true;
				if (evnt.shiftKey && key == Sys.UI.Key.right)
					allowRowMove = false;
				if (this._hierarchical)
				{
					if (allowRowMove && cell.get_column().get_visibleIndex() == this._grid.get_columns().get_length() - 1)
					{
						var nextGridInfo = util._getNextRowForNextGrid(cell._row);
						if (nextGridInfo != null)
						{
							var nextGrid = nextGridInfo.nextGrid;
							var nextRow = nextGridInfo.nextRow;
							if (nextRow != null)
							{
								var nextActivation = nextGrid.get_behaviors().get_activation();
								var visCol = nextGrid._gridUtil._findFirstVisibleColumn();
								if (visCol)
								{
									var firstCellIndex = visCol.get_index();

									this._operaCancelKeyPress = true;
									nextActivation._set_activeCell(nextRow.get_cell(firstCellIndex), true, evnt.shiftKey, evnt.ctrlKey, evnt.keyCode, "keydown");
									$util.cancelEvent(evnt);
								}
								return;
							}
						}
					}
				}
				nextCell = util.getNextCell(cell);
				if (!allowRowMove && nextCell && nextCell._row.get_index() != cell._row.get_index())
					nextCell = null;
			}
			else if (key == Sys.UI.Key.down || key == Sys.UI.Key.enter)
			{
				upDown = 2;
				if (this._hierarchical)
				{
					var nextGridInfo = util._getNextRowForNextGrid(cell._row);
					if (nextGridInfo != null)
					{
						var nextGrid = nextGridInfo.nextGrid;
						var nextRow = nextGridInfo.nextRow;
						if (nextRow != null)
						{
							var nextActivation = nextGrid.get_behaviors().get_activation();
							var cellCount = nextRow.get_cellCount() - 1;
							var cellIndex = cell.get_index();
							var visibleIndex = this._grid.get_columns().get_column(cellIndex).get_visibleIndex();
							visibleIndex = (visibleIndex > cellCount ? cellCount : visibleIndex);
							var nextGridCellIndex = nextGrid._gridUtil._getColumnAdrFromVisibleIndex(visibleIndex);

							this._operaCancelKeyPress = true;
							nextActivation._set_activeCell(nextRow.get_cell(nextGridCellIndex), true, evnt.shiftKey, evnt.ctrlKey, evnt.keyCode, "keydown");
							$util.cancelEvent(evnt);
							return;
						}
					}
				}
				nextCell = util.getNextCellVert(cell);
			}
			if (nextCell != null)
			{
				/* SJZ 9/22/08 7844 We don't want the shift key to be acknowledged while tabbing. */
				var shiftKey = evnt.shiftKey;
				if (key == Sys.UI.Key.tab || key == Sys.UI.Key.enter)
					shiftKey = false;

				this._operaCancelKeyPress = true;
				this._set_activeCell(nextCell, true, shiftKey, evnt.ctrlKey, evnt.keyCode, "keydown");
				$util.cancelEvent(evnt);
			}
			/* check if VirtualScrolling should provide more rows */
			else if (upDown != 0)
			{
				var vs = this._grid.get_behaviors().getBehaviorByName('VirtualScrolling');
				if (vs && vs._doScroll(upDown))
					$util.cancelEvent(evnt);
			}
		}
		else if (evnt.target == this._gridElement && key == Sys.UI.Key.tab && !evnt.shiftKey)
		{
			var setFirstCell = true;
			if (this._hierarchical)
			{
				var lastActiveGridId = this._grid._get_mainGrid()._get_lastActiveGridId();
				if (lastActiveGridId != null)
				{
					var lastActiveGrid = ig_controls[lastActiveGridId];
					if (lastActiveGrid)
					{
						var activation = lastActiveGrid.get_behaviors().get_activation();
						if (activation.get_activeCell() != null)
						{
							var cellElement = activation.get_activeCell().get_element();
							if (cellElement.offsetWidth > 0)
							{
								try
								{
									setFirstCell = false;
									activation.__focusCell(activation.get_activeCell());
									$util.cancelEvent(evnt);

								}
								catch (e)
								{
									setFirstCell = true;
								}
							}
						}
					}
				}
			}

			if (this.get_activeCell() == null && setFirstCell)
			{
				// If focus is on the Grid Element, and there is no ActiveCell, and tab is pressed, then resolve the first row
				// in the Grid (note it might be an aux row) and set it's first cell as active. 			
				var row = this._grid._gridUtil.getFirstVisualRow();
				if (row)
				{
					/* OK 5/15/2009 17592 - Tab into grid after moving a column makes active cell go into wrong spot*/
					var i = 0;
					var column = this._grid._gridUtil._getColumnFromVisibleIndex(i);
					while (column && column.get_hidden())
						column = this._grid._gridUtil._getColumnFromVisibleIndex(++i);
					if (column)
					{
						var cellAdr = column.get_index();
						var nextCell = row.get_cell(cellAdr);
						this._set_activeCell(nextCell, true, evnt.shiftKey, evnt.ctrlKey, evnt.keyCode, "keydown");
						this._operaCancelKeyPress = true;
						$util.cancelEvent(evnt);
					}
				}
			}
		}
	},
	_onKeypressHandler: function(evnt)
	{
		/* Opera doesn't respect canceling the event in KeyDown, so we have to also cancel the event in KeyPress. */
		if (this._operaCancelKeyPress)
			$util.cancelEvent(evnt);
		this._operaCancelKeyPress = false;
	},

	_rowSelectorClicked: function(args)
	{
		var column = this._grid._gridUtil._findFirstVisibleColumn();
		if (!column)
			return;
		var firstCellIndex = column.get_index();
		this._set_activeCell(args.row.get_cell(firstCellIndex), true, false, false, null, "rowSelector");
	},

	_onHideColumn: function(args)
	{
		var activeCell = this.get_activeCell();
		if (activeCell && activeCell.get_column() == args.column && args.column.get_hidden())
		{
			var util = this._grid._gridUtil;
			var nextCell = util.getPrevCell(activeCell);
			if (!nextCell)
				nextCell = util.getNextCell(activeCell);
			this.set_activeCell(nextCell);
		}
	},

	_onRowCollapsing: function(args)
	{
		var row = args.row;
		var lastActiveGridId = this._grid._get_mainGrid()._get_lastActiveGridId();
		var lastActiveGrid = (lastActiveGridId ? ig_controls[lastActiveGridId] : null);
		if (lastActiveGrid && this._grid._gridUtil.isGridADescendent(row, lastActiveGrid))
		{
			var activation = this._grid.get_behaviors().get_activation();
			var firstCellIndex = this._grid._gridUtil._findFirstVisibleColumn().get_index();
			activation.__rowCollapsing = true;
			activation.set_activeCell(row.get_cell(firstCellIndex), true);
		}
	},
	/*******************************END EVENTHANDLERS******************************/

	/*******************************PRIVATE METHODS *******************************/
	__focusCell: function(cell)
	{
		var elem = cell ? cell.get_element() : null;
		if (!elem || elem.offsetWidth == 0)
			return;
		var args = { cell: cell, cancel: false };
		this._grid._gridUtil._fireEvent(this, "ScrolledCellIntoView", args);
		if (args.cancel)
			return;
		this._grid._gridUtil.scrollCellIntoViewIE(cell);
		/* check if it is addNewRow or similar cell-container */
		var cont = cell.get_row();
		if (cont)
			if ((cont = cont._container) == this._container)
				cont = null;
		/* OK 10/15/08 8854 - we need to check if the grid needs to resize based on the active style
		before setting the focus on the cell for FireFox otherwise the whole table will be scrolled 
		out of view when the grid resizes */
		if ($util.IsFireFox && this._grid._notifyBehaviorTData && !cont)
			this._grid._notifyBehaviorTData._onTick();
	},
	__addCssClass: function(cell)
	{
		$util.addCompoundClass(cell.get_element(), this._activeCellCssClass);
		var colElem = cell.get_column()._headerElement;
		if (colElem)
			$util.addCompoundClass(colElem, this._activeColCssClass);

		var row = cell.get_row();
		if (this._rowSelectors)
		{
			if (this._grid._get_auxRowIndex(row, null) == -1)
			{
				this._rowSelectors.addSelectorImage(row, this._activeRowSelectorImgCssClass);
				this._rowSelectors.addSelectorClass(row, this._activeRowSelectorCssClass);
			}
		}
		this._grid._gridUtil._fireEvent(this, "AddingActiveRowCssClass", { "row": row, "cssClass": this._activeRowCssClass });
		$util.addCompoundClass(row.get_element(), this._activeRowCssClass);
	},

	__removeCssClass: function(cell)
	{
		$util.removeCompoundClass(cell.get_element(), this._activeCellCssClass);
		var colElem = cell.get_column()._headerElement;
		if (colElem)
			$util.removeCompoundClass(colElem, this._activeColCssClass);

		var row = cell.get_row();
		if (this._rowSelectors)
		{
			this._rowSelectors.removeSelectorImage(row, this._activeRowSelectorImgCssClass);
			this._rowSelectors.removeSelectorClass(row, this._activeRowSelectorCssClass);
		}

		this._grid._gridUtil._fireEvent(this, "RemovingActiveRowCssClass", { "row": row, "cssClass": this._activeRowCssClass });
		$util.removeCompoundClass(row.get_element(), this._activeRowCssClass);
	},

	_addActiveCellChangedEventHandler: function(handler, priority)
	{
		/// <summary>
		/// Adds a listener to the active cell changed event.
		/// </summary>
		/// <param name="handler" type="Function">
		/// Reference to the new event handler.
		/// </param>
		/// <param name="priority" type="Boolean">
		/// Indicates if the handler should have higher priority.
		/// </param>
		this._grid._gridUtil._registerEventListener(this, "ActiveCellChanged", handler, priority);
	},

	_addActiveCellChangingEventHandler: function(handler)
	{
		/// <summary>
		/// Adds a listener to the active cell changing event.
		/// </summary>
		/// <param name="handler" type="Function">
		/// Reference to the new event handler.
		/// </param>
		this._grid._gridUtil._registerEventListener(this, "ActiveCellChanging", handler);
	},

	_addScrolledCellIntoViewEventHandler: function(handler)
	{
		/// <summary>
		/// Adds a listener to the ScrolledCellIntoView event.
		/// </summary>
		/// <param name="handler" type="Function">
		/// Reference to the new event handler.
		/// </param>
		this._grid._gridUtil._registerEventListener(this, "ScrolledCellIntoView", handler);
	},
	/*******************************END PRIVATE METHODS ***************************/

	/*******************************PUBLIC METHODS*********************************/



	/*******************************END PUBLIC METHODS*****************************/

	/*******************************OVERRIDES*************************************/

	_initializeComplete: function()
	{
		this._rowSelectors = this._parentCollection.getBehaviorFromInterface($IG.IRowSelectorsBehavior);
		if (this._rowSelectors)
			this._rowSelectors.addRowSelectorClickedEventHandler(Function.createDelegate(this, this._rowSelectorClicked));

		var activeCell = this.get_activeCell();
		if (activeCell != null)
		{
			var elem = activeCell.get_element();
			if (this._grid.tabIndex != -1)
				elem.tabIndex = this._grid.tabIndex;
			else
				elem.tabIndex = 0;
			if (this._hierarchical)
				this._set_activeGrid();
		}
	},

	dispose: function()
	{
		if (!this._grid)
			return;
		this._grid._removeElementEventHandler(this._container, "mousedown", this._gridElementMouseDownHandler);
		this._grid._removeElementEventHandler(this._gridElement, "keydown", this._gridElementKeyDownHandler);
		this._grid._gridUtil._unregisterEventListener(this._grid, "HideColumn", this._onHideColumnHandler);
		delete this._onHideColumnHandler;

		if (this._hierarchical)
		{
			this._grid._gridUtil._unregisterEventListener(this._grid, "RowCollapsing", this._onRowCollapsingHandler);
			delete this._onRowCollapsingHandler;
		}

		$IG.Activation.callBaseMethod(this, "dispose");
	}
	/*******************************END OVERRIDES*************************************/

}
$IG.Activation.registerClass('Infragistics.Web.UI.Activation', $IG.GridBehavior, $IG.IActivationBehavior);


/******************************************GridActivationProps ENUM************************************/
$IG.GridActivationProps = new function()
{
	this.ActiveCell = [$IG.GridBehaviorProps.Count, null];
	this.Count = $IG.GridBehaviorProps.Count + 1;
};
/******************************************END GridActivationProps ENUM********************************/


/******************************************EVENTARGS**************************************************/

$IG.ActiveCellChangingEventArgs = function(params)
{
	///<summary>
	///Event arguments object passed into the active cell changing event handler.
	///</summary>
	$IG.ActiveCellChangingEventArgs.initializeBase(this);
	this._currentActiveCell = params[0];
	this._newActiveCell = params[1];
}
$IG.ActiveCellChangingEventArgs.prototype =
{
	getCurrentActiveCell: function()
	{
		/// <summary>
		/// Returns the current Active Cell.
		/// </summary>
		return this._currentActiveCell;
	},

	getNewActiveCell: function()
	{
		/// <summary>
		/// Returns the Cell that is going to be active.
		/// </summary>
		return this._newActiveCell;
	}
}
$IG.ActiveCellChangingEventArgs.registerClass('Infragistics.Web.UI.ActiveCellChangingEventArgs', $IG.CancelEventArgs);


$IG.ActiveCellChangedEventArgs = function(params)
{
	///<summary>
	///Event arguments object passed into the active cell changed event handler.
	///</summary>
	$IG.ActiveCellChangedEventArgs.initializeBase(this);
	this._context = {};
	this._context["behavior"] = params[0].get_name();
	this._activeCell = params[1];
	this._noIndicator = params[2];
}
$IG.ActiveCellChangedEventArgs.prototype =
{

	getActiveCell: function()
	{
		/// <summary>
		/// Returns the Active Cell.
		/// </summary>
		return this._activeCell;
	}
}
$IG.ActiveCellChangedEventArgs.registerClass('Infragistics.Web.UI.ActiveCellChangedEventArgs', $IG.EventArgs);
/******************************************END EVENTARGS**********************************************/

if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();