//Inverts a table so that columns becomes rows, and rows columns.

// Version 1.3: Added table class support with jQuery
// Version 1.2: Fixed restoring when randomizing
// Version 1.1: Supports randomizing of columns and rows
// Version 1.0: Basic functionality

//Runs initializeVerticalMatrix automatically, check last line.
var VerticalMatrix = {
  top: 'tableFormat1',
  inputClassName : "verticalMatrix", //Editable
  tableClassName : "verticalClassification",
  randomClassName : "randomized",
  dontRandomizeLast : 0, //Can be set by fake args randomized_1
  seed : 654, //4124
  //Additional fake arg randomized_1_rows which randomizes the original rows instead of columns

  newMatrices : new Array(),

  debug : false,
  debugPreString : "c_verticalmatrix.js: ",
  debugPostString : "-error: ",

  initializeVerticalMatrix : function() {
    try {
	  var tablesToBeConverted;
	  if(jQuery) {
			tablesToBeConverted = $('.'+VerticalMatrix.top+' table:has(input.'+VerticalMatrix.inputClassName+')')
				.add('.'+VerticalMatrix.tableClassName+' table')
				.toArray();
		}
	  else {
		var inputs = Utilities.getElementsByClassAndTagName(VerticalMatrix.inputClassName, "INPUT");
		tablesToBeConverted = Utilities.getUniqueContainerWithItems(inputs, "TABLE", "TR");
		}
      if(typeof(randomSeed) != "undefined" && !isNaN(randomSeed)) VerticalMatrix.seed = randomSeed;
      for(var i=0; i<tablesToBeConverted.length; i++) {
          var oldTable;
		  if(jQuery) oldTable = tablesToBeConverted[i];
		  else oldTable = Utilities.getKin(tablesToBeConverted[i][0], "parent", "TABLE");
          var random = null;
          var dontRandomizeLast = VerticalMatrix.dontRandomizeLast;
		  var dtTop = null;
		  if(jQuery) dtTop = $(oldTable).parents("."+VerticalMatrix.top).get(0);
          if(dtTop && Utilities.hasClassName(dtTop, VerticalMatrix.randomClassName) || Utilities.hasClassName(oldTable, VerticalMatrix.randomClassName)) {
        	  var fakeArgs = dtTop ? Utilities.getFakeClassArguments(dtTop, VerticalMatrix.randomClassName) : Utilities.getFakeClassArguments(oldTable, VerticalMatrix.randomClassName);
            if(fakeArgs.length >= 2 && !isNaN(fakeArgs[1])) {
        			dontRandomizeLast = Number(fakeArgs[1]);
            }
            if(fakeArgs.length >= 3 && fakeArgs[2] == "rows") random = "rows";
            else random = "columns";          
          }
          var newTable = VerticalMatrix.convertRowsToColumns(oldTable, random, dontRandomizeLast);
          newTable.className = oldTable.className + " verticalMatrix";
          VerticalMatrix.newMatrices.push(newTable);
          oldTable.parentNode.insertBefore(newTable, oldTable);
          oldTable.parentNode.removeChild(oldTable);
      }
    } catch(err) {if(VerticalMatrix.debug) alert(VerticalMatrix.debugPreString + "initializeVerticalMatrix" + VerticalMatrix.debugPostString + err);}
  },
  
  convertRowsToColumns : function(table, random, dontRandomizeLast) {
      var newTable = document.createElement("TABLE");
      if(dontRandomizeLast == undefined) dontRandomizeLast = 0;
      try {
      var tbody = document.createElement("TBODY");
      var createRow = true;
      var rowIterator = 0;
      newTable.appendChild(tbody);
        while(table.rows.length) {
          var rowIndex = 0;
          if(random == "rows" && !createRow) rowIndex = VerticalMatrix.getRandomIndexBetween(0, table.rows.length-1-dontRandomizeLast, table.rows.length*VerticalMatrix.seed);
          if(random == "restorecolumns") {
            for(var x=0; x<table.rows.length; x++) {
              if(table.rows[x].orgCellIndex == rowIterator) {
                rowIndex = x;
                break;
              }
            }
          }
          var oldRow = table.rows[rowIndex];
          var numberOfCells = oldRow.cells.length;
          if(createRow) {
            for(var i=0; i<oldRow.cells.length; i++) {
              oldRow.cells[i].orgCellIndex = i;
            }
          }
          while(oldRow.cells.length) {
            var cellIndex = 0;
            var newCellIndex = numberOfCells - oldRow.cells.length;
            if(random == "columns" && newCellIndex) cellIndex = VerticalMatrix.getRandomIndexBetween(0, oldRow.cells.length-1-dontRandomizeLast, oldRow.cells.length*VerticalMatrix.seed);
            var oldCell = oldRow.cells[cellIndex];
            if(createRow) {
              var newRow = document.createElement("TR");
              newRow.orgCellIndex = oldCell.orgCellIndex;
              var newCell = document.createElement("TD");
              Utilities.moveChildren(oldCell, newCell);
              newCell.className = oldCell.className;
              newRow.appendChild(newCell);
              tbody.appendChild(newRow);
            }
            else {
              var newCell = document.createElement("TD");
              newTable.rows[newCellIndex].appendChild(newCell);
              Utilities.moveChildren(oldCell, newCell);
              newCell.className = oldCell.className;  
            }
            oldRow.deleteCell(cellIndex);
          }
          createRow = false;
          table.deleteRow(rowIndex);
          rowIterator++;
        }
    } catch(err) {if(VerticalMatrix.debug) alert(VerticalMatrix.debugPreString + "rowsToColumns" + VerticalMatrix.debugPostString + err);}
    return newTable;
  },
  
  getRandomIndexBetween : function (lower, upper, seed) {
    if(lower < 0) lower = 0;
    if(upper < 0) upper = 0;

    if(seed == undefined) seed = 12345;
    var maxi = Math.pow(2,32);
    seed = (134775813 * (seed + 1))
       % maxi;
    var num = (seed) / maxi;
    if(typeof lower!='undefined')
    {
     var range = upper - lower;
     num *= range;
     num += lower;
    }
    //alert (lower+", "+upper+", "+seed+", "+Math.round(num));
    return Math.round(num); 
  }
};
VerticalMatrix.initializeVerticalMatrix();
