// Class SortTypes
function SortTypes()
	{
	this.CHARACTER_CASE_INSENSITIVE = 0;
	this.CHARACTER_CASE_SENSITIVE   = 1;
	this.NUMBER                     = 2;
	this.DATE                       = 3;
	}
var g_SortTypes = new SortTypes;

// Class DataTable

function DataTable()
	{
	this.nSortColumn    = 0;
	this.bSortAscending = true;
	this.arColumnNames  = null;
	this.arData         = null;

	this.arColumnIsLUTVal  = null;
	}

DataTable.prototype.clone = function( fNoData )
	{
	if ( !fNoData )
		alert( 'DataTable clone with data not implemented' )

	var oNew = new DataTable();
	oNew.nSortColumn    = this.nSortColumn;
	oNew.bSortAscending = this.bSortAscending;
	oNew.arColumnNames  = this.arColumnNames;

	oNew.arData           = null;
	oNew.arColumnIsLUTVal = null;

	return oNew;
	}
/*
// Couldn't get this to work properly, with regards to setting
// the sort column for the function.  See sortData function below
// for the workaround, but there's got to be a better way to do this.
function compareStringData(a, b)
	{
alert( 'this.nSortColumn = ' + this.nSortColumn );
	var sAUpper = a[this.nSortColumn].toUpperCase();
	var sBUpper = b[this.nSortColumn].toUpperCase();

	if ( sAUpper < sBUpper )
		return -1;
	else if ( sAUpper > sBUpper )
		return 1;
	else return 0;
	}
*/

DataTable.prototype.getColumnID = function( sColumnName, fLUTValues )
	{
	var nNumColumns = this.arColumnNames.length;
	for (var i = 0; i < nNumColumns; i++)
		{
		if ( this.arColumnNames[i] == sColumnName )
			{
			if ( ( fLUTValues == null ) || (this.arColumnIsLUTVal==null) || (this.arColumnIsLUTVal[i] == null) )
				return i;
			else if ( this.arColumnIsLUTVal[i] == fLUTValues )
				return i;
			}
		}

	return -1;
	}

DataTable.prototype.sortData = function( sColumnName, eSortType, bAscending )
	{
//	alert( 'Sorting on ' + sColumnName );

	var nSortCol = this.getColumnID( sColumnName );
	if ( nSortCol < 0 )
		{
		alert('Unknown column for sort: ' + sColumnName);
		return;
		}

	// If bAscending not set, default to true
	if ( bAscending == null ) bAscending = true;

	// Only sort if this is not the current sort column and ordering.
	if ( ( nSortCol != this.nSortColumn ) || ( bAscending != this.bSortAscending ) )
		{
		// Do the sort
		this.nSortColumn    = nSortCol;
		this.bSortAscending = bAscending;

		// Set up some strings for building the comparison function
		var sFieldString = '';

		if ( ( eSortType == null ) ||
			 ( eSortType == g_SortTypes.CHARACTER_CASE_INSENSITIVE ) )
			{
			sFieldString = '[' + this.nSortColumn + '].toUpperCase()';
			}
		else
			sFieldString = '[' + this.nSortColumn + ']';

		// Create a new comparison function object

		// TODO: this seems like a goof way to do this.
		var compareFunc =
		 Function('a, b', 
			'var sAUpper = a' + sFieldString + ';'+
			'var sBUpper = b' + sFieldString + ';'+
			''+
			'if ( sAUpper < sBUpper )'+
			'	return ' + (bAscending ? '-1' : '1') + ';' +
			'else if ( sAUpper > sBUpper )'+
			'	return ' + (bAscending ? '1' : '-1') + ';' +
			'else return 0;'
		);

		this.arData.sort( compareFunc );
		}
	}

DataTable.prototype.getNumColumns = function()
	{
	var nNumCols = 0;
	if ( this.arColumnNames != null )
		nNumCols = this.arColumnNames.length;

	return nNumCols;
	}

DataTable.prototype.getNumRows = function()
	{
	var nNumRows = 0;
	if ( this.arData != null )
		nNumRows = this.arData.length;

	return nNumRows;
	}

DataTable.prototype.getNumVisibleRows = function()
	{
	var nNumRows = this.getNumRows()
	var nNumVisibleRows = 0
	for (var i=0; i < nNumRows; i++)
		{
		if ( this.arData[i].bShow != false )
			nNumVisibleRows++
		}

	return nNumVisibleRows;
	}

DataTable.prototype.isVisible = function( nRow )
	{
	if ( (nRow >= 0) || (nRow < this.getNumRows()) )
		return (this.arData[nRow].bShow != false)
	}

DataTable.prototype.setVisible = function( nRow, fVisible )
	{
	if ( (nRow >= 0) || (nRow < this.getNumRows()) )
		this.arData[nRow].bShow = fVisible
	}

DataTable.prototype.setAllVisible = function( fVisible )
	{
	var nNumRows = this.getNumRows()
	for (var i=0; i < nNumRows; i++)
		{
		this.arData[i].bShow = fVisible
		}
	}

DataTable.prototype.getValue = function(nRow,nCol)
	{
	if ( (nRow < 0) || (nRow >= this.getNumRows()) ||
	     (nCol < 0) || (nCol >= this.getNumColumns())
	   )
		{
	   return null;
		}

	return this.arData[nRow][nCol];
	}

DataTable.prototype.setValue = function(nRow,nCol,val)
	{
	if ( (nRow < 0) || (nRow >= this.getNumRows()) ||
	     (nCol < 0) || (nCol >= this.getNumColumns())
	   )
		{
		return
		}

	this.arData[nRow][nCol] = val
	}

DataTable.prototype.getRow = function( nRow )
	{
	if ( (nRow < 0) || (nRow >= this.getNumRows()) )
		{
		return null;
		}

	return this.arData[nRow]
	}

// Checks the specified date fields for String objects instead of Date objects.
// Assumes that the specified dates strings are in YYYYMMDD format and converts
// them to Date objects.
function FixDateFields( dt, arDateFields )
	{
	var nNumRows = (dt==null) ? 0 : dt.getNumRows()
	if ( nNumRows == 0 )
		return

	var numDateFields = (arDateFields==null) ? 0 : arDateFields.length
	for ( var i=0; i < numDateFields; i++ )
		{
		var nDateCol = dt.getColumnID( arDateFields[i] );
		if ( nDateCol >= 0 )
			{
			for ( var j=0; j < nNumRows; j++ )
				{
				var val = dt.getValue(j, nDateCol)
				if ( typeof val == "string" )
					{
					var dateVal = null

					// Assume its XBASE format: YYYYMMDD
					if ( !isEmptyString( val ) )
						dateVal = new Date( val.substr(0,4), val.substr(4,2)-1, val.substr(6,2) )

					dt.setValue(j, nDateCol, dateVal)
					}
				}
			}
		}
	}

// Converts a clDataView object to a DataTable object
function DataViewToDataTable( oView )
	{
	if ( oView == null )
		return null

	var dt = new DataTable()

	// Dimensions
	var nRows = oView.numRecords()
	var nColumns = oView.numCols()

	// Sort column
	dt.nSortColumn    = -1
	dt.bSortAscending = false

	// Array of heading strings
	dt.arColumnNames = new Array()

	// Data array
	dt.arData = new Array()
	for (var i=0; i < nRows; i++)
		dt.arData[i] = new Array()

	// Fill in the column headings
	for ( var i=0; i < nColumns; i++ )
		{
		dt.arColumnNames[i] = oView.aCols[i].sFieldName
		}

	// Copy the data
	for ( var i=0; i < nRows; i++ )
		{
		for ( var j=0; j < nColumns; j++ )
			{
			dt.arData[i][j] = oView.getRecord(i).getValue(oView.aCols[j].sFieldName)
			}
		}

	return dt
	}

