/*
This script should be put at the end of your HTML document (just before </BODY>).

It provides utilities for table management.
*/

/* Move the current row down one row.  Use with the CSS button class "movedown." */
function MoveDown(el) {
  var curr_row = FindUp(el, "TR");
  if (curr_row == null) {
	return;
  }
  var tbody = FindUp(curr_row, "TBODY");
  var curr_index = curr_row.sectionRowIndex;
  if (curr_index == tbody.rows.length - 2) {
    //second last row does not seem to move down properly if there is another tbody below
    //so, just move the next row up instead
    MoveUp(tbody.rows(tbody.rows.length -1).firstChild)
  }
  else if (curr_index < tbody.rows.length - 1) {
    tbody.moveRow(curr_index, curr_index + 1);
    if (typeof SetDirty == "function") { 
      SetDirty(true);
    }  
    if (typeof ProcessRowDirty == "function") {
      ProcessRowDirty(curr_row);  // mark this row dirty
      ProcessRowDirty(tbody.rows[curr_index]);  // row that this one swapped with
    }
  }
}


/* Move the current row up one row.  Use with the CSS button class "moveup." */
function MoveUp(el) {
  var curr_row = FindUp(el, "TR");
  if (curr_row == null) {
	return;
  }
  var tbody = FindUp(curr_row, "TBODY");
  var curr_index = curr_row.sectionRowIndex;
  if (curr_index > 0) {
    tbody.moveRow(curr_index, curr_index - 1);
    if (typeof SetDirty == "function") {
      SetDirty(true);
    }
    if (typeof ProcessRowDirty == "function") {
      ProcessRowDirty(curr_row); // mark this row dirty
      ProcessRowDirty(tbody.rows[curr_index]);  // row that this one swapped with
    }
  }
}

/* find the next parent with the given tag name */
function FindUp(baseElement, tagName) {
  var el = baseElement;
  while (el != null && el.tagName != tagName)
    el = el.parentElement;
  return el;
}

/* return the first table body element for the given table */
function GetTableBody(table) {
  return table.all.tags("TBODY")[0];
}

/* copy the event handlers from element 1 to 2 including sub-elements */
function CopyHandlers(el1, el2) {
  var i;
  for (i in el1) {
    if (i.substr(0,2) == "on")
      el2[i] = el1[i];
  }
  var children1 = el1.children
  var children2 = el2.children
  var childLen = children1.length
  for (i = 0; i < childLen; i++)
    CopyHandlers(children1[i], children2[i]);
}

/* Adds a row to the given table body element using the last row as a template.
   Args: 1) tbody to add the row to,
         2) tbody to copy the row from. 
   NOTE:  This is an older version that uses cloneNode rather than the much faster CopyTableRow.
          You should use AppendTBodyRows instead of this function if possible (it usually is)
 */
function AddTableRow(tBodyFrom, tBodyTo) {
  var lastRow = tBodyFrom.rows(tBodyFrom.rows.length-1);
  var newRow = lastRow.cloneNode(true);
  // cloneNode does not capture the selected options
  var len = lastRow.all.tags("select").length;
  for (var i=0; i<len; i++) {
    newRow.all.tags("select")(i).selectedIndex = lastRow.all.tags("select")(i).selectedIndex
  }
  newRow.style.display = "";
  CopyHandlers(lastRow, newRow)
  tBodyTo.appendChild(newRow);
  return newRow;
}

/* Adds all rows from the table body, tBodyFrom, into the given table body, tBodyTo.
   Returns the last row added
   Args: 1) tbody to add the rows to,
         2) tbody to copy the rows from.
   NOTES: - Attributes of the rows and cells are not copied because that is too slow.
          - Attributes of the cell contents are copied
          - Event handlers (rows, cells, and cell contents) are not copied because that is too slow
 */
function AppendTBodyRows(tBodyFrom, tBodyTo) {
  var i = 0;
  var fromRows = tBodyFrom.rows
  var rowLen = fromRows.length
  for(i=0; i< rowLen; i++) {
    var lastRow = fromRows[i];
    var newRow = tBodyTo.insertRow()
    CopyTableRow(lastRow,newRow)
  }  
  return newRow;
}

/* Copies row from source to destination (destination assumed empty */
function CopyTableRow(trSource, trDest) {
  var i = 0;
  var cells = trSource.cells
  var cellLen = cells.length
  for (i=0; i < cellLen; i++) {
    var sourceCell = cells[i]
    var destCell = trDest.insertCell()
    CopyContents(sourceCell,destCell, false)
    destCell.colSpan = sourceCell.colSpan
    destCell.rowSpan = sourceCell.rowSpan
    destCell.className = sourceCell.className
    destCell.noWrap = sourceCell.noWrap
    destCell.align = sourceCell.align
    destCell.vAlign = sourceCell.vAlign
  }
  // event handlers are not copied because it is very slow
}

/* Copies the contents from source element to destination Element
   Note:  This works on regular DOM elements, but not special ones like tables */
function CopyContents(elSource, elDest, copyHandlers) {
  var i = 0
  var children = elSource.childNodes
  var len = children.length
  for (i=0;i<len;i++) {
    var child = children[i]
    var newChild = child.cloneNode(true)
    elDest.appendChild(newChild)
    if (copyHandlers && child.nodeName != "#text")
      CopyHandlers(child, newChild)
  }
}


/* Deletes a row from a table and passes back the key value to DeleteRow() in the page's script. */
function DeleteTableRow(el, idstr) {
  var row = FindUp(el, "TR");
  var tbody = FindUp(row,"TBODY");
  var id = row.all(idstr).value;
  tbody.deleteRow(row.sectionRowIndex);
  return id;
}

/* removes all rows from the given table body (or header or footer if you want) */
function TruncateTBody(tbody) {
  for (var toDelete = tbody.rows.length - 1; toDelete > -1;--toDelete) {
    tbody.deleteRow(toDelete)
  }
}

