//
// (C) Cryo Performance Computing 2008, Retail PC Dynamic Online Configuration Code
// V110 Oct 2008

var rowColour = '';
var selImg = '';
var selText = '';
var sMarkup = '';
var oTblRef;
var BasePrice = 0;
var TotalPrice = 0;

// open xml doc build options doc *legacy*
// if (isIE) {
//	var xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
//	xmlDoc.async=false;
//	xmlDoc.onreadystatechange=verify;
//	xmlDoc.load("xmldocs/" + sXMLOptions + ".xml");
//	if (!xmlDoc) alert ("No build XML loaded!!!");
//	}
//	else {
//	var xmlDoc=document.implementation.createDocument("","",null);
//	xmlDoc.async=false;
//	xmlDoc.onreadystatechange=verify;
//	xmlDoc.load("xmldocs/" + sXMLOptions + ".xml");
	// enhanced customisation not yet supported outside of IE
	//oldOpts = document.getElementById('OldOptions');
	//oldOpts.style.display = 'block';
//	}
//

// open xml doc build options doc
var error = "";
var file = "xmldocs/" + sXMLOptions + ".xml";
try //Internet Explorer
{
 var xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
 xmlDoc.async=false;
 xmlDoc.onreadystatechange=verify;
 xmlDoc.load(file);
 var x = xmlDoc.documentElement;
}
catch(e)
{
 try //Firefox, Mozilla, Opera, etc.
 {
  var xmlDoc=document.implementation.createDocument("","",null);
  xmlDoc.async=false;
  xmlDoc.onreadystatechange=verify;
  xmlDoc.load(file);
  var x = xmlDoc.documentElement;
 }
 catch(e)
 {
  try //Google Chrome
  {
   var xmlhttp = new window.XMLHttpRequest();
   xmlhttp.open("GET",file,false);
   xmlhttp.send(null);
   var xmlDoc = xmlhttp.responseXML.documentElement;
   var x = xmlDoc;
  }
  catch(e)
  {
   error=e.message;
  }
 }
}

// only ie supports dynamic customisation for now
if (xmlDoc) {
	document.frmCryoPCOptions.action="http://cgi.www.cryopc.co.uk/cgi-bin/www.cryopc.co.uk/form-quote.pl";
	//var x = xmlDoc.documentElement;
	// open table and write header row, when xml is loaded sync
	BasePrice=parseInt(x.getElementsByTagName("BasePrice")[0].childNodes[0].nodeValue);
	TotalPrice=BasePrice;
	parseNodes(x);
	}

function dumpXML(tree, depth) {

	var sTab = depth + "&nbsp;&nbsp;&nbsp;&nbsp;";
	
	for (var r=0; r++; r<tree.length) {
		document.write(sTab + "nodeName: " + tree[r].nodeName + ", nodeValue: " + tree[r].nodeValue + ", text: " + GetText(tree[r]));
		if (tree.hasChildNodes) dumpXML(tree[r], sTab);
		}
}

//traverse node tree to create option tables
function parseNodes(tree) {

	for (var r=0; r<get_length(tree.childNodes); r++) {
		var x = getNodeByIndex(tree.childNodes, r);

		var isOptEntry = false;
		try {
			isOptEntry = (getNodeByIndex(x.childNodes, 0).getElementsByTagName('optionentry')!=null);
			}
		catch (err)
			{ }
		
		if(isOptEntry && x.hasChildNodes()) {
			var attr = x.attributes;
			if (attr) {
				var optTitle = attr.getNamedItem('optTitle');
				var optInfoPg = attr.getNamedItem('optInfoPg');

	    		parseOptions(x, x.nodeName, optTitle.nodeValue, optInfoPg.nodeValue);
            	}
			}
		}
}

function isCheckboxOpt(nod) {
	var ret = false, attr = nod.attributes;
	if (attr) {
		var optCtl = attr.getNamedItem('optControl');
		if (optCtl)
			ret = optCtl.nodeValue == 'checkbox';
		}
		
	return ret;
}

function get_firstChild(n)
{
	y=n.firstChild;
	while (y.nodeType!=1)
	  {
	  y=y.nextSibling;
	  }
	return y;
}

function get_length(n)
{
	var len = 0;
	
	for (i=0;i<n.length;i++)
	{ 
	if (n[i].nodeType==1)
	  {// only process element nodes 
		len++;
	  } 
	}
	return len;
}

function verify() { 
    if (xmlDoc.readyState!=4)
            return false;
//		else {
//		}
}

function writeHTML(sHTML) {
	//divOpts = document.getElementById('ProductOpts');
	document.write(sHTML);
}

function parseOptions(x, optId, optName, popupLink) {

	selImg = '';
	selText = '';
	sMarkup = '';
	
	// write header row for option table note: <thead> has strange behaviour in Firefox, not used
	writeTableHead(optId, popupLink, optName);

	//iterate through all nodes displaying options
	writeRows(x, optId);

	// write in extra manual options if required
	
	// close option table
	// set chosen option image and text
	if (x.hasChildNodes)
		setTableImageAndText('tbl' + optId, selImg, selText);

	// add supplemnentary options where appropriate
	switch (optId) {
		case 'CaseOpts' : {
			writeGenericRow('Select the colour for your case <input type="radio" value="Black" name="CaseColour" checked>  Anodised Black<input type="radio" value="Silver" name="CaseColour">  Brushed Aluminium Silver');
			break;
			}
		case 'OSVersion' : {
			//write in 32/64 bit option
			writeGenericRow('Select OS Version <input type="radio" value="32bit" name="OSType"> 32 bit<input type="radio" value="64bit" name="OSType" checked> 64 bit');
			break;
			}
		case 'DualBootOS' : {
			//write in 32/64 bit option
			writeGenericRow('Select OS Version <input type="radio" value="32bit" name="DualOSType" checked> 32 bit<input type="radio" value="64bit" name="DualOSType"> 64 bit');
			break;
			}
		default : {
			break;
			}
		}
		
}

function writeTableHead(optId, popupLink, optName, insertRef) {

	var divOpts = document.getElementById("ProductOpts");
	if (!insertRef) insertRef = divOpts;
	
	// '<div id="div' + optId + '">
	var oDiv = create_Element('div' + optId, 'div');
	oDiv.setAttribute('id', 'div' + optId);
		
	// <table class='optionTable' border="0" width="765" id="tbl' + optId + '" cellspacing="3" cellpadding="2">
	var domTbl = create_Element('tbl' + optId, 'table');
	domTbl.setAttribute('width', '765');
	domTbl.setAttribute('id', 'tbl' + optId);
	domTbl.style.border = 0;
	domTbl.style.color = '#000000';
	domTbl.style.backgroundColor = '#FFFFFF';
	domTbl.setAttribute('cellspacing', '3');
	domTbl.setAttribute('cellpadding', '2');
	domTbl.className = 'optionTable';

	var domTbod = document.createElement('tbody');

	// '<tr style="background-color: #000000">'
	var domTH = document.createElement("thead");
	domTH.style.color = '#000000';
	domTH.style.backgroundColor = '#FFFFFF';
	var domTR = document.createElement("tr");

	// <td colspan="3"><font size="3" color="#FFFFFF"><b>' + optName + "</b></font>
	var domTD = document.createElement('td');
	domTD.colSpan = 3;
	var oFont = document.createElement('font');
	oFont.setAttribute('size', '3em');
	oFont.setAttribute('color', '#000000');
	var domTxt = document.createElement('b');
	var oTxt = document.createTextNode(optName);
	domTxt.appendChild(oTxt);
	oFont.appendChild(domTxt);
	domTD.appendChild(oFont);

	// <img src="images/DiscoverMoreButton.gif" id="btnInfo' + optId + '" onmouseout="FP_swapImgRestore()" 
	// onmouseover="FP_swapImg(1,1,/*id*/' + "'btnInfo" + optId + "',/*url*/'images/DiscoverMoreButtonDown.gif')" + 
	// '" align="right" onclick="javascript: showPopup(event, ' + "'" + popupLink + "')" + '" alt="Click to Learn more"></td>';
	var domImg = create_Element('btnInfo' + optId, 'img');
	domImg.setAttribute('src', 'images/DiscoverMoreButton.gif');
	domImg.setAttribute('id', 'btnInfo' + optId);
	domImg.setAttribute('onmouseout', 'FP_swapImgRestore()');
	domImg.setAttribute('onmouseover', 'FP_swapImg(1,1,' + "'btnInfo" + optId + "','images/DiscoverMoreButtonDown.gif')");
	domImg.setAttribute('align', 'right');
	domImg.setAttribute('onclick', "javascript: showPopup(event,'" + popupLink + "')");
	domImg.setAttribute('alt', 'Click to Learn More');
	domImg.style.color = '#000000';
	domImg.style.backgroundColor = '#FFFFFF';
	domTD.appendChild(domImg);

	if (optId=='GraphicsOpts')
	{
		var domBtn = create_Element('btnCompare' + optId, 'img');
		domBtn.setAttribute('src', 'images/CompareCardsButton.gif');
		domBtn.setAttribute('id', 'btnCompare' + optId);
		//domBtn.setAttribute('onmouseout', 'FP_swapImgRestore()');
		//domBtn.setAttribute('onmouseover', 'FP_swapImg(1,1,' + "'btnInfo" + optId + "','images/DiscoverMoreButtonDown.gif')");
		domBtn.style.cursor = 'pointer';
		domBtn.setAttribute('align', 'right');
		domBtn.setAttribute('onclick', "javascript: showScrollablePopup('/CompareGraphics.htm'); return false;");
		domBtn.setAttribute('alt', 'Click to Compare Technical Specification');
		domTD.appendChild(domBtn);
	}
	
	// appending closes tags
	domTR.appendChild(domTD);
	domTH.appendChild(domTR);
	domTbl.appendChild(domTH);
	domTbl.appendChild(domTbod);
	oDiv.appendChild(domTbl);
	oDiv.appendChild(document.createElement('br'));
	insertRef.appendChild(oDiv);
	
	// IE inline event handling wont work through the DOM without this hack
	if (isIE) domImg.parentNode.innerHTML = domImg.parentNode.innerHTML;
	
	// keep ref to working table for subsequent rows etc.
	oTblRef = domTbod;
}

function writeGenericRow(sInnerHtml) {
	// produces a merged single col row, spanning all 3 cols with passed in innerHTML
	rowColour = (rowColour=='E3E3E3') ? 'C0C0C0' : 'E3E3E3';
	var domTR = document.createElement('tr');
	domTR.style.backgroundColor = '#' + rowColour;
	
	var domTD1 = document.createElement('td');
	domTD1.style.width = '150px';

	var domTD = document.createElement('td');
	domTD.colSpan = 3;
	var domFont = document.createElement('font');
	domFont.setAttribute('size', '2');
	domFont.setAttribute('color', '#000000');
	domFont.innerHTML = sInnerHtml;
	
	domTD.appendChild(domFont);
	domTR.appendChild(domTD1);
	domTR.appendChild(domTD);
	oTblRef.appendChild(domTR);
}

function create_Element(sName, sType, sValue) {
	// create element with name attribute doesnt work in IE, this fixes it...
	var eleRet;
	if (sType==null) sType='input';

	if (isIE) {
			var sTag = "<" + sType + " name='" + sName;
			if (sValue && sValue!=null) sTag += "' value='" + sValue;
			sTag += "' />";
			eleRet = document.createElement(sTag);
		} else {
			eleRet = document.createElement(sType);
			eleRet.setAttribute('name', sName);
			eleRet.setAttribute('value', sValue);
		}
		
	return eleRet;
}
	
function writeTableRow(nCols, optionTxt, ctlType, sValue, sId, sIndent, nRowspan, bFirstrow, sPrice, sChecked, optText) {

	if (!sIndent) sIndent= '';
	rowColour = (rowColour=='E3E3E3') ? 'C0C0C0' : 'E3E3E3';
	var domTR = document.createElement('tr');
	domTR.style.backgroundColor = '#' + rowColour;
	// *NEW* fix para margin issues between browsers
	domTR.style.marginBottom = '0px';
	domTR.style.marginTop = '0px';
	
	if (nCols==3) {
		if (bFirstrow) {
				var sName = 'optImageCell';
			} else {
				var sName = 'optTextCell';
			}

		var domTD1 = create_Element(sName, 'td');
		domTD1.setAttribute('id', sName);
		domTD1.style.width = '150px';

		if (bFirstrow) {
				domTD1.style.backgroundColor = '#FFFFFF';
				domTD1.rowSpan = nRowspan;
			}
		}
	
	var domTD2 = document.createElement('td');
	var domFont = document.createElement('font');
	domFont.setAttribute('size', '2');
	domFont.setAttribute('color', '#000000');

	if (ctlType=='checkbox') {
			var domCtl = create_Element(sValue, null, sValue);
			domCtl.setAttribute('id', sValue);
		} else {
			var domCtl = create_Element(sId, null, sValue);
			domCtl.setAttribute('id', sId);
		}
	domCtl.setAttribute('title', optText);
	domCtl.setAttribute('onclick', 'javascript: optionClick(event)');
	domCtl.setAttribute('type', ctlType);

	var domOpttxt = document.createTextNode(optionTxt);

	domFont.appendChild(document.createTextNode(sIndent));
	domFont.appendChild(domCtl);
	domFont.appendChild(domOpttxt);
	domTD2.appendChild(domFont);
	
	var domTD3 = document.createElement('td');
	domTD3.style.width = '50px';
	domTD3.style.textAlign = 'right';
	var domTxt = document.createTextNode(sPrice);
	domFont = document.createElement('font');
	domFont.setAttribute('size', '2');
	domFont.setAttribute('color', '#000000');

	domFont.appendChild(domTxt);
	domTD3.appendChild(domFont);
	
	if (nCols==3) domTR.appendChild(domTD1);
	domTR.appendChild(domTD2);
	domTR.appendChild(domTD3);
	oTblRef.appendChild(domTR);

	if (sChecked=='checked') domCtl.setAttribute('checked', sChecked);

	// fix IE inline event handling bug!
	if (isIE) domCtl.parentNode.innerHTML = domCtl.parentNode.innerHTML;
}


function clearTbody(tblRef) {
   var tbody = tblRef.firstChild;
   tbody = tbody.nextSibling;
   while (tbody.childNodes.length > 0) {
      tbody.removeChild(tbody.firstChild);
   }
}

function GetText(node){ 
	if(isIE) { 
		return node.text; 
		} else { 
		return node.textContent; 
		}
}

function writeRows(x, optId, optSelOverride, lastRow) {

	// x is the collection of top level options and all its child nodes
	// test for and reference any subopts
	if (x.hasChildNodes) {
		var subOpts = x.getElementsByTagName('optiongrp');
		var hasSubopts = (get_length(subOpts) > 0);
		}

	var isSubopt = (x.nodeName=='suboption');
	
	// gets first optionentry tag	
	var b = get_firstChild(x);
	var nodes = x.childNodes;
	var r = 0;
	var ctlType = '';
	
	if (isCheckboxOpt(x))
		ctlType = 'checkbox'
		else
		ctlType = 'radio';
	
	var nodLen = get_length(nodes);
	while (r<nodLen)
	{
		// create row first
		
		// get child element of each option, then all siblings
		var optData = b.childNodes;
		var y = get_firstChild(b);
		var optText = '';
		var optImg = '';
		var optName = '';
		var optDesc = '';
		var optPrice = 0;
		var optSel = '';
		var nCols = 2;
		var nRowCount = 0;
		var bFirstrow = false;
		var i = 0;
		var dataLen = get_length(optData);

		while (i<dataLen) {
			var optValue = GetText(y);
			
			// make sure next child is a populated element
			// skip suboptions for now
			if (hasSubopts && y.nodeName=='suboption') break;

			switch (y.nodeName) {
				case 'optionDefault' :
					{
					// default selected option?
					if (optValue && optSelOverride==null) optSel = optValue=='true' ? 'checked' : '';
					break;
					}
				case 'optionText' :
					{
					if (optValue) optText = optValue;
					break;
					}
				case 'optionId' :
					{
					if (optValue) {
						optName = optValue;
						if (optName==optSelOverride) optSel = 'checked';
						}
					break;
					}
				case 'optionImage' :
					{
					if (optValue) optImg = optValue;
					break;
					}
				case 'optionDesc' :
					{
					if (optValue) optDesc = optValue;
					break;
					}
				case 'optionPrice' :
					{
					if (optValue) optPrice = parseInt(optValue);
					break;
					}
				}
				
			i++;
			do
			{
				if (i<dataLen) y = y.nextSibling;
			} while (y.nodeType!=1 && i<dataLen)
		}

		//optImage and additional optText - only row 1, span all rows-1
		if (!isSubopt && r==0) {
				nRowCount = get_length(nodes)-1;
				// add in number of suboptions to rowspan if applicable
				if (hasSubopts) {
					// first find selected option grp, or default
					var grpNode = getDefaultOptionGrp(x, optSelOverride);
					// then add in number of child nodes
					nRowCount = nRowCount + get_length(grpNode.getElementsByTagName('suboption')[0].childNodes);
					}
					
				nCols = 3;
				bFirstrow = true;
			}
			else if (r==(get_length(nodes)-1)) {
				if ( (!isSubopt && !(hasSubopts && optSel=='checked')) || (isSubopt && lastRow) )
					//sMarkup = sMarkup + '<td width="150"></td>';
					nCols = 3;
					bFirstrow = false;
			}

		//col - optionId radio select
		var sIndent;
		if (isSubopt) {
				//sMarkup = sMarkup + '<td>&nbsp;&nbsp;&nbsp;&nbsp;';
				sIndent =	String.fromCharCode(160) +
							String.fromCharCode(160) +
							String.fromCharCode(160) +
							String.fromCharCode(160);
			} else {
				//sMarkup = sMarkup + '<td>';
			}
			
		//opionPrice col - if not a suboption header
		//sMarkup = sMarkup + '<td width="50">';
		var sPrice = '';
		if (!hasSubopts) {
			//sMarkup = sMarkup + '<p align="right"><font size="2" color="#000000">';
			if (optPrice > -1) {
				//sMarkup = sMarkup + "+£";
					sPrice = "+£";
				} else {
				//sMarkup = sMarkup + "-£";
					sPrice = "-£";
				}
		
			//sMarkup = sMarkup + Math.abs(optPrice);
			//sMarkup = sMarkup + '</font></p>';
			sPrice = sPrice + Math.abs(optPrice);
			}
		
		//sMarkup = sMarkup + '</td></tr>';
		
		writeTableRow(nCols, optDesc, ctlType, optName, optId, sIndent, nRowCount, bFirstrow, sPrice, optSel, optText);
		
		// get default selected option Image and text
		if (optSel=='checked') {
			// call recursively to generate sub option list if there are any and this is the selected option
			if (hasSubopts) {
				writeRows(y, optName, null, (hasSubopts && r==(get_length(nodes)-1)));
				}
			
			if (optText) {
				selText = optText;
				}
			if (optImg) {
				selImg = optImg;
				}
			}
	
			r++;
			do
			{
				if (r<nodLen) b = b.nextSibling;
			} while (b.nodeType!=1 && r<nodLen)
		}
}

function getNodeById(sId, sElement, nodList) {

	if (!sElement || sElement=='') sElement = 'optionentry';

	if (!nodList) {
		var nList = xmlDoc.getElementsByTagName(sElement);
		}
		else {
		var nList = nodList.getElementsByTagName(sElement);
		}
		
	var nFound;
	
	if (get_length(nList)>0) {
		for (var i=0;i<get_length(nList); i++) {
			nFound = getNodeByIndex(nList, i);
			
			if (GetText(nFound.getElementsByTagName('optionId')[0])==sId)
				break;
			}
		}
	
	return nFound;
}

function getNodeByIndex(nList, n)
{
	// cross browser version of childNode access to DOM
	var index = 0;
	
	for (var r=0;r<nList.length;r++)
		{
		if (nList[r].nodeType==1) {
			if (index==n) break;
			index++;
			}
		}
		
	return nList[r];
}

function getFirstElement(nodes) {

	var oElem;
	
	for(r=0; r<nodes.length; r++) {
		if (nodes[r].nodeType==1) {
			oElem = nodes[r];
			break;
			}
	}
	
	return oElem;
}

function getNodeForCheckbox(sId) {

	// find xml node for a checkbox id
	var nodOptionSets = xmlDoc.getElementsByTagName('optionId');
	var found;
	
	for (r=0; r<nodOptionSets.length; r++) {
		var optId = GetText(nodOptionSets[r]);
		if (optId && optId==sId) {
			var nodParent = nodOptionSets[r].parentNode.parentNode;
			if (nodParent) var attr = nodParent.attributes;
	
			if (attr) {
				var ctlType = attr.getNamedItem('optControl');
				if (ctlType && ctlType.nodeValue=='checkbox') {
					found = nodOptionSets[r].parentNode;
					break;
					}
				}
			}
	}
	
	return found;
}

function optionClick(event) {

	// get ref to control
	ev = window.event ? window.event : event;
	ctrlObj = isIE ? ev.srcElement : ev.target;

	optId = ctrlObj.value; // option selected Id
	optClass = ctrlObj.id; // option type Id

	var isCheckbox = (ctrlObj.type == 'checkbox');

	// is this an option or optiongroup, or a checkbox
	if (isCheckbox) {
			var nodes = getNodeForCheckbox(optId);
		} else {
			var nodes = xmlDoc.getElementsByTagName(optClass)[0];
		}

	// null nodes mean its an optiongroup
	if (!nodes) {
			// nodes is actually the option grp with the optClass as an optionId
			nodes = getNodeById(optClass, 'optiongrp');
			// now make nodes all options under all optiongroups for this master option, all prices need adjusting
			var nodParent = nodes.parentNode;

			var allNodes = nodParent.childNodes;
			var hasSubopts = true;
			var tblName = 'tbl' + nodes.parentNode.nodeName;
		}
		else {
			// is this a top level sub group
			var topLevel = (get_firstChild(nodes).nodeName=='optiongrp');

			var allNodes = nodes.childNodes;
			var hasSubopts = false;
			var tblName = 'tbl' + optClass;
		}

	if (isCheckbox) {
		var oOSNode = getNodeById(optId);
		tblName= 'tbl' + oOSNode.parentNode.tagName;
		}

	// find our option in the XML build options and adjust prices accordingly
	var sElement = '';
	if (!topLevel) {
			if (isCheckbox) {
					var b = nodes;
				} else {
					var b = getNodeById(optId, '', nodes);  //returns collection of option nodes for the clicked optionId
				}
		} else {
			// otherwise find default new suboption and use that price
			var b = getDefaultSubOption(optId, nodes);
		}
		
	var x = b.childNodes;
	var newImg = '';
	var newText = '';
	var priceAdj = 0;
	var rowOffset = 0;
	
	for (r=0;r<x.length;r++) {
		switch (x[r].nodeName) {
			case 'optionImage' :
				newImg = GetText(x[r]);
				break;
			case 'optionText' :
				newText = GetText(x[r]);
				break;
			case 'optionPrice' :
				var priceAdj = parseInt(GetText(x[r]));
				break;
			}
		}

	x = allNodes;

	// get ref to table in y
	var refTbl = document.getElementById(tblName);

	// if its a checkbox we dont adjust other option prices, jsut adjust price and return
	if (isCheckbox) {
		// if unchecked then use negative of option value
		if (!ctrlObj.checked)
			priceAdj = priceAdj-(2*priceAdj);
		}
		else
		{
		
		// first adjust all option prices based on newly selected option
		if (hasSubopts || topLevel) {
			// adjust suboption prices
			var nOpts = 0;
			for (r=0;r<x.length;r++) {
				if (x[r].nodeType==1) {
					// process subooptions
					var oNode = get_firstChild(x[r]);

					// get optionId associated with this option group
					if (oNode.nodeName=='optionId') {
							var nodOptId = oNode;
						} else {
							var nodOptId = oNode.getElementsByTagName('optionId');
						}
						
					var grpId = GetText(nodOptId);

					// dont try to tweak table for top level option changes, table will be completely re-rendered later
					var nodOptions = x[r].getElementsByTagName('optionentry');
					adjustOptionPrice(nodOptions, priceAdj, refTbl, nOpts+1, (grpId==optClass && !topLevel));
					nOpts++;
					}
				}
			} else {
			// adjust regular option prices
			if (refTbl) adjustOptionPrice(x, priceAdj, refTbl, 0, true);
			}
	
		// for top level option changes table now needs completely re-rendering, in place
		// displaying new set of suboptions
		if (topLevel) {
			sMarkup = '';
			// clear out old table rows first
			var divRef = document.getElementById('div' + optClass);
			
			oTblRef = refTbl.getElementsByTagName('tbody')[0];
			clearTbody(refTbl);
			
			// write new tbody of table

			//sMarkup = '<table border="0" width="765" id="tbl' + optClass + '" cellspacing="3" cellpadding="2">' + tblRef.rows[0].outerHTML;
			// preserve table tags and header
			// write nodes overriding default option with selected
			writeRows(nodes, optClass, optId);
			// set TBODY inner html to all row and column markup
			//divRef.innerHTML = sMarkup + '<\table>';
			}
		}
	
	// set chosen option image and text
	if (get_length(x)>0) {
		if (refTbl) setTableImageAndText(tblName, newImg, newText);
		}
		
	// adjust total price accordingly
	TotalPrice = parseInt(TotalPrice) + priceAdj;
	document.frmCryoPCOptions.accumulator.value = TotalPrice;

	return false;
}

function getDefaultSubOption(optId, nodes) {
	// function to return node that is the default sub option for the group with optId
	
	var b = getNodeById(optId, 'optiongrp', nodes);
	b = b.getElementsByTagName('suboption')[0].getElementsByTagName('optionDefault');
	
	for (r=0;r<get_length(b);r++) {
		if (b[r].tagName=='optionDefault' && GetText(b[r])=='true') break;
		}
		
	return b[r].parentNode;
}

function getDefaultOptionGrp(nodes, optSelOverride) {
	// returns element option group that is either the default or the selected override
	if (optSelOverride)
			return getNodeById(optSelOverride, 'optiongrp', nodes);
		else {
			var c;
			// get node list of option groups
			var b = nodes.getElementsByTagName('optiongrp');
			for (var r=0; r<get_length(b); r++) {
				// get optionDefault in that group if it exists
				c = b[r].getElementsByTagName('optionDefault')[0];
				if (c.tagName=='optionDefault' && GetText(c)=='true' && c.parentNode.nodeName=='optiongrp') break;
				}
			}
		
	return c.parentNode;
}

function setTableImageAndText(tblName, newImg, newText) {

	var tblRef = document.getElementById(tblName); //Table

	for (var r=0; r<tblRef.rows.length; r++) {
		var x = tblRef.rows[r].cells[0];
		if (x.id=='optImageCell') var imgRef = x;
		if (x.id=='optTextCell') var txtRef = x;
		}

	if (imgRef) {
		if (newImg)
			imgRef.innerHTML = '<p align="center"><img src="images/thumbnails/images/' + newImg + '" width="150"></p>';
			else imgRef.innerHTML = '';
		}
	if (txtRef) {
		txtRef.innerHTML = '<font size="2" color="#000000">' + newText + '</font>';
		}
}

function adjustOptionPrice(x, priceAdj, optTable, rowOffset, chgTable) {

	var nRow = 0;
	
	for (var r=0;r<x.length;r++) {

		a = x[r].childNodes;

		// get and adjust each option price to new price		
		if (a && a.length>0) {
			for (i=0;i<a.length;i++) {
	
				if (a[i].nodeName=='optionPrice') {
						var newPrice = parseInt(GetText(a[i])) - priceAdj;
						if (isIE) {
								a[i].text = newPrice;
							}
							else
							{
								a[i].textContent = newPrice;
							}
						break;
					}
	
				}
	
			// find the table with our option in it, and change it
			if (chgTable) {
				var tblcells = optTable.rows[nRow+rowOffset+1].cells;
				var c = tblcells[tblcells.length-1];
		
				if (newPrice > -1)
					c.innerHTML = '<p align="right"><font size="2" color="#000000">+£' + Math.abs(newPrice) + '</font></p>';
					else
					c.innerHTML = '<p align="right"><font size="2" color="#000000">-£' + Math.abs(newPrice) + '</font></p>';
				}
			
			nRow++;
			}
		}
}
