/******************************************GRID BEHAVIOR COLLECTION**********************************************/
$IG.BehaviorCollectionBase = function(control)
{
	/// <summary>
	/// Base object for the behavior collections used in the grid.
	/// </summary>
	this._grid = control;
	this._behaviors = [];
}

$IG.BehaviorCollectionBase.prototype =
{
	get_grid: function()
	{
		///<summary>
		///Returns the grid the collection belongs to.
		///</summary>
		return this._grid;
	},

	add: function(behavior)
	{
		/// <summary>
		/// Adds a behavior to the collection.
		/// </summary>
		this._behaviors.push(behavior);
	},

	_initializeBehaviors: function()
	{
		if (!this._behaviors)
			return;

		for (var i = 0; i < this._behaviors.length; i++)
		{
			var behavior = this._behaviors[i];
			if (behavior)
			{
				behavior._parentCollection = this;
				if ($IG.IGridBehaviorContainer.isInstanceOfType(behavior))
				{
					var subBehCollection = behavior.get_behaviors();
					if (subBehCollection)
						subBehCollection._initializeBehaviors();
				}
			}
		}
	},

	getBehaviorByName: function(behaviorName)
	{
		/// <summary>
		/// Returns a behavior object with the name specified.
		/// </summary>
		if (!behaviorName)
			return null;

		var behavior = null;
		for (var i = 0; i < this._behaviors.length; i++)
		{
			if (this._behaviors[i].get_name() == behaviorName)
			{
				behavior = this._behaviors[i];
				break;
			}
			if ($IG.IGridBehaviorContainer.isInstanceOfType(this._behaviors[i]))
			{
				behavior = this._behaviors[i].get_behaviors().getBehaviorByName(behaviorName);
				if (behavior != null)
					break;
			}
		}

		//if(behavior == null)
		//   behavior = new behaviorInterface();

		return behavior;
	},
	getBehaviorFromInterface: function(behaviorInterface)
	{
		/// <summary>
		/// Returns a behavior object that implements provided interface.
		/// </summary>
		if (!behaviorInterface)
			return null;

		var behavior = null;
		for (var i = 0; i < this._behaviors.length; i++)
		{
			if (behaviorInterface.isInstanceOfType(this._behaviors[i]))
			{
				behavior = this._behaviors[i];
				break;
			}
			if ($IG.IGridBehaviorContainer.isInstanceOfType(this._behaviors[i]))
			{
				behavior = this._behaviors[i].get_behaviors().getBehaviorFromInterface(behaviorInterface);
				if (behavior != null)
					break;
			}
		}

		//if(behavior == null)
		//   behavior = new behaviorInterface();

		return behavior;
	},

	dispose: function()
	{
		this._grid = null;
		$IG.BehaviorCollectionBase.callBaseMethod(this, "dispose");
	}

}
$IG.BehaviorCollectionBase.registerClass('Infragistics.Web.UI.BehaviorCollectionBase', $IG.ObjectBase);
/******************************************END GRID BEHAVIOR COLLECTION**********************************************/

/******************************************GRID BEHAVIOR**********************************************/
$IG.GridBehavior = function(obj, objProps, control, parentCollection)
{
	/// <summary>
	/// Base object for the behaviors used in the grid.
	/// </summary>
	var props = objProps[0];
	var clientEvents = objProps[3];
	var csm = obj ? new $IG.ObjectClientStateManager(props) : null;
	$IG.GridBehavior.initializeBase(this, [obj, control._element, props, control, csm]);
	this._grid = this._owner;
	this._parentCollection = parentCollection;
	this._owner._initClientEventsForObject(this, clientEvents);
	this.__raiseClientEvent('Initialize');
}

$IG.GridBehavior.prototype =
{
	_initializeComplete: function()
	{

	},
	get_name: function()
	{
		/// <summary>
		/// Gets the name of the behavior.
		/// </summary>
		return this._get_value($IG.GridBehaviorProps.Name);
	},

	/*get_enable:function()
	{
	return this._get_value($IG.GridBehaviorProps.Enable);
	},

	set_enable:function(value)
	{
	this._set_value($IG.GridBehaviorProps.Enable, value);
	},*/

	dispose: function()
	{
		/// <summary>
		/// Called whenever the object is being disposed of.
		/// </summary>
		this._grid = null;
		this._parentCollection = null;
		$IG.GridBehavior.callBaseMethod(this, "dispose");
	},

	__raiseClientEvent: function(clientEventName, evntArgs, eventArgsParams)
	{
		var args = null;
		var grid = this._owner;
		var clientEvent = this._clientEvents[clientEventName];
		if (clientEvent != null)
		{
			if (evntArgs == null)
				args = new $IG.EventArgs();
			else
				args = new evntArgs(eventArgsParams);
			args = grid._raiseSenderClientEvent(this, clientEvent, args);
		}
		return args;
	},


	_responseComplete: function(callbackObject, responseOptions)
	{
	}
}
$IG.GridBehavior.registerClass('Infragistics.Web.UI.GridBehavior', $IG.ObjectBase);
/******************************************GRID BEHAVIOR OBJECT******************************************/

/******************************************GRID BEHAVIOR PROPS ENUM************************************/
$IG.GridBehaviorProps = new function()
{
	var count = $IG.ObjectBaseProps.Count;
	this.Name = [count++, ''];
	//this.Enable = [count++, 0];
	this.Count = count;
};
/******************************************GRID BEHAVIOR PROPS ENUM************************************/

/******************************************GRID BEHAVIOR CONTAINER INTERFACE************************************/
$IG.IGridBehaviorContainer = function()
{
	/// <summary>
	/// Interface that indicates that the implementing object contains child behaviors.
	/// </summary>
};

$IG.IGridBehaviorContainer.prototype =
{
	_initializeBehaviors: function(behaviorProps, control, parentCollection, behaviorCount)
	{
		//
		if (!behaviorProps)
			return;
		var count = isNaN(behaviorCount) ? behaviorProps.length : behaviorCount;
		for (var i = 0; i < count; i++)
		{

			var objProps = behaviorProps[i];
			if (!objProps[0] || !objProps[0][0])
				continue;

			var objName = objProps[0][0][0];
			var propName = objName;

			if (propName == null || !propName.indexOf)
				continue;

			propName = "_" + propName.substr(0, 1).toLowerCase() + propName.substr(1, propName.length - 1);
			var behaviorCollection = this.get_behaviors();
			var behavior = behaviorCollection[propName] = this._createBehaviorObject(objName, i, objProps, control, parentCollection);
			behaviorCollection.add(behavior);
			this._objectsManager.register_object(i, behavior);
		}
		//this.get_behaviors()._initializeBehaviors();
	},
	_createBehaviorObject: function(objName, i, objProps, control, parentCollection)
	{
		/// <summary>
		/// Creates the beahvior object
		/// </summary>		
	},
	get_behaviors: function()
	{
		/// <summary>
		/// Gets the child behavior collection.
		/// </summary>
		throw "Not implemented: get_behaviors()!"
	}
};

$IG.IGridBehaviorContainer.registerInterface("Infragistics.Web.UI.IGridBehaviorContainer");
/******************************************END GRID BEHAVIOR CONTAINER INTERFACE************************************/

/******************************************GRID BEHAVIOR CONTAINER**********************************************/
$IG.GridBehaviorContainer = function(obj, objProps, control, parentCollection)
{
	/// <summary>
	/// Base object for the behaviors that contain other child behaviors.
	/// </summary>
	this._initializeBehaviors = $IG.IGridBehaviorContainer.prototype._initializeBehaviors;	
	$IG.GridBehaviorContainer.initializeBase(this, [obj, objProps, control, parentCollection]);
}

$IG.GridBehaviorContainer.prototype =
{
	_createBehaviorObject: function(objName, i, objProps, control, parentCollection)
	{
		/// <summary>
		/// Gets the child behavior collection.
		/// </summary>
		return new $IG[objName]((objName + i), objProps, control, parentCollection);
	},
	_createObjects: function(objectsManager)
	{
		this._objectsManager = objectsManager;
		this._initializeBehaviors(objectsManager._objects, this._owner, this._owner.get_behaviors());
	},
	_behaviors: null,
	get_behaviors: function()
	{
		/// <summary>
		/// Gets child behavior collection.
		/// </summary>
		if (this._behaviors == null)
			this._behaviors = this._createBehaviorCollection();
		return this._behaviors;
	},
	dispose: function()
	{
		if (this._behaviors && this._behaviors._behaviors)
		{
			var behaviors = this._behaviors._behaviors;
			for (var i = 0; i < behaviors.length; i++)
			{
				behaviors[i].dispose();
			}
			this._behaviors.dispose();
		}
		this._objectsManager = null;
		$IG.GridBehaviorContainer.callBaseMethod(this, "dispose");
	},
	_createBehaviorCollection: function()
	{
		return null;
	}
}
$IG.GridBehaviorContainer.registerClass('Infragistics.Web.UI.GridBehaviorContainer', $IG.GridBehavior, $IG.IGridBehaviorContainer);
/******************************************GRID BEHAVIOR OBJECT******************************************/

/******************************************GRID ACTION***********************************/
$IG.GridAction = function(type, ownerName, object, value, tag)
{
	this.type = type;
	this.ownerName = ownerName;
	this._object = object;
	if (value)
		this._value = value;
	if (tag)
		this._tag = tag;
};

$IG.GridAction.prototype =
{
	type: "", 	// Type of action that is being performed
	ownerName: "", // Name of behavior, or empty if an action is performed by the grid itself
	_object: null, // Object the action is being performed on
	_value: null, 	// A value associated with the action
	_tag: null, 	// An extra value associated with the action
	_transactionList: null, // Reference back to the transaction list that owns the action
	_index: -1, 	// Index of the action inside of the transaction list
	get_action: function()	// Returns the action as an array for serialization
	{
		return { ownerName: this.ownerName, type: this.type, id: (this._object.get_idPair ? this._object.get_idPair() : null), value: this.get_value(), tag: this.get_tag() };
	},
	get_value: function()
	{
		return this._value;
	},
	get_tag: function()
	{
		return this._tag;
	},
	dispose: function()
	{
		this._object = null;
		this._value = null;
		this._tag = null;
	}
}

$IG.GridAction.registerClass('Infragistics.Web.UI.GridAction');

/******************************************END GRID ACTION***********************************/

/******************************************GRID ACTION TRANSACTION LIST***********************************/

$IG.GridActionTransactionList = function()
{
	$IG.GridActionTransactionList.initializeBase(this);
}
$IG.GridActionTransactionList.prototype =
{
	add_transaction: function(action, keepPrevious)
	{
		if (typeof (keepPrevious) == "undefined")
			keepPrevious = false;
		if (!keepPrevious)
		{
			var prevAction = action._object["_action" + action.type]; // Previous action of the same type with the object
			if (prevAction && prevAction._transactionList == this)
				this.remove_transaction(prevAction); // Get rid of old action
		}

		action._transactionList = this;
		action._object["_action" + action.type] = action; // Let the object know of the action for future reference
		action._index = this._count;
		this._orderedList[this._count] = action;
		this._count++;
	},

	remove_transaction: function(action)
	{
		/*
		DK 7 Oct 2008
		Bug 8686 : With EnableAjax set to false, there is an error when you sort or page after you update using RowEditTemplate
		Hack fix.  If the action is null, then don't do anything.  We should never be passing in null, but it can happen.
		*/
		if (action)
		{
			delete action._object["_action" + action.type];
			delete this._orderedList[action._index];
		}
	},

	clear: function()
	{
		for (var i = this._count - 1; i >= 0; i--)
			this.remove_transaction(this._orderedList[i]);
	},

	get_value: function(action)
	{
		return action.get_action();
	},

	get_list: function()
	{
		var list = [];
		var i = 0;
		for (var action in this._orderedList)
		{
			if (!isNaN(parseInt(action)))
				list[i++] = this._orderedList[action].get_action();
		}
		return list;
	},
	get_actionListForType: function(type)
	{
		var list = [];
		var i = 0;
		for (var action in this._orderedList)
		{
			if (!isNaN(parseInt(action)))
			{
				if (this._orderedList[action].type == type)
					list[i++] = this._orderedList[action];
			}
		}
		return list;
	},
	dispose: function()
	{
		for (var i in this._orderedList)
		{
			if (!isNaN(parseInt(i)))
			{
				var action = this._orderedList[i];
				action._transactionList = null;
				if (action._object)
					action._object["_action" + action.type] = null;
				action.dispose();
			}
		}
	}
}

$IG.GridActionTransactionList.registerClass('Infragistics.Web.UI.GridActionTransactionList', $IG.TransactionListBase);

/******************************************END GRID ACTION TRANSACTION LIST***********************************/

/******************************************CANCEL BEHAVIOR EVENT ARGS***********************************/
$IG.CancelBehaviorEventArgs = function(behavior)
{
	///<summary>
	///Base object for cancelable event arguments used in the grid behaviors.
	///</summary>
	$IG.CancelBehaviorEventArgs.initializeBase(this);
	this._context["behavior"] = behavior.get_name();
}
$IG.CancelBehaviorEventArgs.prototype =
{
	_context: {}
}
$IG.CancelBehaviorEventArgs.registerClass('Infragistics.Web.UI.CancelBehaviorEventArgs', $IG.CancelEventArgs);
/******************************************END CANCEL BEHAVIOR EVENT ARGS***********************************/

/*****************************************IActivationBehavior INTERFACE********************************/

$IG.IActivationBehavior = function()
{
	///<summary>
	///Interface that identifies the activation behavior.
	///</summary>
};

$IG.IActivationBehavior.prototype =
{
	get_activeCell: function()
	{
		/// <summary>
		/// Returns/sets the Active cell in the WebDataGrid.
		/// </summary>
	},
	set_activeCell: function(cell, fireEvent)
	{
	},
	_addActiveCellChangedEventHandler: function(handler)
	{
		/// <summary>
		/// Adds a listener to the active cell changed event.
		/// </summary>
		/// <param name="handler" type="Function">
		/// Reference to the new event handler.
		/// </param>
	},
	_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>
	}
};

$IG.IActivationBehavior.registerInterface("Infragistics.Web.UI.IActivationBehavior");

/*****************************************END IActivationBehavior INTERFACE****************************/

/*****************************************IColumnMovingBehavior INTERFACE********************************/
$IG.IColumnMovingBehavior = function()
{
	///<summary>
	///Interface that identifies the column moving.
	///</summary>
};

$IG.IColumnMovingBehavior.prototype =
{

};

$IG.IColumnMovingBehavior.registerInterface("Infragistics.Web.UI.IColumnMovingBehavior");

/*****************************************IColumnResizingBehavior INTERFACE********************************/
$IG.IColumnResizingBehavior = function()
{
	///<summary>
	///Interface that identifies the column resizing.
	///</summary>
};

$IG.IColumnResizingBehavior.prototype =
{
};

$IG.IColumnResizingBehavior.registerInterface("Infragistics.Web.UI.IColumnResizingBehavior");
/***************************************** end IColumnResizingBehavior INTERFACE********************************/

/*****************************************IEditingBehavior INTERFACE********************************/

$IG.IEditingBehavior = function()
{
	///<summary>
	///Interface that identifies the editing behavior.
	///</summary>
};

$IG.IEditingBehavior.prototype =
{
	commit: function()
	{
		/// <summary>
		/// Causes the grid to commit changes to the server.
		/// </summary>
	}
};

$IG.IEditingBehavior.registerInterface("Infragistics.Web.UI.IEditingBehavior");

/*****************************************END IEditingBehavior INTERFACE****************************/

/*****************************************IUpdatingBehavior INTERFACE********************************/

$IG.IUpdatingBehavior = function()
{
	///<summary>
	///Interface that identifies the updating behavior.
	///</summary>
};

$IG.IUpdatingBehavior.prototype =
{
	enterEditMode: function(cell)
	{
		/// <summary>
		/// Causes the grid to enter edit mode.
		/// </summary>
		/// <param name="cell">The cell to enter edit mode.</param>
	},
	exitEditMode: function()
	{
		/// <summary>
		/// Causes the grid to exit edit mode.
		/// </summary>
	},
	get_isInEditMode: function(cell)
	{
		/// <summary>
		/// Gets a value that indicates whether the cell is in edit mode.
		/// </summary>
		/// <param name="cell">WebDataGrid cell object.</param>
	},
	_addExitKeyHandledEventListener: function(handler)
	{
		/// <summary>
		/// Listen for when the grid leaves edit mode. For internal use only. 
		/// </summary>
	},
	_registerEditableRow: function(rowElement)
	{
	},

	_addEnteringEditEventListener: function(handler)
	{
		/// <summary>
		/// Adds a listener to the entering edit event.
		/// </summary>
		/// <param name="handler" type="Function">
		/// Reference to the new event handler.
		/// </param>
	},
	_addExitedEditEventListener: function(handler)
	{
		/// <summary>
		/// Adds a listener to the exited edit event.
		/// </summary>
		/// <param name="handler" type="Function">
		/// Reference to the new event handler.
		/// </param>
	}
};

$IG.IUpdatingBehavior.registerInterface("Infragistics.Web.UI.IUpdatingBehavior");

/*****************************************END IUpdatingBehavior INTERFACE****************************/

/*****************************************IRowAddingBehavior INTERFACE********************************/

$IG.IRowAddingBehavior = function()
{
	///<summary>
	///Interface that identifies the editing behavior.
	///</summary>
};

$IG.IRowAddingBehavior.prototype =
{
	get_row: function()
	{
		/// <summary>
		/// Gets a reference to the add new row object.
		/// </summary>
	}
};

$IG.IRowAddingBehavior.registerInterface("Infragistics.Web.UI.IRowAddingBehavior");

/*****************************************END IRowAddingBehavior INTERFACE****************************/


/*****************************************IRowDeletingBehavior INTERFACE********************************/

$IG.IRowDeletingBehavior = function()
{
	///<summary>
	///Interface that identifies the RowDeleting behavior.
	///</summary>
};

$IG.IRowDeletingBehavior.prototype =
{
	deleteRows: function(rows)
	{
		/// <summary>
		/// Takes a collection of rows and stores their row id pairs in an array
		/// which is handed off to the _deleteRows method for deletion.
		/// </summary>
		///<param name="rows">Collection of rows to be deleted.</param>
	}
};

$IG.IRowDeletingBehavior.registerInterface("Infragistics.Web.UI.IRowDeletingBehavior");

/*****************************************END IRowDeletingBehavior INTERFACE****************************/

/*****************************************ISelectionBehavior INTERFACE********************************/

$IG.ISelectionBehavior = function()
{
	///<summary>
	///Interface that identifies the selection behavior.
	///</summary>
};

$IG.ISelectionBehavior.prototype =
{
	get_selectedCells: function()
	{
		/// <summary>
		/// A collection of cells that are currently selected in the WebDataGrid. 
		/// To select a cell, use the Add method off of the Collection.
		/// To unselect a cell, use the Remove method off of the Collection.
		/// </summary>
	},
	get_selectedRows: function()
	{
		/// <summary>
		/// A collection of rows that are currently selected in the WebDataGrid. 
		/// To select a row, use the Add method off of the Collection.
		/// To unselect a row, use the Remove method off of the Collection.
		/// </summary>
	},
	get_selectedColumns: function()
	{
		/// <summary>
		/// A collection of columns that are currently selected in the WebDataGrid. 
		/// To select a column, use the Add method off of the Collection.
		/// To unselect a column, use the Remove method off of the Collection.
		/// </summary>
	},
	addInternalColumnSelectionChangingHandler: function(handler)
	{
		/* An pre column selection changing event, for use by the column resizing so that I can stop the selection behavior
		from removing my selected columns when doing a resize
		*/
	}
};

$IG.ISelectionBehavior.registerInterface("Infragistics.Web.UI.ISelectionBehavior");

/*****************************************END ISelectionBehavior INTERFACE****************************/

/*****************************************IRowSelectorBehavior INTERFACE********************************/

$IG.IRowSelectorsBehavior = function()
{
	///<summary>
	///Interface that identifies the row selectors behavior.
	///</summary>
};

$IG.IRowSelectorsBehavior.prototype =
{
	addRowSelectorClickedEventHandler: function(handler)
	{
		/// <summary>
		/// Listen for when the grid's row selectors are clicked. For internal use only. 
		/// </summary>
		/// <param name="handler" type="Function">Reference to the event handler.</param>
		/// <remarks>
		/// Handle the RowSelectorClicking or RowSelectorClicked clientside events on the control instead. 
		/// </remarks>
	},
	addSelectorImage: function(row, cssClass)
	{
		/// <summary>
		/// Add a css class containing a new image to the row selector's image area. 
		/// </summary>
		/// <param name="row" type="GridRow">Reference to the row.</param>
		/// <param name="cssClass" type="String">CSS class name.</param>
		/// <remarks>
		/// <p class="body">
		/// This method is designed for other behaviors to use. It shouldn't be necessary to use it 
		/// otherwise. 
		/// </p>
		/// <p class="body">
		/// The images on the row selector are set using CSS classes. The classes will be applied to
		/// a div element inside the row selector. It's recommended that you don't set padding or borders in 
		/// your css or it will distort the width and height of the row selector. Your style will need to set an
		/// appropriate width and height to display the image.
		/// </p>
		/// <p class="body">
		/// If mutiple css classes are applied, the resolution will be up to the browser depending on
		/// the order that the classes are declared in. 
		/// </p>
		/// </remarks>
	},
	removeSelectorImage: function(row, cssClass)
	{
		/// <summary>
		/// Remove a css class containing image information from the row selector's image area. 
		/// </summary>
		/// <param name="row" type="GridRow">Reference to the row.</param>
		/// <param name="cssClass" type="String">CSS class name.</param>
		/// <remarks>
		/// <p class="body">
		/// This method is designed for other behaviors to use. It shouldn't be necessary to use it 
		/// otherwise. 
		/// </p>
		/// </remarks>
	},
	addSelectorClass: function(row, cssClass)
	{
		/// <summary>
		/// Add a new css class to the row selector element.
		/// </summary>
		/// <param name="row" type="GridRow">Reference to the row.</param>
		/// <param name="cssClass" type="String">CSS class name.</param>
		/// <remarks>
		/// <p class="body">
		/// This method is designed for other behaviors to use. It shouldn't be necessary to use it 
		/// otherwise. 
		/// </p>
		/// <p class="body">
		/// If mutiple css classes are applied, the resolution will be up to the browser depending on
		/// the order that the classes are declared in. 
		/// </p>
		/// </remarks>
	},
	removeSelectorClass: function(row, cssClass)
	{
		/// <summary>
		/// Removes a css class from the row selector element
		/// </summary>
		/// <param name="row" type="GridRow">Reference to the row.</param>
		/// <param name="cssClass" type="String">CSS class name.</param>
		/// <remarks>
		/// <p class="body">
		/// This method is designed for other behaviors to use. It shouldn't be necessary to use it 
		/// otherwise. 
		/// </p>
		/// <p class="body">
		/// If mutiple css classes are applied, the resolution will be up to the browser depending on
		/// the order that the classes are declared in. 
		/// </p>
		/// </remarks>
	}
};

$IG.IRowSelectorsBehavior.registerInterface("Infragistics.Web.UI.IRowSelectorsBehavior");

/*****************************************END IRowSelectorBehavior INTERFACE****************************/

/*****************************************IPagingBehavior INTERFACE********************************/

$IG.IPagingBehavior = function()
{
	///<summary>
	///Interface that identifies the paging behavior.
	///</summary>
};

$IG.IPagingBehavior.prototype =
{
	get_pageIndex: function()
	{
		/// <summary>
		/// Gets current page index. 
		/// </summary>
	},
	get_pageSize: function()
	{
		/// <summary>
		/// Gets page size. 
		/// </summary>
	}
};

$IG.IPagingBehavior.registerInterface("Infragistics.Web.UI.IPagingBehavior");

/*****************************************END IPagingBehavior INTERFACE****************************/

/*****************************************IColumnSettings INTERFACE********************************/

$IG.IColumnSettings = function()
{
	///<summary>
	///Interface that identifies a behavior with column settings collection.
	///</summary>
};

$IG.IColumnSettings.prototype =
{
	get_columnSettings: function()
	{
		///<summary>
		///Gets a reference to the column settings collection.
		///</summary>
	}
};

$IG.IColumnSettings.registerInterface("Infragistics.Web.UI.IColumnSettings");

/*****************************************END IRowSelectorBehavior INTERFACE****************************/

/******************************************ColumnSetting**********************************************/
$IG.ColumnSetting = function(adr, element, props, owner, csm)
{
	/// <summary>
	/// Object that defines a column setting for a grid behavior.
	/// </summary>
	$IG.ColumnSetting.initializeBase(this, [adr, element, props, owner, csm]);
}

$IG.ColumnSetting.prototype =
{
	get_columnKey: function()
	{
		/// <summary>
		/// Gets the key of the column the setting is attached to.
		/// </summary>
		return this._get_clientOnlyValue('ck');
	}
}
$IG.ColumnSetting.registerClass('Infragistics.Web.UI.ColumnSetting', $IG.ObjectBase);
/******************************************END ColumnEditor******************************************/

/******************************************ColumnSettingProps ENUM************************************/
$IG.ColumnSettingProps = new function()
{
	this.Count = $IG.ObjectBaseProps.Count;
};
/******************************************END ColumnSettingProps ENUM********************************/

/******************************************IDPAIR***********************************/
$IG.IDPair = function(index, key)
{
	if (typeof (index) != "undefined")
		this.index = index;
	if (typeof (key) != "undefined" && key !== null)
	{// Make the key an array even if it's a single value
		// That is to always account for the compound data key
		if (typeof (key) == "string")
			this.key = key.split(",");
		else if (key.length)
			this.key = key;
		else
			this.key = [key];
	}
};

$IG.IDPair.prototype =
{
	index: -1,
	key: []//Key is always presumed to be compound
}

//$IG.IDPair.registerClass('Infragistics.Web.UI.IDPair');
/******************************************END IDPAIR***********************************/

/******************************************WebDataGrid Utility Object******************************************/
$IG.GridUtility = function(gridObj)
{
	///<summary>
	///Grid's utility object. Contains helper methods to work with the grid.
	///</summary>
	this._grid = gridObj;
};

$IG.GridUtility.prototype =
{
	scrollCellIntoViewIE: function(cell)
	{	
		var elem = cell.get_element();
		var row = cell.get_row();
		var scrollContainer = this._grid._elements["container"];
		var scrollLeft = scrollContainer.scrollLeft, contWidth = scrollContainer.offsetWidth;
		var oldLeft = scrollLeft;
		var left = elem.offsetLeft, width = elem.offsetWidth;

		/* OK 6/17/2009 17423 - Keyboard navigation in Opera doesn't scroll grid down */
		if ($util.IsOpera)
		{
			var topFix = this._grid._marginTop;
			var scrollTop = scrollContainer.scrollTop - topFix;
			var height = scrollContainer.offsetHeight;
			var bottom = scrollTop + height;
			var cellBottom = elem.offsetTop + elem.offsetHeight;
			var vScrBar = this._grid._elements["vScrBar"];
			/* adjust for height of VirtualScrolling (grid-table got marginTop) */
			/* OK 10/20/2009 23739 - don't have to adjust the vertical scroll if the row is 
			and auxilary row */
			if (!this._grid._isAuxRow(row) && vScrBar && (elem.offsetHeight > bottom ||
                        cellBottom < scrollTop ||
                        elem.offsetTop <= bottom && cellBottom > bottom ||
                        elem.offsetTop <= scrollTop && cellBottom >= scrollTop
                        ))
			{
				scrollTop = cellBottom - height + topFix;
				vScrBar.scrollTop = scrollTop;
			}
		}
		/* space on right to fit cell in visible area of container */
		if (left + width > scrollLeft + contWidth)
		{
			scrollLeft = left + width - contWidth;
			/* VS: I can not explain what is wrong with Safari, but that seems to work */
			if ($util.IsSafari)
				scrollLeft += width;
		}
		/* space on left to fit cell in visible area of container */
		if (left < scrollLeft)
		{
			scrollLeft = left;
			/* VS: I can not explain what is wrong with Safari, but that seems to work */
			if ($util.IsSafari) if ((scrollLeft -= width) < 0)
				scrollLeft = 0;
		}
		/* DIV-container cell located in add-new-row */
		var cont = row ? row._container : null;
		if (oldLeft != scrollLeft)
		{
			this._noScrollTime = (new Date()).getTime();
			this._noScrollLeft = scrollContainer.scrollLeft = scrollLeft;
			/* OK 11/09/2009 24459 - when there are no rows in  the grid setting the scrollLeft on the scrollContainer 
			does not do anything, have to go through the horizontal scroll bar in these cases */
			if (($util.IsIE || $util.IsFireFox) && this._grid.get_rows().get_length() == 0)
			{
				if (this._grid._hScrBar)
					this._grid._hScrBar.scrollLeft = scrollLeft;
			}
		}
		try
		{
			elem.focus();
		}
		catch (row) { }
		/* Firefox may scroll container of add-new-row: undo that action, because it destroyes activation, editing, etc. */
		if (cont && cont.scrollLeft > 0)
			cont.scrollLeft = 0;
		/* VS 10/12/2009 Bug 23265. Safari does not scroll to last/first cell, when EditModeActions.EnableOnActive=true */
		/* setting scrollLeft again to same value seems to fix Safari */
		if ($util.IsSafari && oldLeft != scrollLeft)					
			scrollContainer.scrollLeft = scrollLeft;		
	},

	findRowIndexByCellElem: function(elem)
	{
		var obj = $util.resolveMarkedElement(elem.parentNode);
		if (obj)
		{
			var type = obj[0].getAttribute("type");
			if (type == "row")
				return obj[1];
		}
		return null;
	},

	getRowFromCellElem: function(elem)
	{
		var parentRow = elem.parentNode;
		while (parentRow && (parentRow.tagName != "TR" || !parentRow.id))
			parentRow = parentRow.parentNode;
		var obj = null;
		if (parentRow)
			obj = $util.resolveMarkedElement(parentRow);
		if (obj)
		{
			var elem = obj[0];
			var type = elem.tagName; //.getAttribute("type");
			return this._getRowFromCellElem(obj, elem, type);
		}
		return null;
	},
	_getRowFromCellElem: function(obj, elem, type)
	{
		if (type == "TR")
		{
			var index = parseInt(obj[1]);
			if (!isNaN(index))
			{
				var auxRow = elem.getAttribute("auxRow");
				if (auxRow !== null)
					return this._grid._get_auxRows(auxRow)[index];
				else
					return this._grid.get_rows().get_row(index);
			}
			else
			{

				if (elem._object != null)
				{
					return elem._object;
				}
			}
		}
	},
	getCellFromElem: function(elem)
	{
		var obj = $util.resolveMarkedElement(elem);
		if (obj != null)
		{
			elem = obj[0];
			var type = elem.getAttribute("type");
			if (type == "cell")
			{
				var row = this.getRowFromCellElem(elem);
				if (row)
					return row.get_cell(obj[1]);
			}
		}
		return null;
	},

	getCellIndexFromElem: function(elem)
	{
		return elem.cellIndex - this._grid._get_cellIndexOffset();
	},

	getCellElemFromIndex: function(row, index)
	{
		return row._get_cellElementByIndex(row.get_element(), index + this._grid._get_cellIndexOffset());
	},

	isVisibleCell: function(cell)
	{
		if (cell)
		{
			var elem = cell.get_element();
			if (elem && $util.getRuntimeStyle(elem).display != "none")
				return true;
		}
		return false;
	},

	getFirstVisualRow: function()
	{
		var rows = this._grid._get_auxRows($IG.GridAuxRows.Top);
		var row = null;
		if (rows && rows.length > 0)
		{
			row = rows[0];
		}
		else
		{
			rows = this._grid.get_rows();
			row = (rows.get_length() > 0) ? rows.get_row(0) : null;
		}

		if (!row)
		{

			rows = this._grid._get_auxRows($IG.GridAuxRows.Bottom);
			row = (rows && rows.length > 0) ? rows[0] : null;
		}
		return row;
	},
	getLastVisualRow: function()
	{
		var rows = this._grid._get_auxRows($IG.GridAuxRows.Bottom);
		var row = null;
		if (rows && rows.length > 0)
		{
			row = rows[rows.length - 1];
		}
		else
		{
			rows = this._grid.get_rows();
			row = (rows.get_length() > 0) ? rows.get_row(rows.get_length() - 1) : null;
		}

		if (!row)
		{

			rows = this._grid._get_auxRows($IG.GridAuxRows.Top);
			row = (rows && rows.length > 0) ? rows[rows.length - 1] : null;
		}
		return row;
	},

	getNextCell: function(cell)
	{
		if (!cell)
			return cell;
		var cellIndex = cell.get_index();
		var visibleIndex = this._grid.get_columns().get_column(cellIndex).get_visibleIndex();
		var row = cell.get_row();
		/*
		DK 5 sept 2008
		Bug 7066 : Grid view scrolls when tabbing through cells in add new row and focus skips the last cell in add new row and goes to first cell in the data grid
		get_cellCount() already compensates for ._get_cellIndexOffset()
		*/
		if (visibleIndex == row.get_cellCount() - 1)
		{
			var visCol = this._findFirstVisibleColumn();
			var rows = this._grid.get_rows();
			if (this._grid._isAuxRow(row))
			{
				var auxAlign = (this._grid._isAuxRow(row, $IG.GridAuxRows.Top) ? $IG.GridAuxRows.Top : $IG.GridAuxRows.Bottom);
				var auxRows = this._grid._get_auxRows(auxAlign);
				var index = this._grid._get_auxRowIndex(row, auxAlign);
				if (!visCol)
					return null;
				if (index < auxRows.length - 1)
					return auxRows[index + 1].get_cell(visCol.get_index());
				else if (auxAlign == $IG.GridAuxRows.Top && rows.get_length() > 0)
					return rows.get_row(0).get_cell(visCol.get_index());
			}
			else
			{
				var rowIndex = row.get_index();
				if (rowIndex != rows.get_length() - 1)
				{
					var nextRow = rows.get_row(rowIndex + 1);
					if (nextRow != null && visCol)
						return nextRow.get_cell(visCol.get_index());
				}
				else
				{
					var auxRows = this._grid._get_auxRows($IG.GridAuxRows.Bottom);
					if (auxRows && auxRows.length && visCol)
						return auxRows[0].get_cell(visCol.get_index());
				}
			}
		}
		else
		{
			var nextCell = row.get_cell(this._getColumnAdrFromVisibleIndex(visibleIndex + 1));
			if (this.isVisibleCell(nextCell))
				return nextCell;
			return this.getNextCell(nextCell);
		}
	},
	getNextCellVert: function(cell)
	{
		var row = cell.get_row();
		var rowIndex = row.get_index();
		var rows = this._grid.get_rows();
		if (this._grid._isAuxRow(row))
		{
			var auxAlign = (this._grid._isAuxRow(row, $IG.GridAuxRows.Top) ? $IG.GridAuxRows.Top : $IG.GridAuxRows.Bottom);
			var auxRows = this._grid._get_auxRows(auxAlign);
			var index = this._grid._get_auxRowIndex(row, auxAlign);
			if (index < auxRows.length - 1)
				return auxRows[index + 1].get_cell(cell.get_index());
			else if (auxAlign == $IG.GridAuxRows.Top && rows.get_length() > 0)
				return rows.get_row(0).get_cell(cell.get_index());
		}
		else
		{
			if (rowIndex < rows.get_length() - 1)
			{
				var nextRow = rows.get_row(rowIndex + 1)
				if (nextRow != null)
					return nextRow.get_cell(cell.get_index());
			}
			else
			{
				var auxRows = this._grid._get_auxRows($IG.GridAuxRows.Bottom);
				if (auxRows && auxRows.length)
					return auxRows[0].get_cell(cell.get_index());
			}
		}

	},
	getPrevCell: function(cell)
	{
		if (!cell)
			return cell;
		var cellIndex = cell.get_index();
		var visibleIndex = this._grid.get_columns().get_column(cellIndex).get_visibleIndex();
		var row = cell.get_row();
		if (visibleIndex == 0)
		{
			var rows = this._grid.get_rows();
			var nextRow = null;
			if (this._grid._isAuxRow(row))
			{
				var auxAlign = (this._grid._isAuxRow(row, $IG.GridAuxRows.Top) ? $IG.GridAuxRows.Top : $IG.GridAuxRows.Bottom);
				var auxRows = this._grid._get_auxRows(auxAlign);
				var index = this._grid._get_auxRowIndex(row, auxAlign);
				if (index > 0)
					nextRow = auxRows[index - 1];
				else if (auxAlign == $IG.GridAuxRows.Bottom && rows.get_length() > 0)
					nextRow = rows.get_row(rows.get_length() - 1);
			}
			else
			{
				var rowIndex = row.get_index();
				if (rowIndex != 0)
					nextRow = rows.get_row(rowIndex - 1)
				else
				{
					var auxRows = this._grid._get_auxRows($IG.GridAuxRows.Top);
					if (auxRows && auxRows.length)
						nextRow = auxRows[auxRows.length - 1];
				}
			}
			if (nextRow != null)
			/*
			DK 5 sept 2008
			Bug 7066 : Grid view scrolls when tabbing through cells in add new row and focus skips the last cell in add new row and goes to first cell in the data grid
			get_cellCount() already compensates for ._get_cellIndexOffset()
			*/

				return nextRow.get_cell(this._findLastVisibleColumn().get_index());
		}
		else
		{
			var prevCell = row.get_cell(this._getColumnAdrFromVisibleIndex(visibleIndex - 1)); ;
			if (this.isVisibleCell(prevCell))
				return prevCell;
			return this.getPrevCell(prevCell);
		}
	},
	getPrevCellVert: function(cell)
	{
		var row = cell.get_row();
		var rowIndex = row.get_index();
		var rows = this._grid.get_rows();
		if (this._grid._isAuxRow(row))
		{
			var auxAlign = (this._grid._isAuxRow(row, $IG.GridAuxRows.Top) ? $IG.GridAuxRows.Top : $IG.GridAuxRows.Bottom);
			var auxRows = this._grid._get_auxRows(auxAlign);
			var index = this._grid._get_auxRowIndex(row, auxAlign);
			if (index > 0)
				return auxRows[index - 1].get_cell(cell.get_index());
			else if (auxAlign == $IG.GridAuxRows.Bottom && rows.get_length() > 0)
				return rows.get_row(rows.get_length() - 1).get_cell(cell.get_index());
		}
		else
		{
			if (rowIndex != 0)
			{
				var nextRow = this._grid.get_rows().get_row(rowIndex - 1)
				if (nextRow != null)
					return nextRow.get_cell(cell.get_index());
			}
			else
			{
				var auxRows = this._grid._get_auxRows($IG.GridAuxRows.Top);
				if (auxRows && auxRows.length)
					return auxRows[auxRows.length - 1].get_cell(cell.get_index());
			}
		}
	},

	getCellIDPairFromElem: function(element)
	{
		var row = this.getRowFromCellElem(element);
		if (row)
		{
			var column = this._grid.get_columns().get_column(this.getCellIndexFromElem(element));
			if (column)
				return new $IG.CellIDPair(row.get_idPair(), column.get_idPair());
		}
		return null;
	},

	getNextRow: function(element)
	{
		var rows = this._grid._elements.dataTbl.rows;
		if (!element)
			return rows[0];

		if (element.rowIndex == rows.length - 1)
			return null;

		return rows[element.rowIndex + 1];
	},

	getPrevRow: function(element)
	{
		var rows = this._grid._elements.dataTbl.rows;
		if (!element)
			return rows[rows.length - 1];

		if (element.rowIndex == 0)
			return null;

		return rows[element.rowIndex - 1];
	},

	getHeaderFromElem: function(elem)
	{
		var e = elem;
		while (e && e.tagName && (e.tagName != "TH" || !e.getAttribute("adr")))
			e = e.parentNode;
		if (e && e.tagName && e.tagName == "TH" && e.getAttribute("adr"))
		{
			var columns = this._grid.get_columns();
			for (var i = 0; i < columns.get_length(); i++)
			{
				var column = columns.get_column(i);
				var headerElement = column.get_headerElement();
				if (!headerElement)
					return null;
				if (e == headerElement)
					return column.get_header();
			}
		}
		return null;
	},

	getFooterFromElem: function(elem)
	{
		var e = elem;
		while (e && e.tagName && (e.tagName != "TH" || !e.getAttribute("adr")))
			e = e.parentNode;
		if (e && e.tagName && e.tagName == "TH" && e.getAttribute("adr"))
		{
			var columns = this._grid.get_columns();
			for (var i = 0; i < columns.get_length(); i++)
			{
				var column = columns.get_column(i);
				var footerElement = column.get_footerElement();
				if (!footerElement)
					return null;
				if (e == footerElement)
					return column.get_footer();
			}
		}
		return null;
	},

	_registerEventListener: function(obj, evntName, listener, priority)
	{
		if (obj._internalEventListeners == null)
			obj._internalEventListeners = {};
		if (obj._internalEventListeners[evntName] == null)
			obj._internalEventListeners[evntName] = [];

		if (priority)
			obj._internalEventListeners[evntName].unshift(listener);
		else
			obj._internalEventListeners[evntName].push(listener);
	},

	_fireEvent: function(obj, evntName, args)
	{
		if (obj._internalEventListeners == null)
			return;

		var listeners = obj._internalEventListeners[evntName];
		if (listeners != null && listeners.length > 0)
		{
			for (var i = 0; i < listeners.length; i++)
				if (listeners[i](args))
				return true;
		}
		return false;
	},

	_unregisterEventListener: function(obj, evntName, listener)
	{
		if (obj._internalEventListeners == null)
			return;

		var listeners = obj._internalEventListeners[evntName];
		if (listeners != null && listeners.length > 0)
		{
			for (var i = 0; i < listeners.length; i++)
			{
				if (listeners[i] == listener)
				{
					Array.removeAt(obj._internalEventListeners[evntName], i);
					return;
				}
			}
		}
	},

	areIdPairsEqual: function(idPair1, idPair2)
	{
		if (!idPair1 || !idPair2)
			return false;

		if (!(idPair1.key == null && idPair2.key == null))
		{
			if (idPair1.key.length != idPair2.key.length)
				return false;

			for (var i = 0; i < idPair1.key.length; i++)
				if (idPair1.key[i] != idPair2.key[i])
				return false;
		}

		if (idPair1.index != idPair2.index)
			return false;

		return true;
	}
    ,
	_get_gridWidth: function()
	{/* Returns the width that was set to the grid*/
		return $util.getRuntimeStyle(this._grid._element).width;
	},
	_get_containerTableWidth: function()
	{/* Utility method to get the current width of the table that actually holds the rows*/
		return $util.getRuntimeStyle(this._grid._elements.dataTbl).width;
	},
	_get_containerTableWidthResolved: function()
	{/* Utility method to get the current width of the table that actually holds the rows*/
		return this._grid._elements.dataTbl.offsetWidth;
	},
	_set_containerTableWidth: function(value)
	{/* Utility method to resize the width of the table that holds the rows.*/
		this._grid._elements.dataTbl.style.width = value;
	},
	_getColumnFromHeader: function(headerElem)
	{
		if (!headerElem)
			return null;
		var adr = headerElem.getAttribute("adr");
		if (adr < 0 || adr >= this._grid.get_columns().get_length()) return null;
		return this._grid.get_columns().get_column(adr);
	},
	_getColumnFromVisibleIndex: function(index)
	{
		var column = null;
		var columns = this._grid.get_columns();
		for (var i = 0; i < columns.get_length() && !column; i++)
		{
			if (columns._items[i]._visibleIndex == index)
				column = columns.get_column(i);
		}
		return column;
	},
	_getColumnAdrFromVisibleIndex: function(index)
	{
		var column = null;
		var columns = this._grid.get_columns();
		for (var i = 0; i < columns.get_length() && !column; i++)
		{
			if (columns._items[i]._visibleIndex == index)
				column = columns.get_column(i);
		}
		if (column)
			return column.get_index();
		return null;
	},
	_findLastVisibleColumn: function()
	{
		var column = null;
		var index = null;
		var columns = this._grid.get_columns();
		for (var i = 0; i < columns.get_length(); i++)
		{
			if (index == null || columns._items[i]._visibleIndex > index)
			{
				var col = columns.get_column(i);
				if (!col.get_hidden())
				{
					index = col._visibleIndex;
					column = col;
				}
			}
		}
		return column;
	},
	_findFirstVisibleColumn: function()
	{
		var column = null;
		var index = null;
		var columns = this._grid.get_columns();
		for (var i = 0; i < columns.get_length(); i++)
		{
			if (index == null || columns._items[i]._visibleIndex < index)
			{
				var col = columns.get_column(i);
				if (!col.get_hidden())
				{
					index = col._visibleIndex;
					column = col;
				}
			}
		}
		return column;
	},
	_getPreviousRenderedColumn: function(column)
	{
		var index = column.get_visibleIndex() - 1;
		if (index < 0)
			return null;
		var columns = this._grid.get_columns();
		for (var i = 0; i < columns.get_length(); i++)
		{
			var column = columns.get_column(i);
			if (column.get_visibleIndex() == index)
				return column;
		}

	},
	_getGridCellFromElement: function(element)
	{
		while (element && (element.tagName != "TD" && element.tagName != "TH" || element.parentNode.id.indexOf("adr") == -1 && element.parentNode.getAttribute("adr") === null)) //TH for row selectors
			element = element.parentNode;
		return element;
	},
	dispose: function()
	{
		this._grid = null;
	}
};
$IG.GridUtility.registerClass("Infragistics.Web.UI.GridUtility");

/******************************************End WebDataGrid Utility Object******************************************/

/******************************************EditorProvider***************************************/
$IG.EditorProvider = function(adr, elem, props, owner, csm)
{	
	var input = elem;
	var grid = owner;
	if (!elem)
	{
		if (grid._editorProvidersPool)
		{
			var id = grid._element.id + "_" + adr;
			elem = document.getElementById(id);
			if (!elem)
			{
				elem = document.createElement('DIV');
				/* OK 3/25/2009 15317 - Chrome and Safari need the div to have absolute positioning
				otherwise the whole browser will crash */
				grid._editorProvidersPool.appendChild(elem);
				elem.id = id;
				if ($util.IsSafari)
					elem.style.position = "absolute";
				$util.display(elem, true);
				input = document.createElement('INPUT');
				elem.appendChild(input);
			}
			else
				input = elem.firstChild;
		}
	}
	else
	{
		/* OK 3/25/2009 16100 - Chrome and Safari need the div to have absolute positioning
		otherwise the whole browser will crash */
		if ($util.IsSafari && elem.nodeName == 'DIV')
			elem.style.position = "absolute";
		
		/* find first input element */
		var nodes = elem.childNodes;
		var i = -1, len = nodes ? nodes.length : 0;
		if (len > 5)
			len = 5;
		while (++i < len)
			if (nodes[i].nodeName == 'INPUT' && nodes[i].type == 'text')
			input = nodes[i];
	}
	$IG.EditorProvider.initializeBase(this, [adr, elem, props, owner, csm]);
	if (elem)
	{
		elem.control = this;
		this._input = input;
	}
}
$IG.EditorProvider.prototype =
{
	get_inputElement: function()
	{
		/// <summary>
		/// Gets a reference to the input HTML element if it exists in the editor. 
		/// Returns first child of the main element.
		/// Can be overriden by the inherited provider if the input element is not the first child.
		/// </summary>
		return this._input;
	},
	get_value: function()
	{
		/// <summary>
		/// Gets/sets value to/from the editor. 
		/// </summary>
		/// <returns type="Object">Current value in editor.</returns>
		var elem = this.get_inputElement();
		return elem ? elem.value : null;
	},
	set_value: function(val)
	{
		/// <summary>Sets initial value in editor.</summary>
		/// <param name="val">Value for editor.</param>
		this._input.value = (val == null ? '' : val);
		/* set flag that it is default editor (will be used to fake first key entry after focus) */
		this._defEditor = true;
	},
	get_text: function()
	{
		/// <summary>
		/// Gets formatted text from the editor. 
		/// </summary>
		/// <returns type="Object">Current text in editor.</returns>
		/* if the editor does not provide any text formatting
		this method should not return any value */
	},
	showEditor: function(top, left, width, height, cssClass, parent, cell)
	{		
		/// <summary>
		/// Shows and positions the editor. 
		/// </summary>
		///<param name="top" type="Number" integer="true">
		///Top coordinate of the editor in pixels.
		///</param>
		///<param name="left" type="Number" integer="true">
		///Left coordinate of the editor in pixels.
		///</param>
		///<param name="width" type="Number" integer="true">
		///Width of the editor in pixels.
		///</param>
		///<param name="height" type="Number" integer="true">
		///Height of the editor in pixels.
		///</param>
		///<param name="cssClass" type="String">
		///Optional. CSS class to apply to the editor's main HTML element.
		///</param>
		///<param name="parent">
		///Parent HTML element if the editor needs to be reparented.
		///</param>
		///<param name="cell">
		///Cell object of grid.
		///</param>
		var fix = 0, cont = this._owner, holder = parent;
		/* if it is cell in grid, then use grid._poolHolder instead of parent grid._container */
		if (parent == cont._container)
		{
			if (!(holder = cont._poolHolder))
			/* should never happen */
				holder = parent;
			/* equilibristic tricks to get around bugs in IE (Bug 23239 and few unreported) */
			else if (cont._get_level && $util.IsIE)
			{
				var dad = holder.parentNode;
				dad.removeChild(holder);
				dad.insertBefore(holder, dad.firstChild);
			}
		}
		/* do not allow bounds of editor outside of bounds of grid */
		var x = parent.scrollLeft, y = parent.scrollTop, cWidth = parent.clientWidth, cHeight = parent.clientHeight;
		/* OK 11/09/2009 24459 - since we moved the scrollbar the editor positioning is all of in the 
		auxilary rows, the following will take care of the scroll in an aux row*/
		var parentScrollLeft = x;
		if (cell && cell._row && this._owner._isAuxRow(cell._row))
		{
			var tbl = cell._row.get_element();
			while (tbl && tbl.tagName != "TABLE")
				tbl = tbl.parentNode;
			x = tbl.offsetLeft * -1;

			if ($util.IsIE8 || !$util.IsIE)
				left -= x;
			else
				parentScrollLeft = x;
		}
		
		if (!(cell && cell._row && cell._row._container == parent))
		{
			/* adjust for height of VirtualScrolling (grid-table got marginTop) */
			top += this._owner._marginTop - y;
		}
		if (!x) x = 0;
		if (!y) y = 0;
		if (!cWidth || cWidth < 5)
			cWidth = parent.offsetWidth;
		if (!cHeight || cHeight < 5)
			cHeight = parent.offsetHeight;
		/* save values for drop-down editor used in this._setBounds */
		/* Calculate top-shift/offset of grid-cell-area relative to top edge of control. */
		/* If drop-down is located above grid-cell-area, then that space */
		/* is within bounds of control and can be treated as valid location of drop-down. */
		var i = 0, tr = parent;
		/* find TR where editors are located */
		while (i++ < 4 && tr && tr.nodeName != 'TR')
			tr = tr.parentNode;
		/* if TR failed, then assume header with height of 20px */
		this._offsetTop = (tr && i < 4) ? tr.offsetTop : 20;
		/* horizontal shift/scroll of grid-cell-area relative to its container */
		this._x = x;
		/* width of grid-cell-area available for drop-down editor */
		this._cWidth = cWidth;
		/* height grid-cell-area available for drop-down editor */
		this._cHeight = cHeight;
		/* extra height below grid-cell-area available for drop-down editor (paging, horizontal scrollbar, etc.) */
		i = this._owner._element.offsetHeight - this._offsetTop - cHeight;
		/* include that in area available for drop-down editor */
		if (i > 1)
			this._cHeight += i;
		/* check/adjust left edge of editor */
		/* OK 11/09/2009 24459 - where the editor display will start if part of the cell is scrolled out
		of view to the left needed to be adjusted*/		
		var gridLeftEdge = this._owner.get_element().offsetLeft;
		if ((!$util.IsIE || $util.IsIEStandards) && left < 0)
		{
			width += left;
			/* do not allow negative or too small width */
			if (width < 5)
				width = 5;
			left = 0;
		}
		if ($util.IsIE && !$util.IsIEStandards && left - parentScrollLeft < gridLeftEdge)
		{
			width -= (parentScrollLeft - left);
			/* do not allow negative or too small width */
			if (width < 5)
				width = 5;
			left = parentScrollLeft;
		}
		
		/* check/adjust right edge of editor */
		/* OK 11/09/2009 24459 - where the editor display will end if part of the cell is hidden out
		of view to the right needed to be adjusted*/
		if (left + width > cWidth)
		{			
			if (!$util.IsIE || $util.IsIEStandards)
				width -= left + width - cWidth;
			else
				width = x + cWidth - left;
			/* do not allow negative or too small width */
			if (width < 5)
			{
				left += width - 5;
				width = 5;
			}
		}
		/* check/adjust top edge of editor */
		if (top < 0)
		{
			height += top;
			/* do not allow negative or too small height */
			if (height < 5)
				height = 5;
			top = 0;
		}
		/* check/adjust bottom edge of editor */
		if (top + height > cHeight)
		{
			height = cHeight - top;
			/* do not allow negative or too small height */
			if (height < 5)
			{
				top += height - 5;
				height = 5;
			}
		}
		this._show(top, left, width, height, cssClass, holder, cell);
	},
	_show: function(top, left, width, height, cssClass, parent, cell)
	{
		var input = this.get_inputElement();
		this._setBounds(top, left, height, this._element.style, parent, cell);
		this._setCss(input, cssClass);
		var style = input.style;
		style.height = height + 'px';
		style.width = width + 'px';
		var diff = input.offsetWidth - width;
		if (diff != 0) if ((width -= diff) > 2)
			style.width = width + 'px';
		diff = input.offsetHeight - height;
		if (diff != 0) if ((height -= diff) > 2)
			style.height = height + 'px';
		this._focus(input);
		if (this._defEditor)
			this._firstKey(this._charKey);
		this._addHandlers();
	},
	/* first key entry */
	_firstKey: function(key)
	{
		var elem = this._input, tr = this._tr;
		this._charKey = null;
		if (!key)
			return;
		if (!tr)
		{
			try
			{
				if (elem.selectionStart != null)
					tr = 1;
			} catch (val) { }
			if (tr != 1)
				tr = (elem.createTextRange != null) ? elem.createTextRange() : null;
			this._tr = tr;
			if (!tr)
				return;
		}
		elem.value = String.fromCharCode(key);
		if (tr == 1)
		{
			elem.selectionStart = elem.selectionEnd = 1;
			return;
		}
		tr.move('textedit', -1);
		tr.move('character', 1);
		tr.moveEnd('character', 1);
		tr.select();
	},
	_focus: function(elem)
	{
		/*$util._elemForFoc = elem;*/
		/* repeat "focus()" with delay if instant "focus()" failed */
		/*window.setTimeout('try{var e=$util._elemForFoc;$util._elemForFoc=null;e.focus();}catch(e){}', 150);*/
		/* if selection behavior is enabled, then editor under IE does not get focus, and select() seems to help */
		/* this._charKey keyCode of first entry, when editing was started by keypress */
		if ($util.IsIE || !this._charKey) try
		{
			elem.select();
		} catch (e) { }
		try
		{
			elem.focus();
		} catch (e) { }
	},
	_getWrapper: function(elem, css)
	{
		/* if this is shared editor provider, then parent of element cannot be changed */
		var wrapper = this._shared ? this._element : this._wrapper;
		if (!wrapper)
		{
			wrapper = this._wrapper = document.createElement('DIV');
			var container = elem.parentNode;
			container.removeChild(elem);
			container.appendChild(wrapper);
			wrapper.setAttribute("_wrapper", 1);
			wrapper.appendChild(elem);
		}
		this._setCss(wrapper, css);
		return wrapper;
	},
	_setCss: function(elem, css)
	{
		var css0 = elem.className;
		if (css && css0.indexOf(css) < 0)
		{
			if (css0 && css0.length > 0)
				css += ' ' + css0;
			elem.className = css;
		}
	},
	/* add dynamic listeners to process blur and key events to close editor */
	_addHandlers: function()
	{
		var input = this.get_inputElement();
		if (!input || this._hasLsnr)
			return;
		if (!this._onBlurFn)
		{
			this._onBlurFn = Function.createDelegate(this, this._onBlurHandler);
			this._onKeyFn = Function.createDelegate(this, this._onKeyDownHandler);
		}
		this._hasLsnr = true;
		$addHandler(input, 'blur', this._onBlurFn);
		$addHandler(input, 'keydown', this._onKeyFn);
	},
	/* remove dynamic listeners which process blur and key events to close editor */
	_removeHandlers: function()
	{
		if (this._hasLsnr)
		{
			var input = this.get_inputElement();
			/* VS 10/27/2008 get around changes in framework related to dispose */
			/* If browser is closed while editor is opened, then handlers of editor could be already */
			/* removed by editor by itself, so, dispose/remove/etc. triggered by grid break AJAX */
			if (input._events)
			{
				$removeHandler(input, 'blur', this._onBlurFn);
				$removeHandler(input, 'keydown', this._onKeyFn);
			}
		}
		this._hasLsnr = false;
	},
	/* show editor and set its top, left with validation for bounds of table */
	/* also set location of validator for editor */
	/* top - top of editor */
	/* left - top of editor */
	/* height - height of cell */
	/* style - style to adjust */
	/* elem - reference to html element of editor. If it is not null, then show editor below/above cell */
	_setBounds: function(top, left, height, style, parent, cell, elem)
	{
		if (this._owner)
			this._owner._ensureEditorProvidersPool(parent);
		/* show editor to initialize offsetHeight/Width */
		style.display = '';
		style.visibility = 'visible';
		/* size of table-container */
		var tblHeight = 0, tblWidth = 0, editorHeight = height;
		if (cell)
			cell = cell._element;
		if (cell)
		{
			/* used for bottom edge-calculations: vertical shift plus visible/available height for drop-down */
			tblHeight = this._cHeight;
			/* used for right edge-calculations: horizontal shift plus visible/available width for drop-down */
			tblWidth = this._x + this._cWidth;
		}
		/* extra option for add/filterRow to lock editor above/below cell */
		var aboveBelow = 0;
		if (elem)
		{
			editorHeight = elem.offsetHeight;
			var tr = cell ? cell.parentNode : null;
			/* if it is add-new-row, then editor should be above/below cell regardless of container-size */
			/* if it is filter-row, then editor should be below/above cell regardless of container-size */
			if (tr)
				aboveBelow = tr.getAttribute('mkr');
			/* -1: editor above cell (unconditional, without vertical validations) */
			/* 1: editor below cell (unconditional, without vertical validations) */
			if (aboveBelow == 'addNewRow')
				aboveBelow = (tr.className.indexOf('RowTop') > 0) ? 1 : -1;
			else if (aboveBelow == 'filterRow')
				aboveBelow = (tr.className.indexOf('RowBottom') > 0) ? -1 : 1;
			/* needs vertical validations for valid bounds */
			else
				aboveBelow = 0;
			/* shift editor above cell */
			if (aboveBelow < 0)
				top -= editorHeight;
			/* shift editor below cell */
			else
				top += height;
			if (tblHeight > 9)
			{
				/* distance between bottom of editor and bottom of table, if editor below cell */
				var shiftBot = tblHeight - top - editorHeight;
				/* (shiftBot < 0) means that drop-down goes below bottom edge of grid */
				if (aboveBelow == 0 && shiftBot < 0)
				{
					/* valid top edge of drop-down */
					var y = -this._offsetTop;
					/* distance between top of editor and top of table, if editor above cell */
					var shiftTop = top - y - height - editorHeight;
					/* pick up largest value between available spaces below and above cell */
					if (shiftTop > shiftBot)
						top = shiftTop + y;
					else
						top += shiftBot;
					/* do not allow drop-down appear above top edge of control */
					if (top < y)
						top = y;
				}
				/* on 1st init, it may fail and width can be defined by width of parent _eppool, which is 1px */
				var editorWidth = elem.offsetWidth;
				if (editorWidth < 5)
					if ((editorWidth = elem.firstChild.offsetWidth) < 5)
					editorWidth = 5;
				/* check if left edge of editor within width of table */
				if (left + editorWidth > tblWidth)
				/* shift left of editor to the right */
					left = tblWidth - editorWidth;
				/* check/adjust left edge of editor */
				if (left < this._x)
					left = this._x;
			}
		}
		this._fixValidator(top, editorHeight, tblHeight);
		/* safari and g-chrome do not shift editor by its scroll. So marginsTop/Left should be adjusted for those values manually. */
		/* the same happens with left/top (if to make position of _element absolute) */
		/* same thing for IE8 */
		var div = true;
		if (Sys.Browser.agent == Sys.Browser.Safari || $util.IsIEStandards)
		/* VS 17629. Validate all containers for scroll. */
			while (true)
		{
			if (div)
			{
				top -= parent.scrollTop;
				left -= parent.scrollLeft;
			}
			if (!(parent = parent.parentNode))
				break;
			var tag = parent.nodeName;
			if (tag == 'BODY' || tag == 'FORM' || tag == 'HTML')
				break;
			div = tag == 'DIV';
			if (div || tag == 'TABLE' || tag == 'SPAN')
			{
				var pos = $util.getStyleValue(null, 'position', parent);
				if (pos == 'relative' || pos == 'absolute')
					break;
			}
		}
		style.marginTop = top + 'px';
		style.marginLeft = left + 'px';
		/* slider as editor in footer or header may loose content, zIndex seems to fix that */
		style.zIndex = 1000;
		/* disable possible white color, etc. coming from containers like grid-header */
		style.color = 'black';
	},
	/* adjust location of validator */
	/* top - top of editor, height - height of editor, tblHeight - height of table */
	_fixValidator: function(top, height, tblHeight)
	{
		var validator = this._validator, elem = this._element;
		var style = validator ? validator.style : null;
		if (!style)
			return;
		var nodes = elem.childNodes, i = -1;
		/* check if validator is a child of editor-container */
		while (++i < nodes.length)
			if (nodes[i] == validator)
			break;
		/* set parent of validator */
		if (i == nodes.length)
		{
			validator.parentNode.removeChild(validator);
			elem.insertBefore(validator, elem.firstChild);
			style.position = 'absolute';
			style.left = style.top = style.marginTop = '';
		}
		/* move validator below editor or above editor */
		var mt = validator.offsetHeight;
		if (tblHeight < 10 || top + height + mt < tblHeight || top < mt)
			mt = height + 2;
		else
			mt = -(mt + 2);
		style.marginTop = mt + 'px';
	},
	/* return true if val1 is equal to val2 */
	_areEqual: function(val1, val2)
	{
		if (val1 == val2)
			return true;
		if (val1 && val2 && val1.getTime && val2.getTime)
			return val1.getTime() == val2.getTime();
		return false;
	},
	notifyLostFocus: function(e)
	{
		/// <summary>
		/// The method is called whenever the editor loses focus. 
		/// </summary>
		/// <param name="e">
		/// Event object associated with the event that triggered losing focus by the editor.
		/// </param>
	},
	hideEditor: function()
	{
		/// <summary>
		/// Hides the editor. 
		/// </summary>
		var elem = this._element;
		if (!elem)
			return;
		this._removeHandlers();
		$util.display(elem, true);
		var parent = elem._oldParent;
		if (parent && parent != elem.parentNode)
		{
			/* When old logic (remove/appendChild) was used, */
			/* then IE failed to set focus to TD: elem.focus() in scrollCellIntoViewIE */
			/* Old logic (2 lines): */
			/*elem.parentNode.removeChild(elem);*/
			/*parent.appendChild(elem);*/
			/* I tried to use delay (below), but activation in IE chocked after 2nd/3rd arrow key press  */
			/*window.setTimeout($util.createDelegate(this, this._oldParent_IEBug, [elem]), 200);*/
			/* So, to get around: set a flag which will request the remove/appendChild action for elem */
			elem._oldParent_IEBug = true;
			this._owner = null;
		}
	},
	dispose: function(edit)
	{
		/*
		DK 14 Oct 2008
		Bug 9028 : JavaScript error when closing window where WebDataGrid is present with WebCalendar editor provider.
		Reversed the order in dispose so that the editor will be hidden before clearing the _input
		Otherwise during the hideEditor call, when the system is trying to remove dynamic handlers 
		the _input it was using is already gone.
		*/
		this.hideEditor();
		var elem = this._element;
		/* elem._oldParent is set for shared-default-editor, but not for an item of EditorProviders */
		/* if that var is set, then shared-default-editor provider should not be disposed, */
		/* because postback can be async and shared-default-editor provider attached to it */
		/* can be needed by other grids which remain on page */
		var parent = elem ? elem._oldParent : null;
		if (parent)
		{
			/* remove _element in order to prevent its dispose. */
			this._element = null;
			/* flag 2 is set by $IG.WebTextEditor.dispose(). That flag means that it is full postback, */
			/* because WebTextEditor is disposed by itself. In this case continue with normal dispose of editor provider. */
			if (edit != 2)
				return;
		}
		/* that is normal (not default) editor provider: dispose attached editor */
		else if (this._editor && typeof this._editor.dispose == "function")
		{
			/* remove _input in order to prevent its dispose. */
			this._input = null;
			if (elem)
				elem.control = null;
			this._editor.dispose();
		}
		this._tr = this._input = this._editor = this._wrapper = null;
		$IG.EditorProvider.callBaseMethod(this, 'dispose');
	},
	_onKeyDownHandler: function(e)
	{
		var key = e.keyCode;
		if (key == Sys.UI.Key.tab || key == Sys.UI.Key.esc || key == Sys.UI.Key.enter)
			this.notifyLostFocus(e);
	},
	_onBlurHandler: function(e)
	{
		this.notifyLostFocus(e);
	},
	_get_outOfBouns: function()
	{
		return false;
	}
}
$IG.EditorProvider.registerClass('Infragistics.Web.UI.EditorProvider', $IG.ObjectBase);
/******************************************END EditorProvider*****************************************/

if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();