﻿var JTPlatinumGrids = [];

addEvent( window, "load", JTPlatinumGridOnLoad );

function JTPlatinumGridInitialize( gridID, options, requestor, themePath )
{
	var gridObject = document.getElementById( gridID );

	gridObject.FAlwaysShowEditor = options[0];
	gridObject.FCanMoveCols = options[1];
	gridObject.FCanMultiColumnSort = options[2];
	gridObject.FCanRangeSelect = options[3];
	gridObject.FCanResizeCols = options[4];
	gridObject.FCanResizeRows = options[5];
	gridObject.FCanSelect = options[6];
	gridObject.FReadOnly = options[7];
	gridObject.FRowSelect = options[8];
	if( options[9] && options[9] != "null" )
		eval( "gridObject.FOnDataLoad = " + options[9] );
	gridObject.FColumnCount = options[10];
	if( options[11] && options[11] != "null" )
		eval( "gridObject.FOnRowEditing = " + options[11] );
	gridObject.FEditorStyle = options[12];
	gridObject.FEditableColumns = options[13];
	gridObject.FKeyField = options[14];
	gridObject.FGroupBy = options[15];
	gridObject.FSortBy = options[16];
	if( options[17] && options[17] != "null" )
		eval( "gridObject.FOnRowEdited = " + options[17] );
	gridObject.EditingRow = options[18];
	if( options[19] && options[19] != "null" )
		eval( "gridObject.FOnRowInserted = " + options[19] );
	gridObject.FParentField = options[20];
	gridObject.FRowCount = options[21];
	gridObject.FVisibleRowCount = options[22];
	gridObject.FCanDragSelect = options[23];
	gridObject.FAllowScrolling = options[24];
	if( options[25] && options[25] != "null" )
		eval( "gridObject.FOnSelect = " + options[25] );
	// gridObject.FAllowHorizontalScrolling = options[26];
	gridObject.FShowEditColumn = options[27];
	gridObject.FFilterDelay = options[28];	
	gridObject.FRequestor = requestor;
	gridObject.FThemePath = themePath;

	gridObject.FCommand = document.getElementById( gridObject.id + "_Cmd" );
	gridObject.FScrollerDiv = document.getElementById( gridObject.id + "_ScrollerDiv" );
	gridObject.FGroupBar = document.getElementById( gridObject.id + "_GroupBar" );
	gridObject.FTBody = document.getElementById( gridObject.id + "_IntTableBody" );
	gridObject.FTable = document.getElementById( gridObject.id + "_IntTable" );
	gridObject.FHeaderDiv = document.getElementById( gridObject.id + "_Header" );
	gridObject.SelectedRow = -1;
	gridObject.SelectedCol = -1;
	gridObject.SelectedCells = new Array();
	gridObject.cancelCellClick = false;
	gridObject.FHasFixedCols = false;
	gridObject.FFixedCells = new Array();
	gridObject.SelStartRow = -1;
	gridObject.SelStartCol = -1;
	gridObject.FResizedCols = {};

	gridObject.onkeydown = JTPlatinumGridKeyDown;
	
	if( gridObject.FCanDragSelect && gridObject.FCanSelect && gridObject.FCanRangeSelect )
		gridObject.FTBody.onmousedown = JTPlatinumGridTBodyMouseDown;

	//if( gridObject.FCanSelect && gridObject.FCanRangeSelect )
	//	document.getElementById( gridObject.id + "_IntTableBody" ).style.MozUserSelect = "none";
	
	// Preload wait animation.
	gridObject.FWaitAnimation = new Image();
	gridObject.FWaitAnimation.src = gridObject.FThemePath + "images/wait.gif";

	gridObject.Load = function()
	{
		this._updateGridHeight();
		this._initFixedCols();			
		this._loadSelection();
			
		if( this.EditingRow > -1 )
			this.Edit( this.EditingRow );
	}

	gridObject.selectAll = function( select )
	{
		var tBody = document.getElementById( this.id + "_IntTableBody" );
		var rows = JTGetChildrenByTagName( tBody, "TR" );
		for( var i = 0; i < ( rows.length - 1 ); ++i )
		{
			if( rows[ i ].className.indexOf( "row " ) == -1 )
			{
				rows.splice( i, 1 );
				--i;
			}
		}

		for( var i = 0; i < rows.length; ++i )
			this.selectRow( i, select, false, true );
	}

	gridObject.selectRow = function(rowIndex, select, shiftSelect, ctrlSelect) {
		if (!this.FRowSelect) {
			for (var c = 0; c < this.FEditableColumns.length; ++c)
				this.selectCell(rowIndex, c, select, shiftSelect, ctrlSelect || (c > 0));

			return;
		}

		var row = document.getElementById(this.id + "_row_" + rowIndex);
		if (!row)
			return;

		if (select && this.SelectedRow > -1 && (!this.FCanRangeSelect || !ctrlSelect)) {
			if (this.FCanRangeSelect && shiftSelect)
				this.deselectAllExceptFor(this.SelStartRow, -1);
			else
				this.deselectAll();
		}

		if (this.FCanRangeSelect && shiftSelect && this.SelectedRow > -1) {
			var sr = this.SelStartRow;
			var er = Math.max(rowIndex, this.SelStartRow);
			for (var r = Math.min(sr, rowIndex); r <= er; ++r) {
				if (r != sr && r != rowIndex)
					this.selectRow(r, true, false, true);
			}
		}

		if (select) {
			if (!this._selFieldContainsAndAdd(rowIndex, -1)) {
				row.className += " rowselected";
				this._resetHeader();
			}

			this.SelectedRow = rowIndex;
			this.SelectedCells[rowIndex] = 1;
		}
		else {
			this._selFieldRemove(rowIndex, -1);
			row.className = row.className.replace(" rowselected", "");

			if (this.SelectedRow == rowIndex) {
				this.SelectedCol = -1;
				this.SelectedRow = -1;
			}

			this.SelectedCells[rowIndex] = null;
		}

		var selCheck = document.getElementById(this.id + "_rs_" + rowIndex);
		if (selCheck && selCheck.checked != select)
			selCheck.checked = select;

		if (!shiftSelect && !ctrlSelect && select) {
			this.SelStartCol = this.SelectedCol;
			this.SelStartRow = this.SelectedRow;
		}

		if (this.FOnSelect)
			this.FOnSelect(this, this.SelectedRow, this.SelectedCol, select);
	}

	gridObject.selectCell = function(rowIndex, colIndex, select, shiftSelect, ctrlSelect) {
		if (this.FRowSelect) {
			this.selectRow(rowIndex, select, shiftSelect, ctrlSelect);
			return;
		}

		if (!this.FEditableColumns[colIndex].CanSelect)
			return;

		var cell = document.getElementById(this.id + "_cell_" + rowIndex + "_" + colIndex);
		if (!cell)
			return;

		if (select && this.SelectedRow > -1 && this.SelectedCol > -1 && (!this.FCanRangeSelect || !ctrlSelect)) {
			if (this.FCanRangeSelect && shiftSelect)
				this.deselectAllExceptFor(this.SelStartRow, this.SelStartCol);
			else
				this.deselectAll();
		}

		if (this.FCanRangeSelect && shiftSelect && this.SelStartRow > -1 && this.SelStartCol > -1) {
			var sr = this.SelStartRow;
			var sc = this.SelStartCol;
			var er = Math.max(rowIndex, this.SelStartRow);
			var ec = Math.max(colIndex, this.SelStartCol);
			for (var r = Math.min(sr, rowIndex); r <= er; ++r) {
				for (var c = Math.min(sc, colIndex); c <= ec; ++c) {
					if ((r != sr || c != sc) && (r != rowIndex || c != colIndex))
						this.selectCell(r, c, true, false, true);
				}
			}
		}

		if (select) {
			if (!this._selFieldContainsAndAdd(rowIndex, colIndex)) {
				cell.className += " selected";
				this._resetHeader();
			}

			this.SelectedCol = colIndex;
			this.SelectedRow = rowIndex;

			if (typeof (this.SelectedCells[rowIndex]) == "undefined")
				this.SelectedCells[rowIndex] = [colIndex];
			else
				this.SelectedCells[rowIndex].push(colIndex);
		}
		else {
			this._selFieldRemove(rowIndex, colIndex);
			cell.className = cell.className.replace(" selected", "");
			//if( JTIEVer == 7 )
			//	cell.style.paddingBottom = "0px";

			if (this.SelectedRow == rowIndex && this.SelectedCol == colIndex) {
				this.SelectedCol = -1;
				this.SelectedRow = -1;
			}

			if (typeof (this.SelectedCells[rowIndex]) != "undefined")
				this.SelectedCells[rowIndex].removeItem(colIndex);
		}

		if (!ctrlSelect && !shiftSelect && select) {
			this.SelStartCol = this.SelectedCol;
			this.SelStartRow = this.SelectedRow;
		}

		if (this.FOnSelect)
			this.FOnSelect(this, rowIndex, colIndex, select);
	}

	gridObject.deselectAllExceptFor = function( rowIndex, colIndex )
	{
		var selectField = document.getElementById( this.id + "_Selection" );
		var rows = safeSplit( selectField.value, "|" );
		var i, j, cols;
		for( i = 0; i < rows.length; ++i )
		{
			cols = safeSplit( rows[ i ], "," );
			/*
			var selCheck = document.getElementById( this.id + "_rs_" + rowIndex );
			if( selCheck && ( colIndex > -1 || rowIndex != i ) )
				selCheck.checked = false;		
			*/
			if( this.FRowSelect )
			{
				if( cols[ 0 ] != rowIndex )
					this.selectRow( cols[ 0 ], false, false, false );
			}
			else
			{
				
				for( j = 1; j < cols.length; ++j )
				{
					if( cols[ 0 ] != rowIndex || ( colIndex > -1 && cols[ j ] != colIndex ) )
						this.selectCell( cols[ 0 ], cols[ j ], false, false, false );
				}
			}
		}
		var selectAllCheck = document.getElementById( this.id + "_SelectAll" );
		if( selectAllCheck )
			selectAllCheck.checked = false;
	}

	gridObject.deselectAll = function()
	{
		this.deselectAllExceptFor( -1, -1 );
	}

	gridObject.Sort = function( fieldName, direction )
	{
		this._execRequestor( "sort," + fieldName + " " + direction );
		return false;
	}

	gridObject.SortCustom = function( sortList )
	{
		this._execRequestor( "sort," + sortList );
		return false;
	}

	gridObject.Group = function( fieldName, direction )
	{
	}

	gridObject.Edit = function(rowIndex) {
		if (this.FReadOnly)
			return;
		if (this.FOnRowEditing && this.FOnRowEditing(this, rowIndex) == false)
			return;
		if (rowIndex == this.EditingRow)
			return;
		if (this.EditingRow != -1)
			this.Cancel();
		this.deselectAll();
		var row = document.getElementById(this.id + "_row_" + rowIndex);

		for (var i = 0; i < this.FEditableColumns.length; ++i) {
			if (!this.FEditableColumns[i].CanEdit)
				continue;

			var cell = document.getElementById(this.id + "_cell_" + rowIndex + "_" + i);
			var span = cell.getElementsByTagName("span")[0];
			var editor = document.getElementById(this.id + "_" + this.FEditableColumns[i].Name + "_Editor");
			var value = document.getElementById(this.id + "_cell_" + rowIndex + "_" + i + "_value");
			if (value)
				value = value.innerHTML;
			else
				value = span.innerHTML;

			if (!editor)
				continue;

			if (typeof (editor.setValue) != "undefined") {
				editor.setValue(value);
			}
			else if (editor.tagName == "SELECT") {
				for (var j = 0; j < editor.length; ++j) {
					if (editor.options[j].text == value) {
						editor.selectedIndex = j;
						break;
					}
				}
			}
			else if (editor.tagName == "INPUT" && editor.type == "checkbox") {
				if (value == "" || value == "0" || value.toLowerCase() == "false")
					editor.checked = false;
				else
					editor.checked = true;
			}
			else {
				editor.value = value;
			}
		}

		if (this.FEditorStyle == "Inline") {
			for (var i = 0; i < this.FEditableColumns.length; ++i) {
				var cell = document.getElementById(this.id + "_cell_" + rowIndex + "_" + i);
				var span = cell.getElementsByTagName("span")[0];
				if (!this.FEditableColumns[i].CanEdit)
					continue;
				span.style.display = "none";
				var editor = document.getElementById(this.id + "_" + this.FEditableColumns[i].Name + "_Editor");
				if (!editor)
					continue;
				var editorNode = document.getElementById(this.id + "_" + this.FEditableColumns[i].Name + "_Editor_outerdiv");
				if (!editorNode)
					editorNode = editor;
				editorNode.parentNode.removeChild(editorNode);
				cell.appendChild(editorNode);
				// editorNode.style.MozUserSelect = "";
			}
			var editCol = document.getElementById(this.id + "_editcol_" + rowIndex);
			if (editCol) {
				var spans = editCol.getElementsByTagName("span");
				spans[0].style.display = "none";
				spans[1].style.display = "block";
			}
		}
		else {
			row.className += " hidden";
			var editorCont = document.getElementById(this.id + "_editorform");
			editorCont.parentNode.removeChild(editorCont);
			row.parentNode.insertBefore(editorCont, row);
			editorCont.className = editorCont.className.replace(" hidden", "");
			// editorCont.style.MozUserSelect = "";
			// this._updateEndCol();
			this._resetColumns();
			// this._updateColHeader();
		}
		this.EditingRow = rowIndex;
	}

	gridObject.Insert = function()
	{
		var row = document.getElementById( this.id + "_row_-2" );
		var scrollerDiv = document.getElementById( this.id + "_ScrollerDiv" );
		var tBody = document.getElementById( this.id + "_IntTableBody" );
		
		row.className = row.className.replace( " hidden", "" );
		
		if( JTIEVer > -1 )
		{
			var cell = row.getElementsByTagName( "TD" )[ 0 ];
			if( cell )
			{
				cell.className += " nothing";
				cell.className = cell.className.replace( " nothing", "" );
			}
		}
		
		scrollerDiv.scrollTop = scrollerDiv.scrollHeight;
		tBody.scrollTop = tBody.scrollHeight;

		this.Edit( -2 );

		if( this.FEditorStyle == "Inline" )
		{
			scrollerDiv.scrollTop = scrollerDiv.scrollHeight;
			tBody.scrollTop = tBody.scrollHeight;
		}
	}

	gridObject.Post = function()
	{
		if( this.EditingRow == -1 )
			return;
		var row = document.getElementById( this.id + "_row_" + this.EditingRow );
		var pk = document.getElementById( this.id + "_row_" + this.EditingRow + "_pk" );
		var fieldvalues = new Object();
		if( this.FKeyField && pk )
			fieldvalues[ this.FKeyField ] = pk.innerHTML;
		for( var i = 0; i < this.FEditableColumns.length; ++i )
		{
			if( !this.FEditableColumns[i].CanEdit )
				continue;

			var editor = document.getElementById( this.id + "_" + this.FEditableColumns[i].Name + "_Editor" );
			if( !editor )
				continue;
			if( typeof( editor.getValue ) != "undefined" )
				fieldvalues[ this.FEditableColumns[i].DataField ] = editor.getValue();
			else if( editor.tagName == "INPUT" && editor.type == "checkbox" )
				fieldvalues[ this.FEditableColumns[i].DataField ] = ( editor.checked ? "1" : "0" );
			else
				fieldvalues[ this.FEditableColumns[i].DataField ] = editor.value;
		}
		if( this.EditingRow > -1 && this.FOnRowEdited )
		{
			var r = this.FOnRowEdited( this, this.EditingRow, fieldvalues );
			if( typeof( r ) != "undefined" && !r )
				return;
		}
		else if( this.EditingRow == -2 && this.FOnRowInserted )
		{
			var r = this.FOnRowInserted( this, fieldvalues );
			if( typeof( r ) != "undefined" && !r )
				return;
		}
		this._execRequestor( (this.EditingRow > -1) ? ("update," + this.EditingRow + "," + JTObjectToJSON(fieldvalues)) : ("insert," + JTObjectToJSON(fieldvalues)) );
	}

	gridObject.Cancel = function()
	{
		if( this.EditingRow == -1 )
			return;
		var row = document.getElementById( this.id + "_row_" + this.EditingRow );
		if( this.FEditorStyle == "Inline" )
		{
			for( var i = 0; i < this.FEditableColumns.length; ++i )
			{
				var cell = document.getElementById( this.id + "_cell_" + this.EditingRow + "_" + i );
				if( this.FEditableColumns[i].CanEdit )
				{
					var editor = document.getElementById( this.id + "_" + this.FEditableColumns[i].Name + "_Editor" );
					if( !editor )
						continue;
					var editorNode = document.getElementById( this.id + "_" + this.FEditableColumns[i].Name + "_Editor_outerdiv" );
					var editorContainer = document.getElementById( this.id + "_editorcontainer" );
					if( !editorNode )
						editorNode = editor;
					editorNode.parentNode.removeChild(editorNode);
					editorContainer.appendChild(editorNode);
				}
				var span = cell.getElementsByTagName("span")[0];
				span.style.display = "block";
			}
			var editCol = document.getElementById( this.id + "_editcol_" + this.EditingRow );
			if( editCol )
			{
				var spans = editCol.getElementsByTagName("span");
				spans[0].style.display = "block";
				spans[1].style.display = "none";
			}

			if( this.EditingRow == -2 )
				row.className += " hidden";
		}
		else
		{
			row.className = row.className.replace( " hidden", "" );
			var editorCont = document.getElementById( this.id + "_editorform" );
			editorCont.className += " hidden";
			if( JTIEVer > -1 && JTIEVer < 7 )
			{
				var parent = editorCont.parentNode;
				editorCont.parentNode.removeChild(editorCont);
				parent.appendChild(editorCont);
			}
		}					
		this.EditingRow = -1;
	}

	gridObject.Delete = function( rowIndex )
	{
		var pk = document.getElementById( this.id + "_row_" + rowIndex + "_pk" );
		if( !pk )
			return;
		var fieldvalues = new Array(pk.innerHTML);
		this._execRequestor( "delete," + JTObjectToJSON(fieldvalues) );
	}

	gridObject.Command = function( rowIndex, colIndex, commandIndex )
	{
		var pk = document.getElementById( this.id + "_row_" + rowIndex + "_pk" );
		var fieldvalues = new Array(pk.innerHTML);
		this._execRequestor( "command," + rowIndex + "," + colIndex + "," + commandIndex + "," + JTObjectToJSON(fieldvalues) );
	}
	
	gridObject.ToFirstPage = function()
	{
		return this.ToPage( 0 );
	}

	gridObject.ToPage = function( pageNum )
	{
		this._execRequestor( "page," + pageNum );
		return false;
	}
	
	gridObject.ScrollCellIntoView = function( row, col )
	{
		var scrollerDiv = document.getElementById( this.id + "_ScrollerDiv" );
		var tHead = document.getElementById( this.id + "_IntTableHead" );
		var tBody = document.getElementById( this.id + "_IntTableBody" );
		var row = document.getElementById( this.id + "_row_" + row );
		var scroller;

		scroller = scrollerDiv;
		
		if( row.offsetTop > ( scroller.scrollTop + ( scroller.clientHeight - 20 ) ) )
			scroller.scrollTop = row.offsetTop - ( scroller.clientHeight - 20 );
		else if( row.offsetTop < ( scroller.scrollTop + tHead.offsetHeight + 20 ) )
			scroller.scrollTop = row.offsetTop - tHead.offsetHeight - 20;
	}

	gridObject.getRowLevel = function( row )
	{
		var level = row.className.substr( row.className.indexOf( "level" ) + 5 );
		return parseInt( level );
	}
	
	gridObject.getCellHTML = function( row, col )
	{
		return document.getElementById( this.id + "_cell_" + row + "_" + col + "_c" ).innerHTML;
	}

	// Begin internal functions, avoid calling these directly.
	gridObject._StartColResize = function( e, div, gridID, colIndex )
	{
		var event = e || window.event;
		// var headerCol = div.parentNode;										 
		// var colIndex = parseInt( headerCol.id.substr( headerCol.id.indexOf("_header_") + 8 ) );
		// this.FResizingCol = document.getElementById( this.id + "_cell_0_" + colIndex );
		// this.FResizingCol = headerCol;
		this.FResizingCol = document.getElementById( this.id + "_header_" + colIndex );
		this.FResizingIndex = colIndex;
		if( !this.FResizingCol )
			return;
		this.style.MozUserSelect = "none";
		this.ondragstart = function() { return false; };
		this.onselectstart = function() { return false; };
		JTPlatinumGridResizing = this;
		addEvent( this, "mousemove", JTPlatinumGridMouseMove );
		addEvent( document, "mouseup", JTPlatinumGridEndColResize );

		event.cancelBubble = true;
		if( event.stopPropagation )
			event.stopPropagation();
	}

	gridObject._EndColResize = function(e) {
		this.FResizedCols[this.FEditableColumns[this.FResizingIndex].Name] = parseInt(document.getElementById(this.id + "_colitem_hdr_" + this.FResizingIndex).width);
		this.FResizedCols.json = false;
		document.getElementById(this.id + "_ColSizes").value = JTObjectToJSON(this.FResizedCols);
		this.style.MozUserSelect = "";
		this.ondragstart = null;
		this.onselectstart = null;
		this.FResizingCol = null;
		deleteEvent(this, "mousemove", JTPlatinumGridMouseMove);
		deleteEvent(document, "mouseup", JTPlatinumGridEndColResize);
		// this._updateColHeader();
		this._initFixedCols();
	}

	gridObject._MouseMove = function( e )
	{
		var event = e || window.event;
		if( this.FResizingCol )
		{
			var w = Math.max( ( getEventPageX( event ) - getObjectScreenX( this.FResizingCol ) ) + this.FScrollerDiv.scrollLeft - 3, 0 );
			if( w > 20 )
			{
				// this.FResizingCol.style.width = ( w - 0 ) + "px";
				// document.getElementById( this.FResizingCol.id + "_cellsizer" ).style.width = ( w - 0 ) + "px";
				document.getElementById( this.id + "_colitem_hdr_" + this.FResizingIndex ).width = w + "px";
				
				var col = document.getElementById( this.id + "_header_" + this.FResizingIndex );
				if( JTIsWebKit || JTFFVer == 2 )
					col.style.width = w + "px";
				// document.getElementById( this.id + "_colitem_body_" + this.FResizingIndex ).width = ( w - 1 );
				this._updateColHeader( false );
			}
		}
		else if( this.FMovingCol )
		{
			var cm = document.getElementById( this.id + "_ColMover" );
			var cp = document.getElementById( this.id + "_ColPositioner" );
			cm.style.left = ( getEventPageX( event ) - this.FMouseOffsetX - getObjectScreenX( this.FScrollerDiv ) ) + "px";
			cm.style.top = this.FHeaderOffset + ( getEventPageY( event ) - this.FMouseOffsetY - getObjectScreenY( this.FScrollerDiv ) ) + "px";
			cm.style.width = this.FMovingCol.offsetWidth + "px";
			cm.style.display = "block";
			var np = ( getEventPageX( event ) - getObjectScreenX( this.FScrollerDiv ) );
			var tp = -1;
			if( this.FGroupBar )
				tp = ( getEventPageY( event ) - getObjectScreenY( this.FGroupBar ) );
			var i, hdr = null;
			if( this.FGroupBar && tp > -1 && tp < this.FGroupBar.offsetHeight )
			{
				var groupCols = JTGetChildrenByTagName( JTLocateFirstChildByTagName( JTLocateFirstChildByTagName( JTLocateFirstChildByTagName( this.FGroupBar, "TABLE" ), "TBODY" ), "TR" ), "TD" );
				for( i = 0; i < groupCols.length; ++i )
				{
					hdr = groupCols[ i ];
					if( hdr.className.indexOf( "nogroups" ) > -1 )
						break;
					if( np <= ( hdr.offsetLeft + hdr.offsetWidth ) )
						break;
				}
				if( hdr )
				{
					if( i < groupCols.length )
						cp.style.left = hdr.offsetLeft + "px";
					else
						cp.style.left = ( hdr.offsetLeft + hdr.offsetWidth ) + "px";
					cp.style.height = this.FMovingCol.offsetHeight + "px";
					cp.style.display = "block";
					cp.style.top = this.FGroupBar.offsetTop + "px";
				}
				return;
			}
			for( i = 0; i <= this.FEditableColumns.length; ++i )
			{
				if( i < this.FEditableColumns.length )
				{
					hdr = document.getElementById( this.id + "_header_" + i );
					if( np <= ( hdr.offsetLeft + hdr.offsetWidth ) )
						break;
				}
				else
				{
					hdr = document.getElementById( this.id + "_header_" + ( i - 1 ) );
					if( np > ( hdr.offsetLeft + hdr.offsetWidth ) )
						break;
				}
			}
			if( hdr )
			{
				if( i < this.FEditableColumns.length )
					cp.style.left = hdr.offsetLeft + "px";
				else
					cp.style.left = ( hdr.offsetLeft + hdr.offsetWidth ) + "px";
				cp.style.height = this.FMovingCol.offsetHeight + "px";
				cp.style.display = "block";
				cp.style.top = this.FHeaderTop + "px";
			}
		}
		else if( this.FMovingGroup )
		{
			var cm = document.getElementById( this.id + "_ColMover" );
			var cp = document.getElementById( this.id + "_ColPositioner" );
			cm.style.left = ( getEventPageX( event ) - this.FMouseOffsetX - getObjectScreenX( this.FScrollerDiv ) ) + "px";
			cm.style.top = this.FHeaderOffset + ( getEventPageY( event ) - this.FMouseOffsetY - getObjectScreenY( this.FScrollerDiv ) ) + "px";
			cm.style.width = this.FMovingGroup.offsetWidth + "px";
			cm.style.display = "block";
			var np = ( getEventPageX( event ) - getObjectScreenX( this.FScrollerDiv ) );
			var tp = ( getEventPageY( event ) - getObjectScreenY( this.FGroupBar ) );
			var i, hdr = null;
			var groupCols = JTGetChildrenByTagName( JTLocateFirstChildByTagName( JTLocateFirstChildByTagName( JTLocateFirstChildByTagName( this.FGroupBar, "TABLE" ), "TBODY" ), "TR" ), "TD" );
			for( i = 0; i < groupCols.length; ++i )
			{
				hdr = groupCols[ i ];
				if( hdr.className.indexOf( "nogroups" ) > -1 )
					break;
				if( np <= ( hdr.offsetLeft + hdr.offsetWidth ) )
					break;
			}
			if( hdr )
			{
				if( i < groupCols.length )
					cp.style.left = hdr.offsetLeft + "px";
				else
					cp.style.left = ( hdr.offsetLeft + hdr.offsetWidth ) + "px";
				cp.style.height = this.FGroupBar.offsetHeight + "px";
				cp.style.display = "block";
				cp.style.top = this.FGroupBar.offsetTop + "px";
			}
		}
	}

	gridObject._cc = function( e, cell )
	{
		if( !this.FCanSelect )
			return;
		if( this.cancelCellClick )
		{
			this.cancelCellClick = false;
			return;
		}
		this.cancelCellClick = false;

		var event = e || window.event;
		var cellInfo = safeSplit( cell.id, "_" );
		var row = cellInfo[cellInfo.length - 2];
		var col = cellInfo[cellInfo.length - 1];
		if( row == this.EditingRow )
			return;
		if( this.FRowSelect )
			this.selectRow( row, true, e.shiftKey, e.ctrlKey );
		else
			this.selectCell( row, col, true, e.shiftKey, e.ctrlKey );
	}
	
	gridObject._cdc = function( rowIndex )
	{
		if( rowIndex > -1 )
			this.Edit( rowIndex );
	}

	gridObject._selFieldContainsAndAdd = function( rowIndex, colIndex )
	{
		var selectField = document.getElementById( this.id + "_Selection" );

		var rows = safeSplit( selectField.value, "|" );
		var i, j, cols;
		for( i = 0; i < rows.length; ++i )
		{
			cols = safeSplit( rows[ i ], "," );
			var selRowIndex = cols[ 0 ];
			if( selRowIndex == rowIndex )
				break;
		}

		if( i >= rows.length )
		{
			rows.push( rowIndex + "," + colIndex );
			selectField.value = rows.join( "|" );
			return false;
		}

		for( j = 1; j < cols.length; ++j )
		{
			if( cols[ j ] == colIndex )
				break;
		}

		if( j < cols.length )
			return true;

		cols.push( colIndex );
		rows[ i ] = cols.join( "," );
		selectField.value = rows.join( "|" );
		return false;
	}

	gridObject._selFieldRemove = function( rowIndex, colIndex )
	{
		var selectField = document.getElementById( this.id + "_Selection" );

		var rows = safeSplit( selectField.value, "|" );
		var i, j, cols;
		for( i = 0; i < rows.length; ++i )
		{
			cols = safeSplit( rows[ i ], "," );
			var selRowIndex = cols[ 0 ];
			if( selRowIndex == rowIndex )
			{
				for( j = 0; j < cols.length; ++j )
				{
					if( cols[ j ] == colIndex )
					{
						cols.splice( j, 1 );
						if( cols.length == 1 )
							rows.splice( i, 1 );
						else
							rows[ i ] = cols.join( "," );
						selectField.value = rows.join( "|" );
						return;
					}
				}
			}
		}
	}

	gridObject._loadSelection = function()
	{
		var selectField = document.getElementById( this.id + "_Selection" );
		var rows = safeSplit( selectField.value, "|" );
		var i, j, cols;

		selectField.value = "";

		for( i = 0; i < rows.length; ++i )
		{
			cols = safeSplit( rows[ i ], "," );
			var selRowIndex = cols[ 0 ];
			if( this.FRowSelect )
			{
				this.selectRow( selRowIndex, true, false, true ); 
			}
			else
			{
				for( j = 1; j < cols.length; ++j )
					this.selectCell( selRowIndex, cols[ j ], true, false, true );
			}
		}
	}

	gridObject._StartColMove = function( e, cell )
	{
		if( !this.FCanMoveCols )
			return;

		var event = e || window.event;
		this.FHeaderOffset = getObjectScreenY( this.FScrollerDiv ) - getObjectScreenY( this );
		this.FHeaderTop = getObjectScreenY( this.FHeaderDiv ) - getObjectScreenY( this );
		this.FMouseOffsetX = getEventPageX( event ) - getObjectScreenX( cell );
		this.FMouseOffsetY = getEventPageY( event ) - getObjectScreenY( cell );
		this.FMovingCol = cell;
		this.style.MozUserSelect = "none";
		this.ondragstart = function() { return false; };
		this.onselectstart = function() { return false; };
		JTPlatinumGridResizing = this;
		document.getElementById( this.id + "_ColMover" ).innerHTML = document.getElementById( cell.id + "_caption" ).innerHTML;
		addEvent( this, "mousemove", JTPlatinumGridMouseMove );
		addEvent( document, "mouseup", JTPlatinumGridEndColMove );

		event.cancelBubble = true;
		if( event.stopPropagation )
			event.stopPropagation();
	}

	gridObject._EndColMove = function(e) {
		var event = e || window.event;
		var np = (getEventPageX(event) - getObjectScreenX(this.FScrollerDiv));
		var i, tp = -1, col = this.FMovingCol;
		if (this.FGroupBar)
			tp = (getEventPageY(event) - getObjectScreenY(this.FGroupBar));

		this.style.MozUserSelect = "";
		this.ondragstart = null;
		this.onselectstart = null;
		this.FMovingCol = null;
		deleteEvent(this, "mousemove", JTPlatinumGridMouseMove);
		deleteEvent(document, "mouseup", JTPlatinumGridEndColMove);
		document.getElementById(this.id + "_ColMover").style.display = "none";
		document.getElementById(this.id + "_ColPositioner").style.display = "none";

		if (this.FGroupBar && tp > -1 && tp < this.FGroupBar.offsetHeight) {
			var groupCols = JTGetChildrenByTagName(JTLocateFirstChildByTagName(JTLocateFirstChildByTagName(JTLocateFirstChildByTagName(this.FGroupBar, "TABLE"), "TBODY"), "TR"), "TD");
			for (i = 0; i < groupCols.length; ++i) {
				if (groupCols[i].className.indexOf("nogroups") > -1) {
					i = groupCols.length;
					break;
				}
				if (np <= (groupCols[i].offsetLeft + groupCols[i].offsetWidth))
					break;
			}
			var pcs = safeSplit(this.FGroupBy, ",");
			var cs = col.id.split("_");
			pcs.splice(i, 0, this.FEditableColumns[cs[cs.length - 1]].DataField);
			this.FGroupBy = pcs.join(",");
			this._execRequestor("group," + this.FGroupBy);

			return;
		}

		for (i = 0; i < this.FEditableColumns.length; ++i) {
			var hdr = document.getElementById(this.id + "_header_" + i);
			if (np <= (hdr.offsetLeft + hdr.offsetWidth))
				break;
		}
		var cs = col.id.split("_");
		cs = cs[cs.length - 1];
		if (cs != i)
			this._execRequestor("movecol," + this.FEditableColumns[cs].Name + "," + i);
	}

	gridObject._resetHeader = function()
	{
		if( JTIEVer > 0 )
		{
			var ScrollerDiv = document.getElementById( this.id + "_ScrollerDiv" );
			var IntTable = document.getElementById( this.id + "_IntTable" );
			var tHead = JTLocateFirstChildByTagName( IntTable, "THEAD" );
			var rows = JTGetChildrenByTagName( tHead, "TR" );
			for( var i = 0; i < rows.length; ++i )
				rows[ i ].style.top = ScrollerDiv.scrollTop + "px";
		}
	}

	gridObject._initFixedCols = function()
	{
		var hasFixedCols = false;
		var ScrollerDiv = document.getElementById( this.id + "_ScrollerDiv" );
		var IntTable = document.getElementById( this.id + "_IntTable" );
		var tBody = JTLocateFirstChildByTagName( IntTable, "TBODY" );
		var first = true;
		if( tBody )
		{
			var rows = JTGetChildrenByTagName( tBody, "TR" );
			for( var i = 0; i < rows.length; ++i )
			{
				var cols = JTGetChildrenByTagName( rows[ i ], "TD" );
				for( var j = 0; j < cols.length; ++j )
				{
					var col = cols[ j ];
					if( col.className.indexOf( "noscrollcell" ) > -1 )
					{
						var div = JTLocateFirstChildByTagName( col, "DIV" );
						div.origLeft = ( col.offsetLeft - 1 );
						// div.style.top = ( col.offsetTop + tBody.offsetTop + ( ( JTIEVer < 7 && JTIEVer > -1 ) ? 0 : 0 ) + this.FHeaderDiv.offsetHeight ) + "px"; // +1 because of tBody top border.
						div.style.top = ( col.offsetTop ) + "px";
						if( JTIEVer > -1 && tBody.clientWidth == 0 )
							div.style.width = ( col.offsetWidth - ( first ? 11 : 11 ) ) + "px";	// -10 for div padding
						else
							div.style.width = ( col.offsetWidth - ( tBody.offsetWidth - tBody.clientWidth ) - 11 ) + "px";	// -10 for div padding
						div.style.height = ( col.offsetHeight - 5 ) + "px";
						div.style.left = ( col.offsetLeft - 1 ) + "px";

						hasFixedCols = true;
					}
				}
				
				first = false;
			}
		}
		this.FHasFixedCols = hasFixedCols;
		if( !hasFixedCols )
			return;

		var headerColRow = document.getElementById( this.id + "_HeaderTableColumnHeader" );
		var filterColRow = document.getElementById( this.id + "_FilterBar" );
		if( headerColRow )
		{
			var cols = JTGetChildrenByTagName( headerColRow, "TD" );
			var filterCols = ( filterColRow ? JTGetChildrenByTagName( filterColRow, "TD" ) : null );
			for( var j = 0; j < cols.length; ++j )
			{
				var col = cols[ j ];
				var filterCol = filterCols ? filterCols[j] : null;
				if( col.className.indexOf( "noscrollhdr" ) > -1 )
				{
					var div = document.getElementById( col.id + "_fixedhdr" );
					if( !div )
					{
						var table = JTLocateFirstChildByTagName( col, "TABLE" );
						div = document.createElement( "div" );
						div.id = col.id + "_fixedhdr";
						div.className = "noscrollhdrdiv";
						div.style.position = "absolute";
						div.style.top = col.offsetTop + "px";
						div.style.left = col.offsetLeft + "px";
						div.style.width = ( col.offsetWidth - 4 ) + "px";
						div.style.height = ( col.offsetHeight - 6 ) + "px";
						// col.removeChild( table );
						div.appendChild( table.cloneNode( true ) );
						col.appendChild( div );
						
						if( filterCol )
						{
							var filterDiv = document.createElement( "div" );
							filterDiv.id = filterCol.id + "_fixedfilter";
							filterDiv.className = "noscrollfilterdiv";
							filterDiv.style.position = "absolute";
							filterDiv.style.top = ( filterCol.offsetTop ) + "px";
							filterDiv.style.left = filterCol.offsetLeft + "px";
							filterDiv.style.width = ( filterCol.offsetWidth - 3 ) + "px";
							filterDiv.style.height = ( filterCol.offsetHeight - 5 ) + "px";
							filterDiv.innerHTML = filterCol.innerHTML;
							filterCol.innerHTML = "";
							filterCol.appendChild( filterDiv );
						}
					}
					else
					{
						div.style.width = ( col.offsetWidth - 4 ) + "px";
						div.style.height = ( col.offsetHeight - 6 ) + "px";
					}
				}
			}
		}

		if( JTIEVer < 0 )
			this._updateGridHeight();

		return ( hasFixedCols && JTIEVer < 0 );
	}
	
	gridObject._updateFixedColPositions = function()
	{
		if( this.FTBody && this.FHasFixedCols )
		{
			var rows = JTGetChildrenByTagName( this.FTBody, "TR" );
			for( var i = 0; i < rows.length; ++i )
			{
				var cols = JTGetChildrenByTagName( rows[ i ], "TD" );
				for( var j = 0; j < cols.length; ++j )
				{
					var col = cols[ j ];
					if( col.className.indexOf( "noscrollcell" ) > -1 )
					{
						var div = JTLocateFirstChildByTagName( col, "DIV" );
						div.style.left = ( div.origLeft + this.FScrollerDiv.scrollLeft ) + "px";
					}
				}
			}
		}
	}
	
	gridObject._updateGridHeight = function()
	{
		var ScrollerDiv = document.getElementById( this.id + "_ScrollerDiv" );
		var IntTable = document.getElementById( this.id + "_IntTable" );
		var Header = document.getElementById( this.id + "_Header" );
		var HeaderTableColumnRow = document.getElementById( this.id + "_HeaderTableColumnHeader" );
		var tHead = JTLocateFirstChildByTagName( IntTable, "THEAD" );
		var tBody = JTLocateFirstChildByTagName( IntTable, "TBODY" );
		var outerNode = getOuterNode( this );
		
		/*
		if( JTIEVer > 0 )
		{		
			if( this.FAllowHorizontalScrolling )
				ScrollerDiv.style.overflowY = "auto";
		}
		*/

		if( this.FAllowScrolling )
		{
			if( outerNode )
			{
				var h = 0;
				var children = JTGetChildrenByTagName( this, "DIV" );
				for( var i = 0; i < children.length; ++i )
				{
					if ((children[i].className == "toppager" && children[i].getElementsByTagName("DIV").length > 0) || children[i].className == "pager" || children[i].className == "groupbar")
						h += children[ i ].offsetHeight;
				}
				// var scrollBarHeight = ScrollerDiv.offsetHeight - ScrollerDiv.clientHeight;
				ScrollerDiv.style.height = ( outerNode.offsetHeight - h - 1 - Header.offsetHeight ) + "px";
				// FF bug.
				if( ScrollerDiv.className.indexOf( "bugfixer" ) > -1 )
					ScrollerDiv.className = ScrollerDiv.className.replace( " bugfixer", "" );
				else
					ScrollerDiv.className += " bugfixer";
			}
			
			/*	
			var headerEndCol = document.getElementById( this.id + "_HeaderEndColSizer" );
			if( headerEndCol )
				headerEndCol.style.width = ( ScrollerDiv.offsetWidth - ScrollerDiv.clientWidth ) + "px";
			*/

			if( JTIEVer < 7 && JTIEVer > -1 )
			{
				this.style.width = "100%";
				Header.style.width = "100%";
				ScrollerDiv.parentNode.style.setExpression( "width", "parentNode.clientWidth" );
				ScrollerDiv.parentNode.style.position = "relative";
				ScrollerDiv.parentNode.style.overflow = "hidden";
				ScrollerDiv.style.width = "100%";
			}

			this._updateEndCol();			
			this._updateColHeader( true );
		}
		else
		{
			//this.style.overflow = "visible";
			this.style.height = "";
		}
	}
	
	gridObject._resetColumns = function()
	{
		if( !this.FAllowScrolling )
			return;

		var HeaderTableColumnRow = document.getElementById( this.id + "_HeaderTableColumnHeader" );
		
		if( HeaderTableColumnRow )
		{
			var headerCol = document.getElementById( this.id + "_SelectColHeader" );
			if( headerCol )
			{
				var headerColDef = document.getElementById( this.id + "_colitem_hdr_select" );
				if( headerColDef )
					headerColDef.width = 25;
			}
		
			var headerColPrefix = this.id + "_header_";
			var cols = JTGetChildrenByTagName( HeaderTableColumnRow, "TD" );
			for( var i = 0; i < cols.length; ++i )
			{
				headerCol = cols[ i ];
				if( headerCol.id.substr( 0, headerColPrefix.length ) == headerColPrefix && headerCol.className.indexOf( "novisible" ) == -1 )
				{
					var rowColID = headerCol.id.substr( headerColPrefix.length );
					var headerColDef = document.getElementById( this.id + "_colitem_hdr_" + rowColID );
					if( headerColDef )
						headerColDef.width = "";
				}
			}

			headerCol = document.getElementById( this.id + "_EditColHeader" );
			if( headerCol )
			{
				var headerColDef = document.getElementById( this.id + "_colitem_hdr_edit" );
				if( headerColDef )
					headerColDef.width = "127";
			}
		}
		
		this._updateEndCol();
		this._updateColHeader( true );
	}

	gridObject._updateEndCol = function() {
		if (this.FAllowScrolling) {
			if (this.FScrollerDiv.offsetWidth == this.FScrollerDiv.clientWidth && (JTIEVer < 0 || this.FScrollerDiv.scrollHeight <= this.FScrollerDiv.clientHeight)) {
				this.FHeaderDiv.style.marginRight = "0";
			}
			else {
				if (JTIEVer > -1) {
					// IE7 doesn't show scrollbars at this point, so we have to force them to get their width.
					this.FScrollerDiv.style.overflow = "scroll";
				}

				var w;
				if (this.FScrollerDiv.offsetWidth == this.FScrollerDiv.clientWidth)
					w = 11;
				else
					w = this.FScrollerDiv.offsetWidth - this.FScrollerDiv.clientWidth;

				if (JTIEVer > -1)
					this.FScrollerDiv.style.overflow = "auto";

				if (JTIEVer > -1 && JTIEVer < 7) {
					this.FHeaderDiv.style.width = this.FScrollerDiv.clientWidth + "px";
				}
				else {
					this.FHeaderDiv.style.marginRight = w + "px";
				}
			}
		}
	}
	
	gridObject._updateColHeader = function( updateHeader )
	{
		if( !this.FAllowScrolling )
			return;

		var ScrollerDiv = document.getElementById( this.id + "_ScrollerDiv" );
		var IntTable = document.getElementById( this.id + "_IntTable" );
		var Header = document.getElementById( this.id + "_Header" );
		var HeaderTable = document.getElementById( this.id + "_HeaderTable" );
		var HeaderTableColumnRow = document.getElementById( this.id + "_HeaderTableColumnHeader" );
		var tHead = JTLocateFirstChildByTagName( IntTable, "THEAD" );
		var tBody = JTLocateFirstChildByTagName( IntTable, "TBODY" );
		var outerNode = getOuterNode( this );
		
		IntTable.style.width = HeaderTable.clientWidth + "px";
		
		if( HeaderTableColumnRow )
		{
			var headerPaddingWidth = 0;
			var headerWidthAdjust = 0;
			if( JTIEVer > -1 )
			{
				headerPaddingWidth = ( JTIEVer > 6 ) ? 4 : 9;
				headerWidthAdjust = 0;
			}
		
			var headerCol = document.getElementById( this.id + "_SelectColHeader" );
			if( headerCol )
			{
				var rowColDef = document.getElementById( this.id + "_colitem_body_select" );
				var headerColDef = document.getElementById( this.id + "_colitem_hdr_select" );
				if( rowColDef && headerColDef )
				{
					// Added "padding" fix for IE, seems to need it.
					if( updateHeader )
						w = 24;
					else
						w = headerCol.offsetWidth - headerPaddingWidth;

					if( updateHeader )
						headerColDef.width = w - headerWidthAdjust;

					rowColDef.width = w;
				}
			}
		
			var headerColPrefix = this.id + "_header_";
			var tw = 0;
			var cols = JTGetChildrenByTagName( HeaderTableColumnRow, "TD" );
			var gbi = 0;
			for( var i = 0; i < cols.length; ++i )
			{
				headerCol = cols[ i ];
				if( headerCol.id.substr( 0, headerColPrefix.length ) == headerColPrefix && headerCol.className.indexOf( "novisible" ) == -1 )
				{
					var rowColID = headerCol.id.substr( headerColPrefix.length );
					var rowCol = document.getElementById( this.id + "_cell_0_" + rowColID );
					var rowColDef = document.getElementById( this.id + "_colitem_body_" + rowColID );
					var headerColDef = document.getElementById( this.id + "_colitem_hdr_" + rowColID );
					if( rowColDef && headerColDef )
					{
						// Added "padding" fix for IE, seems to need it.
						w = headerCol.offsetWidth - headerPaddingWidth;

						if( updateHeader )
						{
							headerColDef.width = Math.max( w - headerWidthAdjust, 1 );
							headerCol.style.width = ( JTIsWebKit ? (headerColDef.width + "px") : "" );
						}

						rowColDef.width = Math.max( w, 1 );
						if( ( JTIsWebKit || JTFFVer == 2 ) && rowCol )
							rowCol.style.width = rowColDef.width + "px";
					}
				}
				else if( headerCol.className.indexOf( "groupbyheader" ) > -1 )
				{
					var rowColDef = document.getElementById( this.id + "_colitem_body_gb" + gbi );
					if( rowColDef )
					{
						// 1. Added "padding" fix for IE, seems to need it.					
						// rowColDef.width = headerCol.offsetWidth - headerPaddingWidth;
						// 2. Removed the padding because we removed the padding from the group cell.
						// 3. Commented the call out because the columns header/body didn't match
						// rowColDef.width = headerCol.offsetWidth;
					}
						 
					++gbi;
				}
			}

			headerCol = document.getElementById( this.id + "_EditColHeader" );
			if( headerCol )
			{
				var rowColDef = document.getElementById( this.id + "_colitem_body_edit" );
				var headerColDef = document.getElementById( this.id + "_colitem_hdr_edit" );
				if( rowColDef && headerColDef )
				{
					// Added "padding" fix for IE, seems to need it.
					w = headerCol.clientWidth;

					//if( updateHeader )
					//	headerColDef.width = w - 1;

					rowColDef.width = "126px";
				}
			}
		}
		
		if( JTIEVer > -1 )
		{
			this.FScrollerDiv.style.overflow = "hidden";
			IntTable.style.width = HeaderTable.clientWidth + "px";
			this.FScrollerDiv.style.overflow = "auto";
		}
	}

	gridObject._HeaderClick = function( e, colFieldName, otherSortDirection )
	{
		var event = e || window.event;
		var i, curSort = safeSplit( this.FSortBy, "," );
		for( i = 0; i < curSort.length; ++i )
		{
			var colSort = curSort[ i ].trim();
			var pieces = colSort.split( /\s+/, 2 );
			if( pieces[ 0 ] == colFieldName )
				break;
		}
		if( i < curSort.length )
		{
			curSort[ i ] = colFieldName + " " + otherSortDirection;
			this.FSortBy = curSort.join( "," );
		}
		else
		{
			if( event.shiftKey )
			{
				if( this.FSortBy.length > 0 )
					this.FSortBy += ",";
				this.FSortBy += colFieldName + " " + otherSortDirection;
			}
			else
			{
				this.FSortBy = colFieldName + " " + otherSortDirection;
			}
		}
		this.SortCustom( this.FSortBy );
		return false;
	}

	gridObject._startGroupMove = function( e, cellSpan, cellID )
	{
		var event = e || window.event;
		var cell = document.getElementById( cellID );
		this.FHeaderOffset = getObjectScreenY( this.FScrollerDiv ) - getObjectScreenY( this );
		this.FMouseOffsetX = getEventPageX( event ) - getObjectScreenX( cell );
		this.FMouseOffsetY = getEventPageY( event ) - getObjectScreenY( cell );
		this.FMovingGroup = cell;
		this.style.MozUserSelect = "none";
		this.FGroupBar.style.MozUserSelect = "none";
		this.ondragstart = function() { return false; };
		this.onselectstart = function() { return false; };
		JTPlatinumGridResizing = this;
		document.getElementById( this.id + "_ColMover" ).innerHTML = cellSpan.innerHTML;
		addEvent( this, "mousemove", JTPlatinumGridMouseMove );
		addEvent( document, "mouseup", JTPlatinumGridEndGroupMove );

		event.cancelBubble = true;
		if( event.stopPropagation )
			event.stopPropagation();
		return false;
	}

	gridObject._endGroupMove = function( e )
	{
		var event = e || window.event;
		var np = ( getEventPageX( event ) - getObjectScreenX( this.FScrollerDiv ) );
		var i, colIndex, col = this.FMovingGroup;

		this.style.MozUserSelect = "";
		this.FGroupBar.style.MozUserSelect = "";
		this.ondragstart = null;
		this.onselectstart = null;
		this.FMovingGroup = null;
		deleteEvent( this, "mousemove", JTPlatinumGridMouseMove );
		deleteEvent( document, "mouseup", JTPlatinumGridEndGroupMove );
		document.getElementById( this.id + "_ColMover" ).style.display = "none";
		document.getElementById( this.id + "_ColPositioner" ).style.display = "none";

		var tp = ( getEventPageY( event ) - getObjectScreenY( this.FGroupBar ) );
		var groupCols = JTGetChildrenByTagName( JTLocateFirstChildByTagName( JTLocateFirstChildByTagName( JTLocateFirstChildByTagName( this.FGroupBar, "TABLE" ), "TBODY" ), "TR" ), "TD" );
		for( colIndex = 0; colIndex < groupCols.length; ++colIndex )
		{
			if( groupCols[ colIndex ].id == col.id )
				break;
		}
		if( colIndex >= groupCols.length )
			return;

		if( tp < 0 || tp > this.FGroupBar.offsetHeight )
		{
			var curSort = safeSplit( this.FGroupBy, "," );
			if( colIndex < curSort.length )
			{
				curSort.splice( colIndex, 1 );
				this._groupCommand( curSort.join( "," ) );
			}
		}
		else
		{
			var hdr = null;
			for( i = 0; i < groupCols.length; ++i )
			{
				hdr = groupCols[ i ];
				if( hdr.className.indexOf( "nogroups" ) > -1 )
					break;
				if( np <= ( hdr.offsetLeft + hdr.offsetWidth ) )
					break;
			}
			if( hdr )
			{
				var curSort = safeSplit( this.FGroupBy, "," );
				var groupData;
				if( colIndex < curSort.length && colIndex != i )
				{
					groupData = curSort.splice( colIndex, 1 );
					curSort.splice( i, 0, groupData[ 0 ] );
					this._groupCommand( curSort.join( "," ) );
				}
			}
		}
	}

	gridObject._groupCommand = function( groupBy )
	{
		document.getElementById( this.id + "_Selection" ).value = "";
		this._execRequestor( "group," + groupBy );
	}

	gridObject._groupClick = function( fieldName, direction )
	{
		var curSort = safeSplit( this.FGroupBy, "," );
		var i;
		for( i = 0; i < curSort.length; ++i )
		{
			var colSort = curSort[ i ].trim();
			var pieces = colSort.split( /\s+/, 2 );
			if( pieces[ 0 ] == fieldName )
				break;
		}
		if( i < curSort.length )
		{
			curSort[ i ] = fieldName + " " + direction;
			this._groupCommand( curSort.join( "," ) );
		}
		else
		{
			this._groupCommand( fieldName + " " + direction );
		}
	}

	gridObject._expCollapseGroup = function( cell, rowIndex )
	{
		var o, r = document.getElementById( this.id + "_grouprow_" + rowIndex );
		o = ( cell.className.indexOf( "expanded" ) > -1 );
		if( o )
			cell.className = "groupexpcolcell collapsed";
		else
			cell.className = "groupexpcolcell expanded";
		var i = r.className.indexOf( "grouplevel" );
		var curLevel = parseInt( r.className.substr( i + 10 ) );

		while( ( r = r.nextSibling ) )
		{
			if( r.nodeType == 1 )
			{
				if( r.className.indexOf( "grouprow" ) > -1 )
				{
					i = r.className.indexOf( "grouplevel" );
					var rowLevel = parseInt( r.className.substr( i + 10 ) );
					if( rowLevel <= curLevel )
						break;
					
					var cells = r.getElementsByTagName( "TD" );
					for( i = 0; i < cells.length; ++i )
					{
						cell = cells[ i ];
						if( cell.className.indexOf( "groupexpcolcell" ) == -1 )
							continue;
	
						if( o )
							cell.className = "groupexpcolcell collapsed";
						else
							cell.className = "groupexpcolcell expanded";
					}
				}

				if( o )
					r.style.display = "none";
				else
					r.style.display = "";
			}
		}
	}

	gridObject._delayFilterFire = function()
	{
		if( this.FFilterTimeout )
			clearTimeout( this.FFilterTimeout );

		this.FFilterTimeout = setTimeout( this.id + "._execRequestor('');", 1000 );
	}

	gridObject._txtFilterKeyDown = function(input, e) {
		var event = e || window.event;
		var kc = event.charCode || event.keyCode;

		if (this.FFilterTimeout)
			clearTimeout(this.FFilterTimeout);

		if (kc == 0x0D) {
			this._execRequestor("");
			return false;
		}
		else if (this.FFilterDelay)
			this._delayFilterFire();
	}

	gridObject._txtFilterFocus = function( input )
	{
		input.lastValue = input.value;
	}

	gridObject._txtFilterBlur = function(input) {
		if (input.value != input.lastValue) {
			if (this.FFilterTimeout)
				clearTimeout(this.FFilterTimeout);
			if (this.FFilterDelay)
				this._execRequestor("");
		}
	}

	gridObject._txtFilterMethodChange = function( select, e, filterName )
	{
		if( this.FFilterTimeout )
			clearTimeout( this.FFilterTimeout );
		this._execRequestor( "" );
	}

	gridObject._boolFilterClick = function( input, e )
	{
		this._execRequestor( "" );
	}

	gridObject._cellExpand = function(e, span, cellID, rowIndex) {
		if (this.FParentField) {
			var collapse = (span.className.indexOf("collapsed") == -1);
			var row = document.getElementById(this.id + "_row_" + rowIndex);
			var rowLevel = this.getRowLevel(row);
			var nr = row;
			while ((nr = nr.nextSibling)) {
				if (nr.nodeType == 1 && nr.tagName == "TR") {
					if (this.getRowLevel(nr) > rowLevel) {
						if (collapse)
							nr.style.display = "none";
						else
							nr.style.display = "";
					}
					else {
						break;
					}
				}
			}
			if (collapse) {
				span.className = span.className.replace(" expanded", "");
				span.className += " collapsed";
			}
			else {
				span.className = span.className.replace(" collapsed", "");
				span.className += " expanded";
			}
		}
		else {
			var detailKey;

			if (span.className.indexOf("collapsed") > -1)
				detailKey = document.getElementById(this.id + "_row_" + rowIndex + "_dr").innerHTML;
			else
				detailKey = "";

			this._execRequestor("detail," + detailKey);
		}
	}

	gridObject._keyDown = function( e )
	{
		var event = e || window.event;
		var tagName = getEventTarget( event ).tagName;
		if( tagName == "INPUT" || tagName == "SELECT" || tagName == "TEXTAREA" )
			return;

		var kc = event.keyCode;

		this.SelectedCol = parseInt(this.SelectedCol);
		this.SelectedRow = parseInt(this.SelectedRow);

		if( this.SelectedRow < 0 )
			this.selectCell( 0, 0, true, false, false );
		else if( !this.FRowSelect && kc == 37 && this.SelectedCol > 0 )
			this.selectCell(this.SelectedRow, this.SelectedCol - 1, true, event.shiftKey, event.ctrlKey);
		else if( kc == 38 && this.SelectedRow > 0 )
			this.selectCell(this.SelectedRow - 1, this.SelectedCol, true, event.shiftKey, event.ctrlKey);
		else if( !this.FRowSelect && kc == 39 && this.SelectedCol < ( this.FEditableColumns.length - 1 ) )
			this.selectCell(this.SelectedRow, this.SelectedCol + 1, true, event.shiftKey, event.ctrlKey);
		else if( kc == 40 && this.SelectedRow < ( this.FVisibleRowCount - 1 ) )
			this.selectCell(this.SelectedRow + 1, this.SelectedCol, true, event.shiftKey, event.ctrlKey);
		else
			return false;

		this.ScrollCellIntoView( this.SelectedRow, this.SelectedCell );

		if( event.stopPropagation )
			event.stopPropagation();
		if( event.preventDefault )
			event.preventDefault();

		return false;
	}
	
	gridObject._tBodyMouseDown = function( e )
	{
		var event = e || window.event;
		var tagName = getEventTarget( event ).tagName;
		if( tagName == "INPUT" || tagName == "SELECT" || tagName == "TEXTAREA" )
			return;
		this.FMouseOffsetX = getEventPageX( event ) - getObjectScreenX( this ) + this.FScrollerDiv.scrollLeft;
		this.FMouseOffsetY = getEventPageY( event ) - getObjectScreenY( this );
		this.tBodyOffsetX = getObjectScreenX( this.FTBody ) - getObjectScreenX( this );
		this.tBodyOffsetY = getObjectScreenY( this.FTBody ) - getObjectScreenY( this );		
		if( this.FMouseOffsetX > ( this.FTable.clientWidth - this.tBodyOffsetX ) )
			return;
		//this.style.MozUserSelect = "none";
		this.ondragstart = function() { return false; };
		this.onselectstart = function() { return false; };
		JTPlatinumGridResizing = this;
		addEvent( this.FTBody, "mousemove", JTPlatinumGridTBodyMouseMove );
		addEvent( document, "mouseup", JTPlatinumGridTBodyMouseUp );
		event.cancelBubble = true;
		if( event.stopPropagation )
			event.stopPropagation();
	}
	
	gridObject._tBodyMouseMove = function( e )
	{
		var event = e || window.event;
		var cm = document.getElementById( this.id + "_DragSelect" );
		var sx = this.FMouseOffsetX;
		var sy = this.FMouseOffsetY;
		var ex = getEventPageX( event ) - getObjectScreenX( this ) + this.FScrollerDiv.scrollLeft;
		var ey = getEventPageY( event ) - getObjectScreenY( this );
		var l = Math.min( sx, ex );
		var t = Math.min( sy, ey );
		var w = Math.abs( ex - sx );
		var h = Math.abs( ey - sy );
		l = Math.max( this.tBodyOffsetX, l );
		t = Math.max( this.tBodyOffsetY, t );
		w = Math.min( this.FTBody.offsetWidth - ( l - this.tBodyOffsetX ), w );
		h = Math.min( this.FTBody.offsetHeight - ( t - this.tBodyOffsetY ), h );
		cm.style.left = l - this.FScrollerDiv.scrollLeft + "px";
		cm.style.top = t + "px";
		cm.style.width = w + "px";
		cm.style.height = h + "px";
		cm.style.display = "block";
	}
	
	gridObject._tBodyMouseUp = function( e )
	{
		var event = e || window.event;
		var sx = this.FMouseOffsetX;
		var sy = this.FMouseOffsetY;
		var ex = getEventPageX( event ) - getObjectScreenX( this ) + this.FScrollerDiv.scrollLeft;
		var ey = getEventPageY( event ) - getObjectScreenY( this );
		//this.style.MozUserSelect = "";
		this.ondragstart = null;
		this.onselectstart = null;
		this.FMovingCol = null;
		deleteEvent( this.FTBody, "mousemove", JTPlatinumGridTBodyMouseMove );
		deleteEvent( document, "mouseup", JTPlatinumGridTBodyMouseUp );
		var ds = document.getElementById( this.id + "_DragSelect" );
		var l = ( ds.offsetLeft - this.tBodyOffsetX ) + this.FScrollerDiv.scrollLeft;
		var t = ds.offsetTop;
		if( this.FScrollerDiv )
			t -= getObjectScreenY( this.FScrollerDiv ) - getObjectScreenY( this );
		var r = l + ds.offsetWidth;
		var b = t + ds.offsetHeight;
		ds.style.display = "none";
		var rows = JTGetChildrenByTagName( this.FTBody, "TR" );
		var sct = this.FScrollerDiv.scrollTop;
		var inSelRow = false;
		var ctl = event.ctrlKey;
		var rowCount = Math.min( this.FVisibleRowCount, rows.length );
		if( Math.abs( ex - sx ) <= 10 && Math.abs( ey - sy ) <= 10 )
			return;
		if( !ctl )
			this.deselectAll();

		for( var i = 0; i < rowCount; ++i )
		{
			var row = document.getElementById( this.id + "_row_" + i );/*rows[ i ]*/;
			var rt = row.offsetTop;
			var rb = ( row.offsetTop + row.offsetHeight );
			if( rt <= t && rb >= t )
				inSelRow = true;

			if( inSelRow )
			{
				if( this.FRowSelect )
				{
					this.selectRow( i, true, false, true );
				}
				else
				{
					var inSelCell = false;
					for( var c = 0; c < this.FEditableColumns.length; ++c )
					{
						var cell = document.getElementById( this.id + "_cell_" + i + "_" + c );
						if( !cell )
							continue;
						if( cell.offsetLeft <= l && ( cell.offsetLeft + cell.offsetWidth ) >= l )
							inSelCell = true;
						
						if( inSelCell )
						{
							this.selectCell( i, c, true, false, ctl );
							ctl = true;
						}

						if( cell.offsetLeft <= r && ( cell.offsetLeft + cell.offsetWidth ) >= r )
						{
							inSelCell = false;
							break;
						}
					}
				}
					
				ctl = true;
			}

			if( rt <= b && rb >= b )
			{
				inSelRow = false;
				break;
			}
		}
		if( Math.abs( ex - sx ) > 10 || Math.abs( ey - sy ) > 10 )
			this.cancelCellClick = true;
	}

	gridObject._divScroll = function()
	{
		var hdr = document.getElementById( this.id + "_Header" );
		hdr.scrollLeft = this.FScrollerDiv.scrollLeft;
		if( this.FHasFixedCols && this.lastScrollLeft != this.FScrollerDiv.scrollLeft )
		{
			this._updateFixedColPositions();
			this.lastScrollLeft = this.FScrollerDiv.scrollLeft;
		}
	}
	
	gridObject._editorKeyPress = function(e)
	{
		var event = e || window.event;
		var kc = event.keyCode;
		if( kc == 27 )
			this.Cancel(); 
	}
	
	gridObject._showWaitWindow = function()
	{
		var ww = document.getElementById( this.id + "_wait" );
		if( ww )
			ww.style.display = "block";
	}
	
	gridObject._onResize = function()
	{
		this._updateColHeader( true );
	}
	
	gridObject._execRequestor = function( action )
	{
		for( var c = 0; c < gridObject.FEditableColumns.length; ++c )
		{
			var txtField = document.getElementById( gridObject.id + "_" + gridObject.FEditableColumns[ c ].Name + "_Filter" );
			if( txtField )
				txtField.onblur = null;
		}
		this.FCommand.value = action;
		this.FRequestor();
		this.FCommand.value = "";
	}

	gridObject.onParentDisplayChange = function() {
		this.Load();
	}
	
	addEvent( window, "resize", function() { gridObject._onResize(); } );

	if( JTPageLoaded )
		gridObject.Load();
	// else
	// 	JTPlatinumGrids.push( gridObject );
	registerForDisplayChange(gridObject);

	eval( "window." + gridID + " = gridObject;" );
}

function JTPlatinumGridOnLoad()
{
	while( JTPlatinumGrids.length > 0 )
	{
		JTPlatinumGrids[ 0 ].Load();
		JTPlatinumGrids.shift();
	}
}

function JTPlatinumGridMouseMove( e )
{
	JTPlatinumGridResizing._MouseMove( e );
}

function JTPlatinumGridEndColResize( e )
{
	JTPlatinumGridResizing._EndColResize( e );
}

function JTPlatinumGridEndColMove( e )
{
	JTPlatinumGridResizing._EndColMove( e );
}

function JTPlatinumGridEndGroupMove( e )
{
	JTPlatinumGridResizing._endGroupMove( e );
}

function JTPlatinumGridKeyDown( e )
{
	var event = e || window.event;
    var target = getEventTarget( event );
    var gridID = target.id.split( "_" )[ 0 ];
    var gridObject = document.getElementById( gridID );

    if( gridObject )
		return gridObject._keyDown( e );
	else
		return true;
}

function JTPlatinumGridTBodyMouseDown( e )
{
	var event = e || window.event;
	var target = getEventTarget(event);
	while (target.id == "")
		target = target.parentNode;
    var gridID = target.id.split( "_" )[ 0 ];
    var gridObject = document.getElementById( gridID );

    if( gridObject )
		gridObject._tBodyMouseDown( e );
}

function JTPlatinumGridTBodyMouseMove( e )
{
	JTPlatinumGridResizing._tBodyMouseMove( e );
}

function JTPlatinumGridTBodyMouseUp( e )
{
	return JTPlatinumGridResizing._tBodyMouseUp( e );
}

function JTPlatinumGridResize( id )
{
	document.getElementById( id )._onResize();
}