/*

Actual code

edit
*/
function collapseTable( tableIndex ) {
  var Button = document.getElementById( 'collapseButton' + tableIndex );
  var Table = document.getElementById( 'collapsibleTable' + tableIndex );
  if ( !Table || !Button ) {
    return false;
  }

  var collapseColsOptin  = hasCollapsibleCol( tableIndex ); // new
  var collapseColsOptout = hasNoncollapsibleCol( tableIndex ); // new
  var Cols = Table.rows[0].cells; // new
  var CollapseCols = new Array(Cols.length); // new; has to be larger if there are colspans

  if ( collapseColsOptin || collapseColsOptout ) {// new
    //  @colspan currently not handled
    // the following two if-for-if constructs could be combined
    if ( collapseColsOptin ) {
      for ( var i = 0; i < Cols.length; i++ ) {
        if ( CollapseCols[i] == null || !hasClass( Cols[i], 'collapsible' ) ) {
          CollapseCols[i] = !collapseColsOptin;
        } else {
          CollapseCols[i] = collapseColsOptin;
        }
      }
    }
    // 'nocollapse' takes precedence over 'collapsible', i.e.
    // default columns are not collapsible when both types exist
    if ( collapseColsOptout ) {
      for ( var i = 0; i < Cols.length; i++ ) {
        if ( CollapseCols[i] == null || !hasClass( Cols[i], 'nocollapse' ) ) {
          CollapseCols[i] = collapseColsOptout;
        } else {
          CollapseCols[i] = !collapseColsOptout;
        }
      }
    }

    // column with first |th| should be excluded, because it holds the show/hide button
    var Header = Table.rows[0].getElementsByTagName( 'th' )[0];
    CollapseCols[Header.cellIndex] = false;// cellIndex doesn’t handle @colspan
  }

  var Rows = Table.rows;

  // insert check for @colspan here, change CollapseCols accordingly

  if ( Button.firstChild.data == collapseCaption ) {// hide

    if ( collapseColsOptin || collapseColsOptout ) {// new
      for ( var i = 0; i < Rows.length; i++ ) {
        var Cells = Rows[i].cells;
        for ( var j = 0; j < CollapseCols.length; j++) {
          // if we used Cells.length the handling of rows with empty cells at the end should improve
          // this would be a problem if the header row had empty cells at the end
          // we could also do CollapseCols.length-Cells.length times Rows[i].insertCell(-1) 
          if ( CollapseCols[j] ) {
            Cells[j].style.display = 'none';// needs to take @colspan into account
          }
        }
      }
    }

    var collapseRowsOptin = hasCollapsibleRow( tableIndex );// new
    // @rowspan currently not handled
    for ( var i = 1; i < Rows.length; i++ ) {
      if ( collapseRowsOptin ) {// new
        if ( hasClass( Rows[i], 'collapsible' ) ) {
          Rows[i].style.display = 'none';
        }
       } else if ( !collapseColsOptin && !collapseColsOptout ) {
        if ( !hasClass( Rows[i], 'nocollapse' ) &&
             !( hasClass( Rows[i], 'sortbottom' ) && !hasClass( Rows[i], 'collapsible' ) )
           ) { // new condition to exclude certain rows from collapsing
          Rows[i].style.display = 'none';
        }
      }
    }

    Button.firstChild.data = expandCaption;

  } else {// show

    for ( var i = 0; i < Rows.length; i++ ) {

      if ( collapseColsOptin || collapseColsOptout ) {// new
        var Cells = Rows[i].cells;
        for ( var j = 0; j < CollapseCols.length; j++) {
          if ( CollapseCols[j] ) {
            Cells[j].style.display = Rows[0].style.display;
          }
        }
      }

      Rows[i].style.display = Rows[0].style.display;
    }

    Button.firstChild.data = collapseCaption;

  }
}

/* new function to check whether the collapsible table has 
 * any column with the class 'collapsible'
 */
function hasCollapsibleCol( tableIndex ) {
  var Table = document.getElementById( 'collapsibleTable' + tableIndex );
  if ( !Table ) {
    return false;
  }
  var Cols = Table.rows[0].cells;

  for ( var i = 0; i < Cols.length; i++ ) {
    if ( hasClass( Cols[i], 'collapsible' ) ) {
      return true;
    }
  }
  return false;
}

/* new function to check whether the collapsible table has 
 * any column with the class 'nocollapse'
 */
function hasNoncollapsibleCol( tableIndex ) {
  var Table = document.getElementById( 'collapsibleTable' + tableIndex );
  if ( !Table ) {
    return false;
  }
  var Cols = Table.rows[0].cells;

  for ( var i = 0; i < Cols.length; i++ ) {
    if ( hasClass( Cols[i], 'nocollapse' ) ) {
      return true;
    }
  }
  return false;
}

/* new function to check whether the collapsible table has 
 * any row (except the header) with the class 'collapsible'
 */
function hasCollapsibleRow( tableIndex ) {
  var Table = document.getElementById( 'collapsibleTable' + tableIndex );
  if ( !Table ) {
    return false;
  }
  var Rows = Table.rows;

  for ( var i = 1; i < Rows.length; i++ ) {
    if ( hasClass( Rows[i], 'collapsible' ) ) {
      return true;
    }
  }
  return false;
}
//