/* List of supported table cell attributes */
var attr2HTML = new Array();
attr2HTML[ 'className' ] = 'class';

/*
	tableContents is a global array for which the structure is as follows:
		- row 0: contains array elements which are as follows:
			- cell 0: an HTML template of what the cell looks like
			- cell 1: a Javascript function name to display the cell (it takes one argument which is the HTML template)
			- cell 2: a Javascript function name to read the value of the cell
			- cell 3: a Javascript function name to set the value of the cell 
		- row >0: contains array elements which are as follows:
			- cell 0: the index of the model in row 0
			- cell 1: the value of the cell
			- cell 2: an array of cells attributes
			- cell 3: the row ID (if any)
*/

var tableContents = new Array();

function insertRow( tableName, row, index, rowModelIndex )
{
  storeTable( tableName );

  insertRowContents( tableName, row, index, rowModelIndex );

//   var pTab = getLayer( tableName + '_table' );
//   var pRow = pTab.insertRow( index );
//   pRow.innerHTML = getRowHTML( tableName, i );
  showTable( tableName );
}

function emptyTableContents(tableName, nHeaderLines)
{
  var aContent = tableContents[ tableName ];
  nHeaderLines = nHeaderLines == null ? 0 : nHeaderLines;

  for( var i = (aContent.length) ; i > nHeaderLines ; i-- )
  {
    delete aContent[ i ];
  }

  aContent.length = nHeaderLines + 1; // the first line is model
}

function removeRowContents( tableName, index )
{
  index++; // because the first row of the table contains the cell models

  for( var i=index ; i < ( tableContents[ tableName ].length - 1 ); i++ )
  {
    tableContents[ tableName ][ i ] = tableContents[ tableName ][ i + 1 ];
  }

  delete tableContents[ tableName ][ tableContents[ tableName ].length - 1 ];
  tableContents[ tableName ].length = tableContents[ tableName ].length - 1;
  
}

function insertRowContents(tableName, row, index, rowModelIndex, sRowID )
{
  if(sRowID == undefined)
	sRowID = null;
  if( tableContents[ tableName ] == null )
  {
    tableContents[ tableName ] = new Array();
  }
  var aContent = tableContents[ tableName ];
	
  if( index == "" || index == null )
    index = aContent.length;
  else
    index ++; // table row 0 is model

  for( var i = (aContent.length) ; i>index ; i-- )
  {
    tableContents[ tableName ][ i ] = tableContents[ tableName ][ i - 1 ];
  }

  if( rowModelIndex == null )
  {
    tableContents[ tableName ][ index ] = row;
  }
  else
  {
    tableContents[ tableName ][ index ] = new Array();
    tableContents[ tableName ][ index ][ 'sRowID' ] = sRowID;
    var rowModel = eval( 'rowModels_' + tableName + '[' + rowModelIndex + ']' );
    for( var i = 0 ; i < rowModel.length ; i++ )
    {
      tableContents[ tableName ][ index ][ i ] = new Array( rowModel[ i ][ 0 ], row[ i ], rowModel[ i ][ 1 ] );
    }
  }
}

function deleteRow( tableName, index )
{
  storeTable( tableName );

  removeRowContents(tableName, index );
  
  showTable( tableName );
}

function getRows( tableName )
{
  return tableContents[ tableName ];
}

function getRow( tableName, i )
{
  return tableContents[ tableName ][ i + 1 ];
}

function getRowContents( tableName, nRowNumber)
{
	var aTableRow = tableContents[ tableName ][ nRowNumber + 1 ];
	var aRow = new Array();
	for(var j=0;j<aTableRow.length;j++)
		aRow[aRow.length] = aTableRow[j][1];
	return aRow; 
}

function updateRowContents( tableName, nRowNumber, aRow)
{
	var aTableRow = tableContents[ tableName ][ nRowNumber + 1 ];
	for(var j=0;j<aTableRow.length && j<aRow.length;j++)
		aTableRow[j][1] = aRow[j];
	return aRow; 
}

function getRowNumberFromID(tableName, sRowID)
{
  if(tableContents[tableName])
  {
    for(var i=1;i<tableContents[tableName].length;i++)
    {
      if(tableContents[tableName][i]['sRowID'] == sRowID)
        return i-1;
    }
  }
  return -1;
}

function getRowIDFromNumber(tableName, nRowNumber)
{
  if(tableContents[tableName][nRowNumber+1])
  {
    return tableContents[tableName][nRowNumber+1]['sRowID'];
  }
  return null;
}

function getLastRow( tableName )
{
	return tableContents[ tableName ][tableContents[ tableName ].length -1];
}

function getFirstRow( tableName )
{
	return tableContents[ tableName ][1];
}

function getNbRows( tableName )
{
	return tableContents[ tableName ].length - 1;
}

function getCellInputName(tableName, nRowNumber, nColNumber)
{
	return tableName + '_cell_' + nRowNumber + '_' + nColNumber;
}

function getCellInputNameFromID(tableName, nCol, sRowID)
{
  var nRowNumber = getRowNumberFromID(tableName, sRowID);
  if(nRowNumber >= 0)
	 return getCellInputName(tableName, nRowNumber, nCol);
  else
	 return null;
}

function storeTable( tableName, nRowNumber )
{
  var formName = eval( tableName + '_formName' );

  // start from row 1 (as row 0 contains the table cell models)
  //alert( tableContents[ tableName ] );
  var iMax = nRowNumber != undefined ? nRowNumber+2 : tableContents[ tableName ].length;
  var iMin = nRowNumber != undefined ? nRowNumber+1 : 1;
  for( var i=iMin ; i<iMax ; i++ )
  {
    //alert( tableContents[ tableName ][ i ] );
    for( var j=0 ; j<tableContents[ tableName ][ i ].length ; j++ )
    {
      // call the get input value function on the name of the cell
      //alert( tableContents[tableName][0][tableContents[tableName][i][j][0]] );
      if( tableContents[tableName][0][tableContents[tableName][i][j][0]][2] != '' )
      {
        //alert( tableContents[tableName][0][tableContents[tableName][i][j][0]][2] );
        var cellName = tableName + '_cell_' + (i-1) + '_' + j;
        //if( getFormObject( cellName, formName ) != null )
        {
          var pValue = evalFunc( tableContents[tableName][0][tableContents[tableName][i][j][0]][2], // JS getter function (setInputValue())
                                 cellName, // cell name
                                 formName, // form name
                                 undefined, // document
                                 undefined, // enforce IE to get value though document.all.*
                                 getTableOldValue( tableName, i - 1, j ) ); // old value

          if(pValue !== undefined)
            tableContents[tableName][i][j][1] =  pValue;
        }
      }
    }
  }
}

function getTableOldValue( tableName, i, j )
{
  return tableContents[tableName][i + 1][j][1];
}

function emptyTable( tableName )
{
  var pTab = getLayer( tableName );

  pTab.innerHTML = '';

//   var t = '';
//   for( var i in pTab )
//     {
//       t += i + "=" + pTab.i + " ";
//     }
//   alert( t );
//   pTab.tBodies[0].innerHTML = '';
 //  pTab.tBody.innerHTML = '';

//   if( pTab.rows != null )
//   {
//     var len = pTab.rows.length;
//     for( var i = (len -1 ); i>= 0 ; i-- )
//     {
//       pTab.deleteRow( i );
//     }
//   }

  var formName = eval( tableName + '_formName' );
  setInputValue( tableName + '_width', 0, formName );
  setInputValue( tableName + '_height', 0, formName );
}

function getTableHTMLContent( tableName )
{
  var pTab = getLayer( tableName );

  return pTab.innerHTML;
}

function updateTable( tableName, nRowNumber )
{
  var iMin = (nRowNumber != undefined) ? nRowNumber+1 : 1;
  var iMax = (nRowNumber != undefined) ? nRowNumber+2 : tableContents[tableName].length;
  var formName = eval( tableName + '_formName' );
  for(var i=iMin;i<iMax;i++)
  {
    // for each cells
    for(var j=0;j<tableContents[tableName][i].length;j++)
    {
      // if set input value function defined
      if( tableContents[tableName][0][tableContents[tableName][i][j][0]][3] != '' )
      {
        // call the set input value function to set the value of the cell
        //        alert( tableContents[tableName][0][tableContents[tableName][i][j][0]][3] + ' ' + cellName + ' ' + tableContents[tableName][i][j][1] + ' ' + formName );
        var cellName = getCellInputName(tableName,i-1,j);
        evalFunc( tableContents[tableName][0][tableContents[tableName][i][j][0]][3],
                  cellName,
                  tableContents[tableName][i][j][1],
                  formName );
      }
    }
  }
}

function showTable( tableName, debug )
{
  //  alert( 'showTable(' + tableName +')');
  //emptyTable( tableName );

  var pTab = getLayer( tableName );

  hideTable(tableName);

  var formName = eval( tableName + '_formName' );

  //  alert( '1' );

  var width = 0;
  var tab = new Array();

  var t = getCurrentDate().getTime();
  var t2 = 0;
  var t3 = 0;

  var aTmp = new Array();

  aTmp.push( " <table id=\"" + tableName + "_table\" " + getInputValue( tableName + '_attrs', formName ) + ">" );

  var imax = tableContents[ tableName ].length;
  for( var i=1 ; i<imax ; i++ )
  {
    aTmp.push( "<tr>" );

    aTmp.push( getRowHTML( tableName, i ) );

    if( width < tableContents[ tableName ][ i ].length )
    {
      width = tableContents[ tableName ][ i ].length;
    }

    aTmp.push( "</tr>" );
  }

  aTmp.push( "</table>" );

  var sHTML = aTmp.join( '' );

  if( debug )
    {
      //      alert( (new Date().getTime() - t) + ' t2=' + t2 + ' t3=' + t3 );
    }
  t = getCurrentDate().getTime();
  //pTab.innerHTML = sHTML;
  setInnerHTML(pTab, sHTML);
  if( debug )
    {
      //alert( new Date().getTime() - t );
    }

  t = getCurrentDate().getTime();
//  if( debug != 3 )
//    updateTable( tableName );

  if( debug )
    {
      //alert( new Date().getTime() - t );
    }

  if( tableContents[ tableName ].length > 1 )
  {
    setInputValue( tableName + '_width', width, formName );
    setInputValue( tableName + '_height', tableContents[ tableName ].length - 1, formName );
  }
  else
  {
    setInputValue( tableName + '_width', 0, formName );
    setInputValue( tableName + '_height', 0, formName );
  }
  displayTable(tableName);
}

function setInnerHTML(pTab, sHTML)
{
  pTab.innerHTML = sHTML;
}

function getTableContent( tableName )
{
  return tableContents[ tableName ];
}

function setTableContent( tableName, tableContent )
{
  emptyTable( tableName );
  tableContents[ tableName ] = tableContent;
  showTable( tableName );
}

function displayTable( tableName )
{
  showLayer( tableName + '_table' );
}

function hideTable( tableName )
{
  hideLayer( tableName + '_table' );
}

function getRowHTML( tableName, i )
{
  var aTmp = new Array();
  var jmax = tableContents[ tableName ][ i ].length;
  var formName = eval( tableName + '_formName' );
  for( var j=0 ; j<jmax ; j++ )
  {
    var cellName = getCellInputName(tableName,i-1,j);
      
    aTmp.push( "<td " );
    aTmp.push( tableContents[tableName][i][j][2] );
    aTmp.push( " >" );
    g_sHTMLTemplate = evalFunc( tableContents[tableName][0][tableContents[tableName][i][j][0]][1], // model gen html function
                         tableContents[tableName][0][tableContents[tableName][i][j][0]][0], // model template
                         cellName,
                         i-1,
                         j,
                         tableContents[tableName][i]['sRowID'],
                         tableContents[tableName][i][j][1] );

    evalFunc( tableContents[tableName][0][tableContents[tableName][i][j][0]][3],
              cellName,
              tableContents[tableName][i][j][1],
              formName );
                  
    aTmp.push( g_sHTMLTemplate );
    g_sHTMLTemplate = null;
    aTmp.push( "</td>" );
  }

  return aTmp.join('');
}
