/* grid_formatting.js
 *
 * version 1.14 - added isRefurb parameter to lockgrid for survey refurb demo.
 * version 1.13 - [30-01-08]: removed click handlers from
 *                highlightEmptyGridRows and highlightEmptyGridCols.
 * version 1.12 - [13-11-07]: modified colorRows to account for group headers
 * version 1.11 - [05-11-07]: modified removeHorizontal dividers - no longer
                  removes the row but sets it's display property to 'none'
 * version 1.10 - [19-10-07]: modified isGridErrorPage,highlightEmptyGridRows.
 * version 1.9 - modified removeDividerLines to account for sliders
 * version 1.8 - added function highlightEmptyGridColumns
 * version 1.7 - added function appendRightAnswerText
 * version 1.6 - renamed function lockGridRows to lockGrid and added
                 locking functionality to 3D grids.
 * version 1.5 - modified function formatAnswerLabels to use the styles
                 defined in existing span nodes
 * version 1.4 - added function lockGridRows
 * version 1.3 - added funcion isIE, modified function highlightEmptyGridRows.
 * version 1.2 - modified function findGrids to check for tables within an 
 *               answer table
 * version 1.1 - added 3 new functions: highlightEmptyGridRows, 
 *               getAnswerGridRows and getEmptyGridRows 
 * Version 1.0 - original version
 *
 * Dependencies
 * requires rsn_misc.js, rsn_gut_manipulation.
 *
 * Copyright (2007) Research Now Plc.
 */
 
/*
 * removes vertical divider lines from a grid table
 *
 * answerTable  - a reference to the HTML table containing the grid
 * hasScrollBar - true if the scroll bar option has been selected in grid
 *                properties.
 */
function removeVerticalDividers(answerTable)  {
	var verticalDividers = new Array();
	var firstRow = answerTable.getElementsByTagName("tr")[0];
	var tds = firstRow.getElementsByTagName("td");
	
	for (var i = 0; i < tds.length; i++)  {
		var td = tds[i];
		
		if (isVerticalDivider(td))
	    firstRow.removeChild(td);
	}
}

/*
 * removes horizontal divider lines from a grid table
 *
 * answerTable  - a reference to the HTML table containing the grid
 * hasScrollBar - true if the scroll bar option has been selected in grid
 *                properties.
 * keepFirst - (boolean) determines if the first horizontal divider is removed
 *             or not.
 */
function removeHorizontalDividers(answerTable, hasScrollBar, keepFirst)  {
	var rows = answerTable.getElementsByTagName("tr");
	var isFirst = true;
	
	for (var i = 1; i < rows.length; i++) {
		var curRow = rows[i];
		
	// confirmit scrollbar relies on first horizontal divider being present 
	if (hasScrollBar && i == 1)  {
		curRow.style.visibility = "hidden";
		continue;
	}
		
    if ( isHorizontalDivider(curRow) ) {
		//curRow.parentNode.removeChild(curRow);
	    if (isFirst && keepFirst) {
	        isFirst = false;
			continue;
		}
		curRow.style.display = "none";
	}
  }
}

/* removes divider lines from a grid table and colors its rows
 *
 * answerTable  - a reference to the HTML table containing the grid
 * hasScrollBar - true if the scroll bar option has been selected in grid
 *                properties.
 */
function removeDividerLines(answerTable, hasScrollBar) { 
	if (isIE())  {
	    var behavior = answerTable.style["behavior"];
		var hasSliders = behavior.indexOf("gridSlider2.htc") != -1;
	
		//. no need to remove divider lines if sliders are present.
		if (hasSliders)  {
			return;
		}
	}
	
	// cancel Confirmit's default cellspacing="1" attr
	answerTable.cellSpacing = 0;
  
	// remove vertical divider lines
	removeVerticalDividers(answerTable);

	// remove horizontal divider lines
	removeHorizontalDividers(answerTable, hasScrollBar);
}

/* returns true if a tr (row) is used only as a horizontal dividing line in a 
 * grid. Will throw exception if row is null or contains no children that are
 * tds.
 */
function isHorizontalDivider(row) {
	var firstTd = row.getElementsByTagName("td")[0];
	return isVerticalDivider(firstTd);
}

/* returns true if a td cell in the top row of a grid table is used only as a 
 * vertical divider line
 */
function isVerticalDivider(td) {
	var firstChild = td.firstChild;
	return firstChild != null 
      	&& firstChild.nodeType == 1 /* Node.ELEMENT_NODE */
		&& firstChild.tagName.toLowerCase() == "img" 
		&& /nothing\.gif$/i.test( firstChild.getAttribute("src") );
}

/* sets the background color of rows in a table to rgbValues[0], rgbValues[1] 
 * etc... and repeats the colors if there are more rows than colors.
 *
 * answerTable - a reference to the HTML table containing the grid
 * rgbValues   - an array of colors to be applied to the rows in the 
 *               answerTable
 */
function colorRows(answerTable, rgbValues, groupHeaders) {
	var isGroupHeader = false;
	var rows = answerTable.getElementsByTagName("tr");
	var count = 0;
	outer: for (var i = 0; i < rows.length; i++) {
		var row = rows[i];

		// skip over the rows that are horizontal dividers
		if (isHorizontalDivider(row))
			continue;

		// repeat the colors if there are more rows than colors.
		if (count >= rgbValues.length) {
			count = 0;
		}
		
		var tds = row.getElementsByTagName("td");
		
		//group header
		if (tds.length == 1)  {
			tds[0].colSpan = (tds[0].colSpan * 2) + 1;
			isGroupHeader = true;	
		}
		else {
		    isGroupHeader = false;	
		}
		
		if (groupHeaders && !isGroupHeader)
			continue outer;
		
		rgb = rgbValues[count++];
	
	    if(rgb != "")
		    row.style.backgroundColor = rgb;
    }
}

/*
 * determines if the passed in object has any properties associated with it
 */
function hasProperties(object)  {
	var propertiesExist = false;
	for (var rule in object) {
		propertiesExist = true;
		return true;
	}
   
	if (!propertiesExist)
		return false;
}

/* formats the scale labels in the answerTable to the rules defined
 * in css
 *
 * answerTable - the answer table containing the scale lables
 * css         - an obect representing css style properties to be applied to
 *               the scale labels
 */
function formatScaleLabels(answerTable, css) { 
	if (!hasProperties(css))
		return;

	var labels      = getGridScaleLabels(answerTable);
    
	// li = label iterator (for looping thru labels array)
	var li = 0
  
	var firstRow = answerTable.getElementsByTagName("tr")[0];
	var tds      = firstRow.getElementsByTagName("td");
  
	// li = label iterator (for looping thru labels array)
	for (var i=1; i < tds.length; i++) {
		var td = tds[i];
    
		// skip over vertical divider lines
		if (isVerticalDivider(td)) {
			continue;
		}
     
		// gut this td and put the label in it
		while ( td.hasChildNodes() )
			td.removeChild(td.firstChild);
    
		var label = labels[li++];
		var span  = document.createElement("span");
		for (var rule in css)
			span.style[rule] = css[rule];

		// apply default font family
		if (!css.fontFamily)
			span.style.fontFamily = getCalculatedStyle(body, "fontFamily");

		// apply default font size
		if (!css.fontSize)
			span.style.fontSize = "10pt";

		span.innerHTML = label;
		td.appendChild(span);
	}
}

/* formats the answer labels in the answerTable to the rules defined
 * in css
 *
 * answerTable - the answer table containing the answer labels
 * css         - an obect representing css style properties to be applied to
 *               the answer labels
 */
function formatAnswerLabels(answerTable, css) {	
	if (!hasProperties(css))
		return;
  
	var labels = getGridAnswerLabels(answerTable);
  
	// li = label iterator (for looping thru labels array)
	var li = 0;
	var rows = answerTable.getElementsByTagName("tr");
  
	for (var i = 1; i < rows.length; i++) {
		// skip over horizontal divider lines
		if (isHorizontalDivider(rows[i])) {
			continue;
		}
	  
    var firstTd = rows[i].getElementsByTagName("td")[0];
	var span = null;
	
	// check for current span nodes defined in the answer text
	var spanNodes = firstTd.getElementsByTagName("span");
	if (spanNodes.length > 0)  {
		span = spanNodes[0];
	}
	else {
	    span = document.createElement("span");	
	}
    
    // gut this td and put the label in it
    while ( firstTd.hasChildNodes() )
		firstTd.removeChild(firstTd.firstChild);
    
    var label = labels[li++];
    if (label != null) {
 
        // apply css style properties
        for (var rule in css)
		    if (!span.style[rule])
        	    span.style[rule] = css[rule];

		    // apply default font family
		    if (!css.fontFamily)
			    span.style.fontFamily = getCalculatedStyle(body, "fontFamily");

		    // apply default font size
		    if (!css.fontSize)
			    span.style.fontSize = "10pt";

		    span.innerHTML = label;
		    firstTd.appendChild(span);
        }
    }
}

/* returns an array of scale labels in an answerTable
 *
 * answerTable - the grid table that contains the scale labels
 */
function getGridScaleLabels(answerTable) {
	var firstRow = answerTable.getElementsByTagName("tr")[0];
	var tds      = firstRow.getElementsByTagName("td");
	var labels   = new Array();
  
	for (var i = 1; i < tds.length; i++) {
		var td    = tds[i];
    
        // skip over vertical divider lines
        if (isVerticalDivider(td)) {
            continue;
        }	
    
        var textNode = getFirstNode(td, 3, true);
        var parent = textNode.parentNode;
    
        while (parent.tagName.toLowerCase() != "span" 
	        && parent.tagName.toLowerCase() != "font") {
    	    parent = parent.parentNode;
	    } 
		
        labels.push( parent.innerHTML );
    }
    return labels;
}

/* returns an array of answer labels in an answerTable
 *
 * answerTable - the grid table that contains the answer labels
 */
function getGridAnswerLabels(answerTable) {
    var rows   = answerTable.getElementsByTagName("tr");
	var labels = new Array();
  
	for (var i = 1; i < rows.length; i++) {
		var tr = rows[i];
    
		// skip over horizontal divider lines
		if (isHorizontalDivider(tr)) {
			continue;   
		}
    
		var td = tr.getElementsByTagName("td")[0];
		var textNode = getFirstNode(td, 3, true);
		if (textNode != null) {
			var parent = textNode.parentNode;
    
			while (parent.tagName.toLowerCase() != "span" 
					&& parent.tagName.toLowerCase() != "font") {
    		  		parent = parent.parentNode;
			} 

			labels.push( parent.innerHTML );
	    }
	}
  	return labels;
}

/* returns an array of references to all HTML answer tables on the current 
 * page
 */
function getAnswerTables() {
    var divTags    = document.getElementsByTagName("div");
    var answers = new Array();
    for (var i = 0; i < divTags.length; i++) {
        var divTag = divTags[i];
        if (divTag.className == "answers") 
	        answers.push(divTag.getElementsByTagName('table')[0]);
    }
    return answers;
}

/* returns an array of references to all HTML answer tables on the current 
 * page that are either Grids or 3DGrids
 */
function findGrids() {
	var grids = new Array();
	var tables = getAnswerTables();
 
	for (var i=0; i<tables.length;i++) {
		var table = tables[i];
  
		// check for tables inside this table
		var innerTables = table.getElementsByTagName("table");
		if (innerTables != null && innerTables.length >=1)
			continue;
  
		var trs = table.getElementsByTagName("tr");
		var tds = trs[0].getElementsByTagName("td");
		if (tds.length >= 3) {
			grids.push(table);
		}
	}
	return grids;
}

/* applies equal padding space on the scale labels in the answerTable.
 *
 * answerTable - a reference to the HTML grid table to apply the scale 
 * padding to
 */
function autoScaleGrid(table) {
    var lengthArr = new Array();
	var max = 0;

	// get the header containing the scale headers
	var headerRow = table.getElementsByTagName("tr")[0];
	var headerTds = headerRow.getElementsByTagName("td");

	// iterate through the scale headers, leave out the first td 
	// as it is blank
	for (var i=1; i< headerTds.length; i++) {
		var headerTd = headerTds[i];

		// skip over the divider columns
		if (isVerticalDivider(headerTd)) {
			continue;
		}
  
		var textNode = getFirstNode(headerTd, 3, true);
  
		if (textNode == null) {
			continue;
		} 
   
		if (textNode.nodeValue.length > max)
			max = textNode.nodeValue.length;
	}

	var spacing = max*10;
  
	// set td width 
	for (var i=1; i<headerTds.length; i++) {
		var headerTd = headerTds[i];
   
		// skip over the divider columns
		if (headerTd.firstChild != null && headerTd.firstChild.
		    tagName.toLowerCase() == "img") {
       			continue;
			}
   
			headerTd.width = spacing;
	}
}

/*
 * formats all grid tables on the current page
 *
 * rgbArr       - array of rgb values to color the rows of the grid
 * scaleStyles  - an object with css style properties to apply to the
 * 				  scale text
 * answerStyles - an object with css style properties to apply to the
 *                answer text
 */
function formatAllGrids(rgbArr, scaleStyles, answerStyles) {
    var grids = findGrids();
	var grid = null;
 
	for (var i=0;i<grids.length;i++) { 
		grid = grids[i];
		
		autoScaleGrid(grid);
		formatAnswerLabels(grid, answerStyles);
		formatScaleLabels(grid, scaleStyles);
		removeDividerLines(grid);
		colorRows(grid, rgbArr);
	}
}

/* finds all empty/unanswered columns in the 3D grid table and makes their 
 * background color flash from fromRGB to toRGB. If toRGB is absent, the 
 * column will stay solidly lit in fromRGB.
 *
 * answerTable - a reference to the HTML grid table to apply the scale 
 *               padding 
 * fromRGB     - color to use for the background of an empty column. Will 
 *				 flash alternately with toRGB if present.
 * toRGB       - (optional) if present, empty columns will rapidly alternate 
 *               (flash) from fromRGB to toRGB
 * speed       - the speed to alternatively flash between the colors in
 *               milliseconds
 */
function highlightEmptyGridCols(answerTable, fromRGB, toRGB, speed) {
	if (!isGridErrorPage())
		return;
	
	// a reference to the interval function
	var intervalRef = null;
	
	// a reference to the column names that will not be highlighted
	var checkedArr = new Array();
	
	// a reference to the td cells that will be highlighted
	var cellsToHighlight = new Array();	
	
	// find all columns that do not need to be highlighted
	for (var i=0; i<inputs.length;i++) {
		var input = inputs[i];
		if (input.checked)
			checkedArr.push(input.name);
	}
	
	// determine which cells to highlight from the column name
	for (var i=0; i<inputs.length; i++)  {
		var input = inputs[i];
		var highlightCell = true;
		
		for (var k=0; k<checkedArr.length; k++)  {
			var name = checkedArr[k];
			if (input.name == name )
				highlightCell = false;
		}
		
		if (highlightCell)  {
			cellsToHighlight.push(input.parentNode);	
		}
	}
	
	// set the initial background color of the cells to highlight
	for (var i=0; i<cellsToHighlight.length; i++)  {
		var cell = cellsToHighlight[i];
		cell.bgColor = fromRGB;  
	}	
	
	// initiate the highlighting on each of the cells to highlight
	intervalRef = window.setInterval(function()  {
		for (var i=0; i<cellsToHighlight.length; i++)  {
			var cell = cellsToHighlight[i];				
			if (cell.bgColor == fromRGB.toLowerCase())
				cell.bgColor = toRGB;
			else if (cell.bgColor == toRGB.toLowerCase()) 
				cell.bgColor = fromRGB;			
		}
	}, speed);
}

/* finds all empty/unanswered rows in the grid table and makes their 
 * background color flash from fromRGB to toRGB. If toRGB is absent, the row 
 * will stay solidly lit in fromRGB.
 *
 * answerTable - a reference to the HTML grid table to apply the highlighting
 * fromRGB     - color to use for the background of an empty row. Will flash 
 *               alternately with toRGB if present.
 * toRGB       - (optional) if present, empty rows will rapidly alternate 
 *               (flash) from fromRGB to toRGB
 * speed       - the speed to alternatively flash between the colors in
 *               milliseconds
 */
function highlightEmptyGridRows(answerTable, fromRGB, toRGB, speed) {
	if (fromRGB) fromRGB = fromRGB.toLowerCase();
	if (toRGB) toRGB = toRGB.toLowerCase();
	
	if (!isGridErrorPage())
		return;
	
	if (is3DGrid(answerTable))
		return;
	
	var rows = getEmptyGridRows(answerTable);
  
	// a reference to the interval functions
	var intervalRef = null;
    
	for (var i=0; i<rows.length; i++)  {
		var row = rows[i];  
		//set initial bgColor for the empty rows
		row.bgColor = fromRGB; 
	}	
  
	// if toRGB is not null, alternate between fromRGB and toRGB at the 
	// specified speed
	if (toRGB != null) {
		var row = null;

		intervalRef = window.setInterval(function()  {
			for (var i=0; i<rows.length; i++)  {
				row = rows[i];
				row.bgColor = row.bgColor == fromRGB? toRGB: fromRGB;
			}
		}, speed);
	}	  	
}

/* returns all the rows in the HTML table that have not been answered by
 * the respondent
 *
 * table - a reference to the HTML table containing the answers
 */
function getEmptyGridRows(table)  {
	var rows = getAnswerGridRows(table);
	var emptyRows = new Array();
 
	for (var i=0; i<rows.length; i++)  {
		var inputs = rows[i].getElementsByTagName("input");
		var isEmpty = true;
	  
		inputLoop: for (var k=0; k<inputs.length; k++)  {
		    if (inputs[k].checked)  {
			    isEmpty = false;
				break inputLoop;
			}
		}
	  
		if (isEmpty)
			emptyRows.push(rows[i]);
	}
	return emptyRows;
}

/*
 * returns all answer rows of a table
 *
 * table - a reference to the HTML table containing the answers
 */
function getAnswerGridRows(table)  {
	var rows = table.getElementsByTagName("tr");
	var answerRows = new Array();
  
	for (var i=1; i<rows.length; i++)  {
		if (isHorizontalDivider(rows[i]))
			continue;
	
	answerRows.push(rows[i]);
	}
	return answerRows;
}

/*
 * returns true if the client browser is Internet Explorer, false
 * otherwise.
 */
function isIE()  {
	return navigator.appName.toLowerCase().indexOf("microsoft") != -1;
}

/*
 * function that locks the grid row or column after the respondent has 
 * selected an answer, preventing them to click on more answers
 *
 * is3DGrid - determines if this is a 3D Grid so that columns will be locked
 *            instead of rows.
 */
function lockGrid(tableNum, is3DGrid, isRefurb)  {
	
	var table = getAnswerTable(tableNum);
	var rows = table.getElementsByTagName("tr");
   
	// array to store the id's of each button in the grid
	var inputArr = new Array();
	
	// set up event listeners on each button in the table
	for (var i=0; i<rows.length; i++)  {
		var inputs = rows[i].getElementsByTagName("input");
	  
		for (var k=0; k<inputs.length; k++)  {
			inputArr.push(inputs[k]);
			if (isIE())  {
				inputs[k].onclick = handleClick;
				if (isRefurb) { inputs[k].previousSibling.attachEvent("onmousedown", handleClick); }
				if (!is3DGrid && !isRefurb)
					inputs[k].parentNode.onclick = handleClick;
			}
			else  {
				
				inputs[k].onclick = handleClick; //TEST
                                if (isRefurb) inputs[k].previousSibling.addEventListener("mousedown", handleClick, false);
			}	  
		}
	}
  
	// check for already checked items
	for (var i=0; i<inputArr.length; i++)  {
		if (inputArr[i].checked)  { 
			var cellsToLock = getCellsToLock(inputArr[i], inputArr, is3DGrid, isRefurb);
			disableElements(inputArr[i], cellsToLock, !is3DGrid, isRefurb);
		}
	}
	
  
	function handleClick(evt) {
		evt = evt ? evt : window.event;
		var src = isIE() ? evt.srcElement : evt.target;
		if (!is3DGrid && src.tagName.toLowerCase() == "td")  {
			src = src.getElementsByTagName("input")[0];
		}
	  
		var cellsToLock = getCellsToLock(src, inputArr, is3DGrid, isRefurb);
		disableElements(src, cellsToLock, !is3DGrid, isRefurb); 	  
  	} //end of handleClick
}

/*
 * appends the answer text to the right hand side of the grid
 *
 * tableNum - the position of the grid on the page.
 */
function appendRightAnswerText(tableNum)  {
	var table = getAnswerTable(tableNum);
	var rows = table.getElementsByTagName("tr");
	
	var firstRow = rows[0];
	
	// copy the vertical divider and add it to the right hand side of the
	// grid
	var verticalDiv = firstRow.getElementsByTagName("td")[1];
	
	
	if (isVerticalDivider(verticalDiv))  {
		var verticalDivClone = verticalDiv.cloneNode(true);
		firstRow.appendChild(verticalDivClone);
	
		// add a vertical divider to the left hand side and change the 
		// background color for the effect of padding
		verticalDivClone = verticalDiv.cloneNode(true);
		verticalDivClone.bgColor = "white";
		firstRow.insertBefore(verticalDivClone, verticalDiv);
	
		// add a vertical divider to the right hand side and change the 
		// background color for the effect of padding
		verticalDivClone = verticalDiv.cloneNode(true);
		verticalDivClone.bgColor = "white";
		firstRow.appendChild(verticalDivClone);	
		}
		
	var firstTd = firstRow.getElementsByTagName("td")[0];
	var firstTdClone = firstTd.cloneNode("true");
	firstRow.appendChild(firstTdClone);
		
	// for each answer label, copy the answer text and add it to the right 
	// hand side of the grid
	for (var i=1; i<rows.length; i++)  {
		var row = rows[i];

		// increase the col span of all horizontal dividers
		if (isHorizontalDivider(row)) {
			var td = row.getElementsByTagName("td")[0];
			td.colSpan = td.colSpan + 4;
			continue;
		}

		var answerTd = row.getElementsByTagName("td")[0];

		// remove non-breaking space that confirmit adds to the answer labels
		var html = answerTd.innerHTML;
		var end = html.indexOf("&nbsp");
		answerTd.innerHTML = html.slice(0, end);

		answerTd.align = "right";

		var answerTdRight = answerTd.cloneNode(true);
 
		answerTdRight.align = "left";

		//check for div tags
		var div = answerTdRight.getElementsByTagName("div")[0];

		if (div != null) {
			div.align = "left";
		}
		row.appendChild(answerTdRight);
	} // end of for
}

/*
 * helper function that returns the elements to be locked from a grid based
 * on the element checked by the respondent.
 *
 * checkedElem - the element that the respondent checked in the grid.
 * elems       - an array of elements in the grid
 * is3DGrid    - determines if this is a normal grid or a 3D grid
 */
function getCellsToLock(checkedElem, elems, is3DGrid, isRefurb)  {
        if (isRefurb) checkedElem = checkedElem.parentNode.getElementsByTagName("input")[0];
	var cellsToLock = null;
	if (is3DGrid)  {
		var name = checkedElem.name;
		cellsToLock = new Array();
		  
		for (var k=0; k<elems.length;k++)  {
			if (checkedElem.id == elems[k].id)
				continue;
				  
			if (elems[k].name == name)  
				cellsToLock.push(elems[k]);
		}	  
	}
	else  {
		var rowToLock = checkedElem.parentNode;
		while (rowToLock.tagName.toLowerCase() != "tr")  {
			rowToLock = rowToLock.parentNode;  
		} 
		cellsToLock = rowToLock.getElementsByTagName("input");
	}
	return cellsToLock;
}

/*
 * helper function that disables the elements passed into the function. 
 *
 * elements      - an array of elements to disable.
 * disableParent - some browsers allow you to click on the area around the
 *                 radio button. Set this to true to disable this.
 */
function disableElements(checkedElem, elements, disableParent,isRefurb)  {
        if (isRefurb) checkedElem = checkedElem.parentNode.getElementsByTagName("input")[0];
 	for (var i = 0; i < elements.length; i++)  {
		if (checkedElem.id == elements[i].id)
			continue;
		
		var elem = elements[i];
		elem.disabled = true;

                if (isRefurb) {
                  var img = elem.previousSibling;
                  img.style.visibility = "hidden";
                }
		
		if (disableParent)
			elem.parentNode.disabled = true;
	}	
}

/*
 * determines if a grid is part of an error page
 */
function isGridErrorPage()  {
	return document.getElementById("errorMessage") != null;
}

function is3DGrid(answerTable) {
	var tr = answerTable.getElementsByTagName("tr")[2];
	var inputs = tr.getElementsByTagName("input");
	
	if (inputs.length == 1)
		return false;
	
	for (var i=0; i<inputs.length; i++) {
		if (i+1 != inputs.length) {
			if (inputs[i].value && inputs[i+1].value && inputs[i].value 
				== inputs[i+1].value)
				return true;
		}
	}
	
	return false;
}

function isGrid(table) {
  // check for tables inside this table
  var innerTables = table.getElementsByTagName("table");
  if (innerTables != null && innerTables.length >=1)
    return false;
  
  var trs = table.getElementsByTagName("tr");
  var tds = trs[0].getElementsByTagName("td");
  if (tds.length >= 3) {
    return true;
  }

  return false;
}