var StaticGrid = null;

/* Constructor */
function HyperGrid(id, enableHover, singleClickUrlColumn, doubleClickUrlColumn, previewPaneUrlColumn, previewPaneCallback, rowToSelect,
rightClickCallback, doubleClickCallback, deleteKeyCallback, dragDropEnabled, dragDropColumn, dragText, fastRender)
{
	this.ID = id;
	this.Timer = null;
	this.EnableHover = enableHover;
	this.DoubleClickCallback = doubleClickCallback;
	this.PreviewPaneCallback = previewPaneCallback;
	this.PreviewPaneUrlColumn = previewPaneUrlColumn;
	this.SingleClickUrlColumn = singleClickUrlColumn;
	this.DoubleClickUrlColumn = doubleClickUrlColumn;
	this.RightClickCallback = rightClickCallback;
	this.DeleteKeyCallback = deleteKeyCallback;
	this.DragDropColumn = dragDropColumn;
	this.DragText = dragText;
	this.FastRender = fastRender;
	this.RowToSelect = rowToSelect + 1;
	this.Urls = new Array();
	this.DragDropEnabled = dragDropEnabled;
	this.InitializeGrid();
	StaticGrid = this;
}
/* Sets up the grid */
HyperGrid.prototype.InitializeGrid = function()
{
	var GridTable = document.getElementById(this.ID + "_Table");
	this.GridTable = GridTable;
	this.HiddenInput = document.getElementById(this.ID + "_HiddenInput");
	this.HiddenLSR = document.getElementById(this.ID + "_HiddenLSR");
	this.Scrollable = document.getElementById('Scrollable');
	var Div = document.getElementById(this.ID);
	Div.disposeRef = this;
	Div.dispose = function() { this.disposeRef.DeinitializeGrid(); this.disposeRef = null; };
	if (!GridTable) return;
	this.CurrentRowNumber = -1;
	this.VirtualRowNumber = -1;
	if (!this.FastRender)
		this.HGRows = HGGetElementsByTagName(GridTable, "TR", 2);
	else
		this.HGRows = GridTable.getElementsByTagName("TR");
	this.HGRows[0].HGGrid = this;
	this.SetupHeader(this.HGRows[0]);
	for (index = 1; index < this.HGRows.length; index++)
	{
		var row = this.HGRows[index];
		if (index == 1) this.FirstClicked = row;
		row.HGGrid = this;
		row.HGRowNumber = index - 1;
		this.SetupHGRow(row);
	}


	this.Focuser = document.getElementById(this.ID + "_Focuser");
	if (this.Focuser == null)
	{
		this.Focuser = document.createElement("input");
		this.Focuser.type = "text";
		this.Focuser.style.position = "absolute";
		this.Focuser.style.width = "0px";
		this.Focuser.style.height = "0px";
		this.Focuser.style.margin = "0px";
		this.Focuser.style.padding = "0px";
		this.Focuser.style.outline = "none";
		this.Focuser.style.border = "none";
		this.Focuser.id = this.ID + "_Focuser";
		var theForm = document.getElementById("aspnetForm");
		document.body.insertBefore(this.Focuser, theForm);
	}
	this.Focuser.KeyPressHandler = this.KeyPressHandler;
	HGAddHandler(this.Focuser, "keydown", "KeyPressHandler");

	if (document.HGOnBlur == undefined)
		document.HGOnBlur = this.Focus;
};

/* Configures the header row */
HyperGrid.prototype.SetupHeader = function(row)
{
	row.HGCells = row.getElementsByTagName("TH");
	for (ci = 0; ci < row.HGCells.length; ci++)
	{
		var cell = row.HGCells[ci];
		cell.HGRow = row;
		cell.HGGrid = row.HGGrid;
		this.FindCheckBoxes(cell);

		if (cell.CheckBox != undefined)
		{
			cell.CheckBox.HGRow = row;
			cell.ClickHandler = this.CheckAll;
			cell.CheckBox.ClickHandler = this.CheckAll;
			HGAddHandler(cell, "click", "ClickHandler");
			HGAddHandler(cell.CheckBox, "click", "ClickHandler");
		}
		else
		{
			cell.ClickHandler = this.Focus;
			HGAddHandler(cell, "click", "ClickHandler");
		}
	}
}
/* Configures each row of the grid */
HyperGrid.prototype.ReturnFalse = function(evt)
{
	HGCancelEvent(evt);
	return false;
}
HyperGrid.prototype.HighlightRow = function(evt)
{
	HGAddClass(this, "hover");
}
HyperGrid.prototype.UnHighlightRow = function(evt)
{
	HGRemClass(this, "hover");
}
HyperGrid.prototype.SetupHGRow = function(row)
{
	row.HGCells = row.getElementsByTagName("TD");
	if (this.EnableHover && !this.FastRender)
	{
		row.HoverHandler = this.HighlightRow;
		row.UnHoverHandler = this.UnHighlightRow;
		HGAddHandler(row, "mouseover", "HoverHandler");
		HGAddHandler(row, "mouseout", "UnHoverHandler");
	}

	var findCheckBoxes = true;
	for (ci = 0; ci < row.HGCells.length; ci++)
	{
		var cell = row.HGCells[ci];
		cell.HGRow = row;
		cell.HGGrid = row.HGGrid;
		if (findCheckBoxes) findCheckBoxes = this.FindCheckBoxes(cell);

		if (cell.CheckBox == undefined)
		{
			if (cell.HGRow.UniqueID == undefined)
				cell.HGRow.UniqueID = row.HGRowNumber;
			cell.ClickHandler = this.ClickHandler;
			HGAddHandler(cell, "click", "ClickHandler");

			cell.DblClickHandler = this.DblClickHandler;
			HGAddHandler(cell, "dblclick", "DblClickHandler");

			if (!this.FastRender)
			{
				cell.RightClickHandler = this.RightClickHandler;
				HGAddHandler(cell, "contextmenu", "RightClickHandler");

				cell.SelectHandler = this.ReturnFalse;
				HGAddHandler(cell, "selectstart", "SelectHandler");

				cell.BeginDrag = this.BeginDrag;
				HGAddHandler(cell, "mousedown", "BeginDrag");
			}
		}
		else
		{
			var splitparts = cell.CheckBox.id.split("_");
			cell.HGRow.UniqueID = splitparts[splitparts.length - 1];
			cell.CheckBox.HGRow = row;
			if (cell.CheckBox.checked)
			{
				HGSelectRow(row, true);
				row.HGGrid.FirstClicked = row;
				row.HGGrid.CurrentRowNumber = row.HGRowNumber;
			}
			cell.CheckHandler = this.CheckHandler;
			cell.CheckBox.CheckHandler = this.CheckHandler;
			HGAddHandler(cell, "click", "CheckHandler");
			HGAddHandler(cell.CheckBox, "click", "CheckHandler");
		}
	}
};

/* Finds the first checkbox in a cell */
HyperGrid.prototype.FindCheckBoxes = function(cell)
{
	var checkboxes = cell.getElementsByTagName("input");
	for (cbi = 0; cbi < checkboxes.length; cbi++)
	{
		var cb = checkboxes[cbi];
		if (cb.type == "checkbox")
		{
			cell.HGRow.CheckBox = cb;
			cell.CheckBox = cb;
			return true;
		}
	}
	return false;
};

/* Adds a URL Column to the object */
HyperGrid.prototype.AddUrlColumn = function(name, urlRef)
{
	this.Urls[name] = urlRef;
};

/* Called after the constructor to auto select the row that needs selecting */
HyperGrid.prototype.AutoSelect = function()
{
	if (this.HGRows.length > this.RowToSelect && this.RowToSelect > 0)
	{
		var row = this.HGRows[this.RowToSelect];
		this.SingleSelectRow(this, row);
		this.EnsureVisible(this, this.RowToSelect);
		this.DoPreviewPane(this, row, false);
	}
}

/* Checks all checkboxes. Used by the header row checkbox */
HyperGrid.prototype.CheckAll = function(evt)
{
	var grid = this.HGRow.HGGrid;
	var check = this.CheckBox;
	if (check == undefined) check = this;
	check.checked = !check.checked;

	if (!check.checked)
		grid.ClearSelection(grid);
	else
	{
		for (var index = 1; index < grid.HGRows.length; index++)
			HGSelectRow(grid.HGRows[index], true);
	}
	grid.NoSingleSelect(grid);
	grid.FirstClicked = null;
	grid.CurrentRowNumber = -1;
	grid.Focus();
	return true;
}


/**************************************** selecting rows *****************************************/
/* Returns an array of all the selected rows */
HyperGrid.prototype.GetSelectedRows = function()
{
	var selectedArr = new Array();
	if (this.HGRows == null) return selectedArr;
	var counter = 0;
	for (index = 0; index < this.HGRows.length; index++)
	{
		var row = this.HGRows[index];
		if (row.IsClicked)
		{
			selectedArr[counter] = row;
			counter++;
		}
	}
	return selectedArr;
};
/* remove any selected rows from the grid */
HyperGrid.prototype.ClearSelection = function(grid)
{
	var selected = grid.GetSelectedRows();
	for (var index = 0; index < selected.length; index++)
		HGDeselectRow(selected[index]);
};
/* Clears out any info about the currently selected but unchecked row */
HyperGrid.prototype.NoSingleSelect = function(grid)
{
	grid.PrimaryRow = null;
	grid.HiddenInput.value = "";
};
/* This function selects a single row, but does not check the checkbox */
HyperGrid.prototype.SingleSelectRow = function(grid, row)
{
	HGSelectRow(row, false);
	grid.PrimaryRow = row;
	if (row.CheckBox != null) grid.HiddenInput.value = row.CheckBox.id;
	grid.FirstClicked = row;
	grid.CurrentRowNumber = row.HGRowNumber;
};
/* this row got selected */
HyperGrid.prototype.ClearEvents = function()
{
	clearTimeout(this.Timer);
}
HyperGrid.prototype.TimerEvent = function(callback)
{
	clearTimeout(this.Timer);
	this.Timer = setTimeout(callback, 200);
}
HyperGrid.prototype.SelectRow = function(evt, row, grid, mark, preview)
{
	var ctrl = HGCtrlPressed(evt);
	var shift = HGShiftPressed(evt);

	if (!ctrl && !shift && preview)
		grid.DoPreviewPane(grid, row, mark);

	if (!ctrl)
	{
		grid.ClearSelection(grid);
		grid.VirtualRowNumber = row.HGRowNumber;
	}

	if (shift)
	{
		grid.NoSingleSelect(grid);
		var firstrow = grid.FirstClicked.HGRowNumber;
		var lastrow = row.HGRowNumber;
		if (lastrow < firstrow)
		{
			firstrow ^= lastrow;
			lastrow ^= firstrow;
			firstrow ^= lastrow;
		}
		for (var index = firstrow + 1; index < lastrow + 2; index++)
			HGSelectRow(grid.HGRows[index], true);
	}
	else
	{
		if (ctrl && row.IsClicked)
			HGDeselectRow(row);
		else if (ctrl)
		{
			if (grid.PrimaryRow != null)
			{
				HGSelectRow(grid.PrimaryRow, true);
				grid.NoSingleSelect(grid);
			}
			HGSelectRow(row, true);
		}
		else
		{
			grid.FirstClicked = row;
			grid.CurrentRowNumber = row.HGRowNumber;
			grid.PrimaryRow = row;
			if (row.CheckBox != null) grid.HiddenInput.value = row.CheckBox.id;
			HGSelectRow(row, false);
		}
	}
};
HyperGrid.prototype.GetUrlForSelectedRow = function()
{
	var dcc = this.DoubleClickUrlColumn;
	if (dcc == "")
		return;
	if (this.Urls == null) return;

	if (this.PrimaryRow == null)
	{
		var rows = this.GetSelectedRows();
		if (rows == null || rows.length != 1)
			return null;

		return this.Urls[dcc][rows[0].HGRowNumber];
	}

	return this.Urls[dcc][this.PrimaryRow.HGRowNumber];
}

/******************************************************** events **************************/
/* Fire the preview pane event if neccesary */
HyperGrid.prototype.DoPreviewPane = function(grid, row, mark)
{
	var pcb = grid.PreviewPaneCallback;
	if (pcb != null)
	{
		var pcc = grid.PreviewPaneUrlColumn;
		var isNew = false;
		if (mark && row.className.indexOf('newrow') != -1)
			isNew = true;
		if (mark)
			grid.TimerEvent(function() { if (grid.Urls) { if (pcb(grid.Urls[pcc][row.HGRowNumber], isNew, mark) && mark) HGRemClass(row, "newrow"); } });
		else
			pcb(grid.Urls[pcc][row.HGRowNumber], isNew, mark);
	}
};
/* single click event */
HyperGrid.prototype.DoSingleClick = function(grid, row)
{
	var scc = grid.SingleClickUrlColumn
	if (scc != "")
		grid.TimerEvent(function() { HGRemClass(row, "newrow"); if (grid.Urls) location.href = grid.Urls[scc][row.HGRowNumber]; });
};
HyperGrid.prototype.DoRightClick = function(grid, evt)
{
	if (grid.RightClickCallback != null)
		grid.RightClickCallback(evt);
};
HyperGrid.prototype.DoDoubleClick = function(grid, row)
{
	var dcc = grid.DoubleClickUrlColumn;
	if (dcc != "")
	{
		var isNew = false;
		if (row.className.indexOf('newrow') != -1)
			isNew = true;
		grid.ClearEvents();
		HGRemClass(row, "newrow");
		if (grid.DoubleClickCallback == null)
			location.href = grid.Urls[dcc][row.HGRowNumber];
		else
			grid.DoubleClickCallback(grid.Urls[dcc][row.HGRowNumber], row.UniqueID, isNew);
	}
}



/*************************** handlers **********************/
HyperGrid.prototype.Focus = function()
{
	//	if (document.body.focus)
	//		document.body.focus()
	try
	{
		if (this.Focuser)
			this.Focuser.focus();
		else
			StaticGrid.Focuser.focus();
	}
	catch (err) { }
}

/* Key press handler for the entire document */
HyperGrid.prototype.KeyPressHandlerDown = function(evt)
{
	if (evt.keyCode == 38 || evt.keyCode == 40 || evt.keyCode == 13 || evt.keyCode == 46)
		return HGCancelEvent(evt);
	return true;
}
HyperGrid.prototype.KeyPressHandler = function(evt)
{
	var ctrl = HGCtrlPressed(evt);
	var shift = HGShiftPressed(evt);

	var grid = StaticGrid;
	var cur = grid.CurrentRowNumber;
	if (shift)
		cur = grid.VirtualRowNumber;
	if (cur < 0) cur = 0;
	if (cur > grid.HGRows.length - 2) cur = grid.HGRows.length - 2;
	var alwaystop = false;
	
	if (evt.keyCode == 38 /*up*/)
	{
		cur--;
		HGCancelEvent(evt);
	}
	else if (evt.keyCode == 40 /*down*/)
	{
		cur++;
		HGCancelEvent(evt);
	}
	else if (evt.keyCode == 13 /* enter */)
	{
		grid.DoDoubleClick(grid, grid.HGRows[cur + 1]);
		return HGCancelEvent(evt);
	}
	else if (evt.keyCode == 46 /* delete */)
	{
		if (grid.DeleteKeyCallback != null)
			grid.DeleteKeyCallback(grid.HGRows[cur + 1]);
		return HGCancelEvent(evt);
	}
	else
		return true;

	if (cur < 0)
	{
		cur = 0;
		grid.EnsureVisible(grid, grid.HGRows[cur]);
	}
	if (cur > grid.HGRows.length - 2) cur = grid.HGRows.length - 2;
	grid.SelectRow(evt, grid.HGRows[cur + 1], grid, true, true);
	grid.EnsureVisible(grid, grid.HGRows[cur + 1], alwaystop);

	return false;
}

HyperGrid.prototype.IsVisible = function(grid, row)
{
	if (grid.Scrollable == null)
		return;
	var rowTop = row.offsetTop;
	var rowBottom = rowTop + row.clientHeight;
	var scrollTop = grid.Scrollable.scrollTop;
	var scrollBottom = scrollTop + grid.Scrollable.clientHeight;
	if (rowTop < scrollTop || rowBottom > scrollBottom)
		return false;
	return true;
};

HyperGrid.prototype.EnsureVisible = function(grid, row, alwaystop)
{
	if (grid.Scrollable == null)
		return;
	var rowTop = row.offsetTop;
	var rowBottom = rowTop + row.clientHeight;
	var scrollTop = grid.Scrollable.scrollTop;
	var scrollBottom = scrollTop + grid.Scrollable.clientHeight;
	if (rowTop < scrollTop || alwaystop)
		grid.Scrollable.scrollTop = rowTop;
	else if (rowBottom > scrollBottom)
		grid.Scrollable.scrollTop += (rowBottom - scrollBottom);
};
/* row got clicked */
HyperGrid.prototype.BeginDrag = function(evt)
{
	var ctrl = HGCtrlPressed(evt);
	var shift = HGShiftPressed(evt);
	var grid = this.HGGrid;
	var row = this.HGRow;

	if (this.HGGrid.DragDropEnabled && parent.StartDragDrop)
	{
		var notClicked = !this.HGRow.IsClicked;
		if (!this.HGRow.IsClicked)
		{
			if (!ctrl && !shift)
				this.HGGrid.DoSingleClick(this.HGGrid, this.HGRow);
			this.HGGrid.SelectRow(evt, this.HGRow, this.HGGrid, true, false);
			self.EndDragFunc = function() { grid.DoPreviewPane(grid, row, true); };
		}
		else
		{
			if (ctrl)
			{
				HGDeselectRow(row);
			}
		}

		if (ctrl || (shift && notClicked))
		{
			self.finishedDragging = new Date();
		}

		var posx = 0;
		var posy = 0;
		if (evt.pageX || evt.pageY)
		{
			posx = evt.pageX;
			posy = evt.pageY;
		}
		else if (evt.clientX || evt.clientY)
		{
			posx = evt.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
			posy = evt.clientY + document.body.scrollTop + document.documentElement.scrollTop;
		}
		if (posx != 0 && posy != 0)
		{
			if (self.SetupMouseMove) SetupMouseMove();

			var count = this.HGGrid.GetSelectedRows().length;
			var dragText;
			if (count == 1)
				dragText = this.HGRow.HGCells[this.HGGrid.DragDropColumn].innerHTML;
			else
				dragText = this.HGGrid.DragText.replace(/\{0\}/, count.toString());
			parent.StartDragDrop(this.HGGrid, dragText, evt.screenX, evt.screenY, posx, posy);
		}
	}
	HGCancelEvent(evt);
	return false;
}
HyperGrid.prototype.ClickHandler = function(evt)
{
	var ctrl = HGCtrlPressed(evt);
	var shift = HGShiftPressed(evt);
	var grid = this.HGGrid;
	var row = this.HGRow;

	if (self.finishedDragging != null)
	{
		var dif = (new Date()) - self.finishedDragging;
		self.finishedDragging = null;
		if (dif < 1000)
			return false;
	}

	if (!ctrl && !shift)
		this.HGGrid.DoSingleClick(grid, row);
	this.HGGrid.SelectRow(evt, this.HGRow, this.HGGrid, true, true);


	grid.Focus();
	return true;
};
/* Called when someone right clicks a cell */
HyperGrid.prototype.RightClickHandler = function(evt)
{
	var grid = this.HGRow.HGGrid;
	if (!this.HGRow.IsClicked)
	{
		grid.ClearSelection(grid);
		grid.SingleSelectRow(grid, this.HGRow);
	}

	grid.DoRightClick(grid, evt);
	grid.Focus();
	return HGCancelEvent(evt);
};
/* Called when someone double clicks the cell */
HyperGrid.prototype.DblClickHandler = function(evt)
{
	this.HGGrid.Focus();
	this.HGGrid.DoDoubleClick(this.HGGrid, this.HGRow);
	return HGCancelEvent(evt);
};
/* called when someone clicks the checkbox or its containing cell */
HyperGrid.prototype.CheckHandler = function(evt)
{
	var grid = this.HGRow.HGGrid;
	var ctrl = HGCtrlPressed(evt);
	if (this.CheckBox == undefined)
	{
		// clicked on the checkbox
		if (this.checked)
			HGSelectRow(this.HGRow, true);
		else
			HGDeselectRow(this.HGRow);
	}
	else
	{
		// clicked on the containing cell
		this.CheckBox.checked = !this.CheckBox.checked;
		if (this.CheckBox.checked)
			HGSelectRow(this.HGRow, true);
		else
			HGDeselectRow(this.HGRow);
	}
	evt.cancelBubble = true;

	var oldPrim = grid.PrimaryRow;
	if (oldPrim != null)
	{
		grid.NoSingleSelect(grid);

		if (ctrl || oldPrim == this.HGRow) //they are adding to the current selection
			HGSelectRow(oldPrim, true); 	//or checking the currently selected row
		else
		{
			HGDeselectRow(oldPrim); 	//this means they are starting a new check selection
			grid.FirstClicked = this.HGRow;
			grid.CurrentRowNumber = this.HGRow.HGRowNumber;
		}
	}
	grid.Focus();
};



/* misc functions */
function HGCancelEvent(evt)
{
	evt.cancelBubble = true;
	if (evt.stopPropagation)
		evt.stopPropagation();
	if (evt.preventDefault)
		evt.preventDefault();
	if (evt.returnValue)
		evt.returnValue = false;
	return false;
}
function HGSelectRow(row, adjustCheck)
{
	row.IsClicked = true;
	if (row.CheckBox && adjustCheck)
		row.CheckBox.checked = true;
	row.HGGrid.HiddenLSR.value = row.HGRowNumber;
	if (row.HGGrid.Focuser && row.HGGrid.Scrollable)
		row.HGGrid.Focuser.style.top = (row.offsetTop + row.HGGrid.Scrollable.offsetTop - row.HGGrid.Scrollable.scrollTop) + "px";


	HGAddClass(row, "selected");
};
function HGDeselectRow(row)
{
	row.IsClicked = false;
	if (row.CheckBox)
		row.CheckBox.checked = false;
	HGRemClass(row, "selected");
};

function HGAddHandler(target, eventName, handlerName)
{
	if (target.addEventListener)
	{
		target[eventName + handlerName] = function(e) { return target[handlerName](e) };
		target.addEventListener(eventName, target[eventName + handlerName], false);
	}
	else if (target.attachEvent)
	{
		target[eventName + handlerName] = function(e) { return target[handlerName](e) };
		target.attachEvent("on" + eventName, target[eventName + handlerName]);
	}
	else
	{
		var originalHandler = target["on" + eventName];
		if (originalHandler)
		{
			target[eventName + handlerName] = function(e) { originalHandler(e); return target[handlerName](e); };
			target["on" + eventName] = target[eventName + handlerName];
		}
		else
		{
			target["on" + eventName] = target[handlerName];
		}
	}
}
function HGRemHandler(target, eventName, handlerName)
{
	if (target.detachEvent)
	{
		target.detachEvent("on" + eventName, target[eventName + handlerName]);
		target[eventName + handlerName] = null;
	}
	else if (target.removeEventListener)
	{
		target.removeEventListener(eventName, target[eventName + handlerName], false);
		target[eventName + handlerName] = null;
	}

}
function HGCtrlPressed(evt)
{
	return evt.ctrlKey;
}
function HGShiftPressed(evt)
{
	return evt.shiftKey;
}
function HGAddClass(node, c)
{
	var curclass = node.className;
	var i = curclass.indexOf(c);
	if (i == -1)
		node.className = curclass + ' ' + c;
}
function HGRemClass(node, c)
{
	var curclass = node.className;
	var i = curclass.indexOf(c);
	if (i == 0 || i == 1)
		node.className = curclass.substring(i + c.length, curclass.length);
	else if (i != -1)
		node.className = curclass.substring(0, i - 1) + " " + curclass.substring(i + c.length, curclass.length);

	if (c == "newrow")
	{
		var imgs = node.getElementsByTagName("img");
		for (i = 0; i < imgs.length; i++)
		{
			var img = imgs[i];
			img.src = img.src.replace(/UnreadMessage\.gif/i, "ReadMessage.gif");
			img.src = img.src.replace(/UnreadMessage_Low\.gif/i, "ReadMessage_Low.gif");
			img.src = img.src.replace(/UnreadMessage_High\.gif/i, "ReadMessage_High.gif");
			img.src = img.src.replace(/TicketUnread\.gif/i, "TicketRead.gif");
			img.src = img.src.replace(/UnreadChat\.gif/i, "ReadChat.gif");
		}
	}
}

function HGGetElementsByTagName(element, tagName, depth)
{
	var Arr = new Array();
	HGGetElementsByTagNameInner(Arr, element, tagName, depth);
	return Arr;
}
function HGGetElementsByTagNameInner(Arr, element, tagName, depth)
{
	for (var i = 0; i < element.childNodes.length; i++)
	{
		var elem = element.childNodes[i];
		if (elem.tagName == tagName)
			Arr[Arr.length] = elem;
		if (elem.childNodes.length > 0 && depth > 0)
			HGGetElementsByTagNameInner(Arr, elem, tagName, depth - 1);
	}
}

/* cleanup */
HyperGrid.prototype.DeinitializeGrid = function()
{
	if (document.HGOnBlur != undefined)
		document.HGOnBlur = null;

	if (this.Focuser)
	{
		HGRemHandler(this.Focuser, "keydown", "KeyPressHandler");
		this.Focuser.KeyPressHandler = null;
		this.Focuser = null;
	}
	this.DeSetupHeader(this.HGRows[0]);
	for (index = 1; index < this.HGRows.length; index++)
	{
		var row = this.HGRows[index];
		if (index == 1) this.FirstClicked = null;
		this.DeSetupHGRow(row);
		row.HGGrid = null;
		row.HGRowNumber = null;
	}

	this.GridTable = null;
	this.HiddenInput = null;
	this.HiddenLSR = null;
	this.Scrollable = null;
	var Div = document.getElementById(this.ID);
	Div.dispose = null;
	this.CurrentRowNumber = null;
	this.VirtualRowNumber = null;
	this.HGRows[0].HGGrid = this;
	this.HGRows = null;

	this.ID = null;
	this.Timer = null;
	this.EnableHover = null;
	this.DoubleClickCallback = null;
	this.PreviewPaneCallback = null;
	this.PreviewPaneUrlColumn = null;
	this.SingleClickUrlColumn = null;
	this.DoubleClickUrlColumn = null;
	this.RightClickCallback = null;
	this.DeleteKeyCallback = null;
	this.RowToSelect = null;
	this.Urls = null;
	StaticGrid = null;
}

/* Configures the header row */
HyperGrid.prototype.DeSetupHeader = function(row)
{
	row.HGCells = row.getElementsByTagName("TH");
	for (ci = 0; ci < row.HGCells.length; ci++)
	{
		var cell = row.HGCells[ci];
		if (cell.CheckBox != undefined)
		{
			HGRemHandler(cell, "click", "ClickHandler");
			HGRemHandler(cell.CheckBox, "click", "ClickHandler");
			cell.CheckBox.HGRow = null;
			cell.ClickHandler = null;
			cell.CheckBox.ClickHandler = null;
			cell.CheckBox = null;
		}
		else
		{
			HGRemHandler(cell, "click", "ClickHandler");
			cell.ClickHandler = null;
		}
		cell.HGRow = null;
		cell.HGGrid = null;
	}
	row.HGCells = null;
}
/* Configures each row of the grid */
HyperGrid.prototype.DeSetupHGRow = function(row)
{
	row.HGCells = row.getElementsByTagName("TD");
	for (ci = 0; ci < row.HGCells.length; ci++)
	{
		var cell = row.HGCells[ci];

		if (cell.CheckBox == undefined)
		{
			row.UniqueID = null;
			HGRemHandler(cell, "click", "ClickHandler");
			cell.ClickHandler = null;

			HGRemHandler(cell, "dblclick", "DblClickHandler");
			cell.DblClickHandler = null;

			if (!this.FastRender)
			{
				HGRemHandler(cell, "selectstart", "SelectHandler");
				cell.SelectHandler = null;

				HGRemHandler(cell, "mousedown", "BeginDrag");
				cell.RightClickHandler = null;

				HGRemHandler(cell, "contextmenu", "RightClickHandler");
				cell.BeginDrag = null;
			}
		}
		else
		{
			if (cell.CheckBox.checked)
			{
				row.HGGrid.FirstClicked = null;
				row.HGGrid.CurrentRowNumber = null;
			}
			HGRemHandler(cell, "click", "CheckHandler");
			HGRemHandler(cell.CheckBox, "click", "CheckHandler");
			cell.CheckHandler = null;
			cell.CheckBox.CheckHandler = null;
			cell.CheckBox.HGRow = null;
			cell.CheckBox = null;
			cell.HGRow.UniqueID = null;

		}
		cell.HGRow = null;
		cell.HGGrid = null;

	}
	if (this.EnableHover && !this.FastRender)
	{
		HGRemHandler(row, "mouseover", "HoverHandler");
		HGRemHandler(row, "mouseout", "UnHoverHandler");
		row.HoverHandler = null;
		row.UnHoverHandler = null;
	}
	row.HGCells = null;
};

function HGAddLoadEvent(callback)
{
	if (window.attachEvent)
		window.attachEvent("onload", callback);
	else if (window.addEventListener)
		window.addEventListener("load", callback, false);
}
if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();