/**
 * Global variable pointing to a 2D array representing the contents of the 
 * table
 */
var tblContents;

/**
 * Global variable pointing to a 1D array representing the headers of the table
 */
var tblHeader;

/**
 * Main entry point into the javascript.  Calle gen_table with a header 
 * array and a content 2D array to create a new table using header for the
 * header columns and content for the table content
 * 
 * @param header 1 x n Array containing Word objects
 * @param content m x n Array containing Word objects
 * @return
 */
function gen_table(header, content) {
	tblContents = content;
	tblHeader = header;
	
	insertTableHeaders();
	insertTableBody();
	newColumnButton();
}

/**
 * Takes the data inside tblHeader and creates new HTML Elements for it so 
 * that we get nice table headers
 * @return
 */
function insertTableHeaders() {
	var thead = document.getElementById("tblhead");
		
	//create a new row to store our th header cells
	var tr = newTableRowNode(0);
	tr.id = "tblheadrow";

	for (i = 0; i < tblHeader.length; i++) {
		var th = newHeaderNode(tblHeader[i])
		tr.appendChild(th);
	}
	
	//add tr to the thead as a child
	thead.appendChild(tr);
}

/**
 * takes the data inside tblContent and creates new HTML elements for it so 
 * that we have a nice table to see
 * @return
 */
function insertTableBody() {
	var tbody = document.getElementById("tblbody");	
	
	for (j = 0; j < tblContents.length; j++) {
		var tr = newTableRowNode(j);
		for (i = 0; i < tblContents[j].length; i++) {
			
			//if we're in the first column, don't add the checkmark box 
			var cell;
			if (i == 0)  {
				cell = newCellNode(tblContents[j][i].word);
			}
			else {
				cell = newMarkedCellNode(tblContents[j][i].word,
						tblContents[j][i].status);
			}
			
			//we can identify where a cell belongs in tblContents by setting its
			//unique id to be row_cowl
			cell.id = "" + j + "_" + i;
			tr.appendChild(cell);
		}
		tbody.appendChild(tr);
	}
}

/**
 * This inserts the "new language" button in the table
 * @return
 */
function newColumnButton() {
	var tblheadrow= document.getElementById("tblheadrow");
	
	var tblcell = document.createElement("th");
	tblcell.id = "buttoncell";
	
	//create a button that lets users add new languages
	var newLangBtn = document.createElement("input");
	newLangBtn.setAttribute("type", "button");
	newLangBtn.setAttribute("onClick", "addColumn()");
	newLangBtn.id = "addlang";
	newLangBtn.value ="+";
	
	tblcell.appendChild(newLangBtn);
	tblheadrow.appendChild(tblcell);
}

/**
 * Creates a new table row element, tr
 * Will be one of two classes, even or odd, mainly used for CSS colouring
 * to make the nice zebra stripes pattern
 * @param rowCount the row position that the new row will be place din
 * @return a new tr object
 */
function newTableRowNode(rowCount) {
	var row = document.createElement("tr");
	
	if(rowCount%2 == 0) {
		row.setAttribute("class", "even");
	}
	else {
		row.setAttribute("class", "odd");
	}
		
	return row;
}

/**
 * Creates a new th table row with the sortTable function attached to it as
 * a listener
 * @param text the text that you want to appear inside the header node
 * @return a new th node
 */
function newHeaderNode(text) {
	var cell = document.createElement("th");
	cell.setAttribute("onClick", "sortTable(" + i + ")");
	cell.innerHTML = text;
	
	return cell;
}

/**
 * Creates a th node with a input, textbox, node inside of it, also adds
 * the appropriate listeners
 * @return
 */
function newEditableHeaderNode() {
	var newhead = document.createElement("th");
	newheadbox = document.createElement("input");
	
	newheadbox.setAttribute("type", "text");
	newheadbox.setAttribute("value", "New Language...");
	newheadbox.setAttribute("onblur", "verifyHeader()");
	newheadbox.setAttribute("onkeypress", "verifyHeaderKeyCheck(event)");
	
	newhead.appendChild(newheadbox);
	
	return newhead;
}

/**
 * Creates a generic td cell node with some preset setings, like
 * class and action events
 * 
 * Each "cellNode" contains a sub-element, a span element which contains
 * the actual text of the cell
 * @param text the text that you want in the table cell
 * @return a td node with a span as a child
 */
function newCellNode(text) {
	var cellNode = document.createElement("td");
	var t = document.createElement("span");
	t.setAttribute("class", "cellSpan unverified");
	t.innerHTML = text;
	
	cellNode.title = getTimeStamp();
	cellNode.setAttribute("ondblclick", "openTxtBx(event)");
	cellNode.setAttribute("class", "cellLabel");
	
	cellNode.appendChild(t);
	return cellNode;
}

/**
 * Returns a "marked" cell node, which is basically a cell in the table 
 * with an extra img object showing whether the word is verified, unverified or
 * rejected.  
 * 
 * @param text the text that you want to put in the table cell
 * @return a td node with a span and an img as a child
 */
function newMarkedCellNode(text, status) {
	var cellNode = newCellNode(text);
	
	var check = newCheckmarkNode();
	cellNode.appendChild(check);
	
	//modify the text and image depending on the status of the word
	if(status == 0) {
		setUnverified(cellNode);
	}
	else if (status == 1) {
		setVerified(cellNode);
	}
	else if (status == -1) {
		setRejected(cellNode);
	}
	return cellNode;
}

/**
 * return a new img node that has the checkmarks in it
 * @return
 */
function newCheckmarkNode() {
	var check = document.createElement("img");
	check.setAttribute("onclick", "changeStatus(event)");
	check.setAttribute("ondbclick", "");
	
	return check
}

/**
 * Returns a new input, textbox element with button press listeners
 * @return
 */
function newInputNode() {
	var box = document.createElement("input");
	box.setAttribute("type", "text");
	
	box.setAttribute("onblur", "closeTxtBx(event)");
	box.setAttribute("onkeypress", "closeTxtBxKeyCheck(event)");
	
	return box;
}

/**
 * Figures the current time as a string 
 * @return
 */
function getTimeStamp() {
	var today = new Date();
	var timestamp = "Last edited on " + today.getUTCDate()
						+ "/" + (today.getUTCMonth() + 1)
						+ "/" + today.getUTCFullYear()
						+ " at " + today.getUTCHours() + ":"
						+ today.getUTCMinutes() + ":"
						+ today.getUTCSeconds() + " UTC";
	
	return timestamp
}

/**
 * Sets a td element to "verified".  There are a few things that we have to
 * change here.  First, we will change the span element so it is in the verified
 * class.  Then, we will modify the source image in the img tag to the checkmark
 * and set its title and class to be verified and check.  The CSS will take 
 * care of the rest
 * @param td the cell in the table that you want to change the status of
 * @param word the word as a Word object in tblContent that we are modifying
 * @return
 */
function setVerified(td, word) {
	var span = td.childNodes[0];
	var img = td.childNodes[1];
	
	img.setAttribute("src", "img/check.png");
	img.setAttribute("title", "verified");
	img.setAttribute("class", "check");
	span.setAttribute("class", "verified");
	
	td.setAttribute("title", getTimeStamp());
	
	if (word != null) {
		word.status = 1;
	}
}

/**
 * Sets a td element to "rejected".  There are a few things that we have to
 * change here.  First, we will change the span element so it is in the 
 * rejected class.  Then, we will modify the source image in the img tag 
 * to the xmark and set its title and class to be rejected and xmark.  
 * The CSS will take care of the rest
 * @param td the cell in the table that you want to change the status of reject
 * @param word the word as a Word object in tblContent that we are modifying
 * @return
 */
function setRejected(td, word) {
	var span = td.childNodes[0];
	var img = td.childNodes[1];
	
	img.setAttribute("src", "img/xmark.png");
	img.setAttribute("title", "rejected");
	img.setAttribute("class", "xmark");
	span.setAttribute("class", "rejected");
	
	td.setAttribute("title", getTimeStamp());
	
	if (word != null) {
		word.status = -1;
	}
}

/**
 * Sets a td element to "unverified".  There are a few things that we have to
 * change here.  First, we will change the span element so it is in the 
 * unverified class.  Then, we will modify the source image in the img tag 
 * to the empty and set its title and class to be unverified and empty.  
 * The CSS will take care of the rest
 * @param td the cell in the table that you want to change the status of empty
 * @param word the word as a Word object in tblContent that we are modifying
 * @return
 */
function setUnverified(td, word) {
	var span = td.childNodes[0];
	var img = td.childNodes[1];
	
	img.setAttribute("src", "img/empty.png");
	img.setAttribute("title", "unverified");
	img.setAttribute("class", "empty");
	span.setAttribute("class", "unverified");
	
	td.setAttribute("title", getTimeStamp());
	
	if (word != null) {
		word.status = 0;
	}
}
