ScrollableTable = function(tableElement)  
{
  //optional second parameter for scroll element
  //optional third parameter to compensate for column drift
this.sourceTable = tableElement;
this.columnOffset = 0;
if (arguments.length > 1){
  if (arguments[1]!=null)
    this.scrollElement = arguments[1];
  if (arguments.length>2)
    this.columnOffset = arguments[2]
}
else
  this.scrollElement =  tableElement.parentNode;
//bail out if the table is already scrollable.
if (this.scrollElement.scrollHandler!=null) return null;


this.initialize = function()
{
  this.scrollElement.scrollHandler = this;
  this.overlayTable = this.sourceTable.cloneNode(false);  //preserves all base table attributes
  this.overlayTable.setAttribute('id','');  //don't want to confuse any scripts that may reference the table id
  this.overlayTable.style.position = 'absolute';
  this.overlayTable.style.top = 0;
  this.overlayTable.style.height = this.sourceTable.getElementsByTagName('TH')[0].height;
  this.overlayTable.style["z-index"] = parseInt(this.sourceTable.getAttribute('z-index'))+1;
  
  //build the new header row
  var newTbody = document.createElement('TBODY');
  var newTR = this.sourceTable.getElementsByTagName('TR')[0].cloneNode(true);
  newTbody.appendChild(newTR);
  this.overlayTable.appendChild(newTbody);
  //this.overlayTable.setAttribute('id','table2');

  this.scrollElement.appendChild(this.overlayTable);

  var sourceHeaderCells = this.sourceTable.getElementsByTagName('TH');
  var overlayHeaderCells = this.overlayTable.getElementsByTagName('TH');
  
  for (var i=0;i<sourceHeaderCells.length;i++)
  {
    //add a div to the header cell; forces width
    var newElement = document.createElement('DIV');
    newElement.style.width = parseInt(sourceHeaderCells[i].clientWidth)+this.columnOffset;
    newElement.style.height = 1;
    newElement.style.overflow = 'hidden';  //don't let browser expand div height 
    newElement.style.display = 'block';
    newElement.style.background = 'transparent';
    overlayHeaderCells[i].appendChild(newElement);
  }
  
  //attach scroll event to container element.
  if(this.scrollElement.addEventListener) 
    this.scrollElement.addEventListener('scroll',this.processScroll,true);
  else 
  if(this.scrollElement.attachEvent)
    this.scrollElement.attachEvent('onscroll',this.processScroll);
}

this.processScroll = function(evt)
{
  //this function will be in the wrong scope when executed, redirect the request.
  var evtTarget = null;
  
  if(evt.target) 
    evtTarget = evt.target;
  else 
    if(evt.srcElement) 
      evtTarget = evt.srcElement;
  
  if (evtTarget)
  {
    var scrollObject = evtTarget.scrollHandler;
    evtTarget.scrollHandler.scrollTo(evtTarget.scrollLeft, evtTarget.scrollTop);
  }
}

this.scrollTo = function(newLeft,newTop)
{
  //update header position to match scroll
  // TODO: add fixed left column
  this.overlayTable.style.top = newTop;
}

this.cleanup = function()
{
  if (this.scrollElement!=null){
    try{
      this.scrollElement.removeChild(this.overlayTable);
    }
    catch(e)
    {}
    finally
    {
      if(this.scrollElement.removeEventListener) 
        this.scrollElement.removeEventListener('scroll',this.processScroll,true);
      else 
      if(this.scrollElement.detachEvent)
        this.scrollElement.detachEvent('onscroll',this.processScroll);
      this.scrollElement.scrollHandler = null;
    }
  }
}

this.initialize();
}

