// ============================================================================= //
// ch6-cart.js
// John Niven, January 2004
// Copyright (c) 2004 Channel 6 Multimedia
// ============================================================================= //

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
// CONFIG START =>
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
var B_DEBUG						= false;
var DOMAIN						= '../index.html';
var SECURE_DOMAIN			= '../index.html';
var PATH							= '../index.html';
var SITE							= DOMAIN + PATH;
var SHOP							= 'shop/index.html';
var SECURE_SITE				= SECURE_DOMAIN + PATH;
var SITE_SHOP					= SITE + SHOP;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
// <=   END CONFIG
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //

// ============================================================================= //
// pseudo-constants used for page-navigation:
// ============================================================================= //
var PAGE_INTRO				= 'shop-intro.html';
var PAGE_START				= 'shop.html';
var PAGE_SOFTWARE			= 'software.html';
var PAGE_UPGRADE			= 'upgrade.html';		// NOT in cgi-bin
var PAGE_UPGRADE2			= 'upgrading.html';	// NOT in cgi-bin
var PAGE_DIVX				= 'div-x.html';
var PAGE_REMOTE				= 'remote.html';
var PAGE_ACCESSORIES		= 'accessories.html';
var PAGE_CART				= 'cart.html';
var PAGE_CHECKOUT			= 'checkout.html';
var PAGE_CONFIRM			= 'confirm.html';
var PAGE_THANKS				= 'thanks.html';
var PAGE_FULLSHOP			= 'fullshop.html';
var PAGES_UPGRADE			= 'upgrade3.html';		// (all upgrade pages in /cgi-bin)
var PAGE_BUNDLE_CHECKOUT	= 'checkout-bundle.html';
var PAGE_BUNDLE_CONFIRM		= 'confirm-bundle.html';
var PAGE_BUNDLE_THANKS		= 'thanks-bundle.html';

// for testing
var PAGE_UPGRADE_V1_3		= 'new-upgrade-v1-3.html';
var PAGE_UPGRADE_V2_3		= 'new-upgrade-v2-3.html';
var PAGE_UPGRADE_V3_DVB		= 'new-upgrade-v3-dvb.html';
var PAGE_UPGRADE_DVB		= 'new-upgrade-dvb.html';

// ============================================================================= //


// ============================================================================= //
// cart global pseudo-constants and variables:
// ============================================================================= //
var S_SEP							= '¦';	// seperates "product,quantity" pairs
var aryCart						= new Array();			// the shopping cart array
var iProduct					= 0;
var COOKIE_CART				= 'ch6cart';
var COOKIE_VISITED		= 'ch6lastPage';
var COOKIE_ACCESSORIES	= 'ssAccessories';
var COOKIE_SS_VERSION	= 'ssVersion';
var COOKIE_SS_CD			= 'ssCD';
var COOKIE_CHECKOUT		= 'ch6checkout';
var COOKIE_SS_CODE_SS	= 'ssCode';
var COOKIE_SS_CODE_DIVX	= 'ssCodeDivX';
var COOKIE_SS_CODE_ALT	= 'ssCodeAlt';
var COOKIE_AFFILIATE	= 'ssAffiliateID';
//var CURRENCY					= "€";
var CURRENCY		= '£';
//var CURRENCY		= "&euro;";
// ============================================================================= //


// ============================================================================= //
// inventory-handling constants:
// ============================================================================= //
var I_CODE = 0, I_NAME = 1, I_DESC = 2, I_PRICE = 3, I_USED = 4;
// ============================================================================= //


// ============================================================================= //
// inventory-handling functions:
// ============================================================================= //
function getCode(iIndex) { return getItem(iIndex,I_CODE); }
function getName(iIndex) { return getItem(iIndex,I_NAME); }
function getDescription(iIndex) { return getItem(iIndex,I_DESC); }
function getPrice(iIndex) { return getItem(iIndex,I_PRICE); }
function isUsed(iIndex) { return getItem(iIndex,I_USED); }
function getItem(iIndex,iField) { 
	var aryTemp = aryProducts[iIndex].split(',');
	return aryTemp[iField];
}
// ============================================================================= //


// ============================================================================= //
// purpose:			convert the contents of an HTML form-field into
//							a JavaScript array
// params-in:
//	oElement		form element		hidden form-field
// param-out:
//							array						array of product,quantity pairs
// ============================================================================= //
function htmlToArray(oElement) {
	var aryRows = oElement.value.split(S_SEP);	// array of product,quantity pairs
	return aryRows;
}

// ============================================================================= //
// purpose:			convert the contents of a cookie into a Javascript array
// params-in:
//							void
// param-out:
//	aryIn				array						array of product,quantity pairs
// ============================================================================= //
function cookieToArray()	{
	var sCart = getCookie(COOKIE_CART);
	var aryReturn = new Array();
	if (sCart != null && sCart.length > 0) {
		var aryTemp = sCart.split('=');
		if (aryTemp[0] != null && aryTemp[0].length > 0) {
			aryReturn = aryTemp[0].split(S_SEP);
		}
	}
	return aryReturn;
}

// ============================================================================= //
// purpose:			convert the contents of a Javascript array into
//							an HTML form-field
// params-in:
//	aryIn				array						array of product,quantity pairs
//	oElement		form element		field to place "array" into
// param-out:
//							void
// ============================================================================= //
function arrayToHTML(aryIn, oElement) {
	var sResult = '';
	for (var i = 0; i < aryIn.length; i++) {
		var sRow = aryIn[i];
		if (sRow != "") { sResult += sRow + S_SEP; }
	}
	oElement.value = sResult;
}

// ============================================================================= //
// purpose:			convert the contents of a Javascript array into a cookie
// params-in:
//	aryIn				array						array of product,quantity pairs
// param-out:
//							void
// ============================================================================= //
function arrayToCookie(aryIn)	{
	var sResult = '';
	for (var i = 0; i < aryIn.length; i++) {
		var sRow = aryIn[i];
		if (sRow != "") {
			if (i < (aryIn.length - 1)) {
				sResult += sRow + S_SEP;
			} else {
				sResult += sRow;
			}
		}
	}
	// cookie will expire in 1 month's time:
	var expDate = new Date();
	if (expDate.getMonth() < 11) {
		// month >= 0 && month < 11 - increment the month:
		expDate.setMonth(expDate.getMonth() + 1);
	} else {
		// month == 11 (December) - set month to 0 (January) and increment the year:
		expDate.setMonth(0);
		expDate.setYear(expDate.getYear() + 1);
	}
	setCookie(COOKIE_CART, sResult);
}

// ============================================================================= //
// purpose:			add a product to the cart
// params-in:
//	iProduct		integer					ID of product
//	aryCart			array						shopping-cart array
// param-out:
//							void
// ============================================================================= //
function addToCart(iProduct, aryCart) {
	var bAdded = false;
	// if the product is already in the cart, increment the quantity:
	for (var i = 0; i < aryCart.length; i++) {
		var sRow = aryCart[i];
		var iPos = sRow.indexOf(",");
		var product = sRow.slice(0,iPos);
		var quantity = sRow.slice(iPos+1,sRow.length);
		if (iProduct == product) {
			quantity = (quantity*1) + 1;			// 1+1=2, not 11!!!
			sRow = product + ',' + quantity;
			aryCart[i] = sRow;
			bAdded = true;
		}
	}
	// if the product isn't in the cart, add it
	if (!bAdded) {
		var sRow = eval('"' + iProduct + ',1"');
		var iTemp = aryCart.push(sRow);
	}
	// refresh cart and persist:
	var sLocation = window.location.href;
	if (sLocation.indexOf(PAGE_CART) >= 0) {
		refreshCart(aryCart);
	} else {
		updateHTMLCart(aryCart);
	}
	arrayToCookie(aryCart);
	return aryCart;
}

// ============================================================================= //
// purpose:			update the quantity of a product already in the cart
// params-in:
//	iProduct		integer					ID of product
//	iQuantity		integer					quantity
//	aryCart			array						shopping-cart array
// param-out:
//							void
// ============================================================================= //
function updateCart(iProduct, iQuantity, aryCart) {
	if (iQuantity > 0) {
		for (var i = 0; i < aryCart.length; i++) {
			var sRow = aryCart[i];
			var iPos = sRow.indexOf(',');
			var product = sRow.slice(0,iPos);
			if (iProduct == product) {
				var quantity = iQuantity;
				sRow = product + ',' + quantity;
				aryCart[i] = sRow;
			}
		}
	} else {
		aryCart = removeFromCart(iProduct, aryCart);
	}
	// refresh cart and persist:
	var sLocation = window.location.href;
	if (sLocation.indexOf(PAGE_CART) >= 0) {
		refreshCart(aryCart);
	} else {
		updateHTMLCart(aryCart);
	}
	arrayToCookie(aryCart);
	return aryCart;
}

// ============================================================================= //
// purpose:			remove a product from the cart
// params-in:
//	iProduct		integer					ID of product
//	aryCart			array						shopping-cart array
// param-out:
//							void
// ============================================================================= //
function removeFromCart(iProduct, aryCart) {
	// only bother removing it if it exists...!:
	if (existsIn(iProduct, aryCart)) {
		var aryNewCart = new Array(aryCart.length - 1);
		var j = 0;
		for (var i = 0; i < aryCart.length; i++) {
			var sRow = aryCart[i];
			var iPos = sRow.indexOf(',');
			var product = sRow.slice(0,iPos);
			// copy the p,q pair to the new array *IIF* the product
			// isn't the the product specified for removal:
			if (iProduct != product) {
				aryNewCart[j++] = aryCart[i];
			}
		}
		aryCart = aryNewCart;
	}
	// refresh cart and persist:
	var sLocation = window.location.href;
	if (sLocation.indexOf(PAGE_CART) >= 0) {
		refreshCart(aryCart);
	} else {
		updateHTMLCart(aryCart);
	}
	arrayToCookie(aryCart);
	return aryCart;
}

// ============================================================================= //
// purpose:   empty the cart completely
// ============================================================================= //
function emptyCart(aryCart)	{
	// 1. aryCart:
	// loop from end to start, deleting rows from the array:
	// (no good reason for end-to-start, just "feels" better this way ;-)
	for (var i = aryCart.length - 1; i >= 0; i--) {
		var temp = aryCart.pop();
	}
	// 2. cookie:
	document.cookie = COOKIE_CART + '=';
	// 3. HTML cart:
	updateHTMLCart(aryCart);
}

// ============================================================================= //
// purpose:			checks whether a product exists in the cart
// params-in:
//	iID					integer					ID of product
//	aryIn				array						shopping-cart array
// param-out:
//							boolean					true if product exists, else false
// ============================================================================= //
function existsIn(iID, aryIn) {
	var bReturn = false;
	for (var i = 0; i < aryIn.length; i++) {
		var sRow = aryIn[i];
		var iPos = sRow.indexOf(',');
		var product = sRow.slice(0,iPos);
		if (iID == product) { bReturn = true; }
	}
	return bReturn;
}

// ============================================================================= //
// purpose:			for a given row ("a cart item"), returns the product ID
// params-in:
//	iID					integer					ID of row
//	aryIn				array						shopping-cart array
// param-out:
//							integer					ID of product
// ============================================================================= //
function getProduct(iID, aryCart) {
	var sRow = aryCart[iID];
	var iPos = sRow.indexOf(',');
	var product = 0;
	if (iPos > 0) {
		product = sRow.slice(0,iPos);
	}
	return product;
}

// ============================================================================= //
// purpose:			for a given row ("a cart item"), returns the quantity
// params-in:
//	iID					integer					ID of row
//	aryIn				array						shopping-cart array
// param-out:
//							integer					quantity
// ============================================================================= //
function getQuantity(iID, aryCart) {
	var sRow = aryCart[iID];
	var iPos = sRow.indexOf(',');
	var quantity = sRow.slice(iPos+1,sRow.length);
	return quantity;
}

// ============================================================================= //
// purpose:		adds products to the cart, from the querystring:
// ============================================================================= //
function checkQS(qs) {
	if (qs != '') {
		qs = qs.substr(1, qs.length-1);	// remove the "?" prefix
		var aryQS = qs.split('=');
		var name = aryQS[0];
		var value = aryQS[1];
		if (name == 'product') {
			aryCart = addToCart(value, aryCart);
			
		}
	}
}

// ============================================================================= //
// purpose:		called "onLoad"
// ============================================================================= //
function initCart()	{
	checkAffiliateID(location.search);
	aryCart = cookieToArray();
	updateHTMLCart(aryCart);
	var sLocation = window.location.href;
	if (sLocation.indexOf(PAGE_SOFTWARE) >= 0) {
		drawPrices();
		showNavForm();
	}
	if (sLocation.indexOf(PAGE_DIVX) >= 0) {
		drawPrices();
		showNavForm();
	}
	if (sLocation.indexOf(PAGE_REMOTE) >= 0) {
		drawPrices();
		showNavForm();
	}
	if (sLocation.indexOf(PAGE_UPGRADE) >= 0) {
		// do nowt? (no cart on this page)
	}
	if (sLocation.indexOf(PAGE_UPGRADE2) >= 0) {
		drawUpgradePrices();
		showNavForm();
	}
	if (sLocation.indexOf(PAGE_ACCESSORIES) >= 0) {
		drawPrices();
		showNavForm();
	}
	if (sLocation.indexOf(PAGE_CART) >= 0) {
		checkQS(location.search);
		refreshCart(aryCart);
		showNavForm();
	}
	if (sLocation.indexOf(PAGE_CHECKOUT) >= 0) {
		refreshCartCost(aryCart);
		refreshCartSummary(aryCart);
		redrawSelectMonth('CCExpMonth', ' STYLE="VISIBILITY: visible" TABINDEX="22" CLASS="fields"');
		redrawSelectYear('CCExpYear', ' STYLE="VISIBILITY: visible" TABINDEX="23" CLASS="fields"', true);

		// added 20041101,jn:
		redrawSelectMonth('CCValidMonth', ' STYLE="VISIBILITY: visible" TABINDEX="24" CLASS="fields"');
		redrawSelectYear('CCValidYear', ' STYLE="VISIBILITY: visible" TABINDEX="25" CLASS="fields"', false);
		// :added 20041101,jn

		ccChanged(document.frmCheckout.CCType);
		
		// added 20041101,jn:
		unescapeForm(document.frmCheckout);
		// :added 20041101,jn
		
		showNavForm();
	}
	if (sLocation.indexOf(PAGE_CONFIRM) >= 0) {
		drawConfirmation();
		showNavForm();
	}
	if (sLocation.indexOf(PAGE_THANKS) >= 0) {
		clearCookies();
	}
	if (sLocation.indexOf(PAGE_BUNDLE_THANKS) >= 0) {
		clearCookies();
	}
	if (sLocation.indexOf(PAGE_FULLSHOP) >= 0) {
		drawPrices();
	}
	if (sLocation.indexOf(PAGES_UPGRADE) >= 0) {
		drawPrices();
		showNavForm();
	}
	if (sLocation.indexOf(PAGE_UPGRADE_V1_3) >= 0) {
		drawPrices();
		showNavForm();
	}
	if (sLocation.indexOf(PAGE_UPGRADE_V2_3) >= 0) {
		drawPrices();
		showNavForm();
	}
	if (sLocation.indexOf(PAGE_UPGRADE_V3_DVB) >= 0) {
		drawPrices();
		showNavForm();
	}
	if (sLocation.indexOf(PAGE_UPGRADE_DVB) >= 0) {
		drawPrices();
		showNavForm();
	}
	if (sLocation.indexOf(PAGE_BUNDLE_CHECKOUT) >= 0) {
		redrawSelectMonth('CCExpMonth', ' STYLE="VISIBILITY: visible" TABINDEX="22" CLASS="fields"');
		redrawSelectYear('CCExpYear', ' STYLE="VISIBILITY: visible" TABINDEX="23" CLASS="fields"', true);

		// added 20041101,jn:
		redrawSelectMonth('CCValidMonth', ' STYLE="VISIBILITY: visible" TABINDEX="24" CLASS="fields"');
		redrawSelectYear('CCValidYear', ' STYLE="VISIBILITY: visible" TABINDEX="25" CLASS="fields"', false);
		// :added 20041101,jn
		
		ccChanged(document.frmCheckout.CCType);
		drawBundle();
		showNavForm();
		var oEl = document.getElementById('ch6prev');
		oEl.setAttribute('STYLE', 'visibility: hidden; width: 0;');
	}
	if (sLocation.indexOf(PAGE_BUNDLE_CONFIRM) >= 0) {
		drawConfirmationBundle();
		showNavForm();
	}
}

// ============================================================================= //
// loop thru' all (both!) "ch6autoUpgradePrice...", replace content with price:
// [NB. basically identical to "drawPrices()", but...
// (a) allow for upgrades (cheaper to go 2->3, than 1->3, for example)
// (b) and if we're upgrading from v.3, hide the v.3 option]
// ============================================================================= //
function drawUpgradePrices() {
	var i = 1;
	var sID = 'ch6autoUpgradePrice' + i;
	var oEl = document.getElementById(sID);
	while(oEl != null) {
		var sProductID = oEl.innerHTML;
		var sRealID = 0;
		var version = getCookie(COOKIE_SS_VERSION);
		if (version == '3') {
			if (sProductID == 'dvb') {
				sRealID = 16;
			} else if (sProductID == 'v3') {
				sRealID = -1;
			}
		} else if (version == '2') {
			if (sProductID == 'dvb') {
				sRealID = 17;
			} else if (sProductID == 'v3') {
				sRealID = 19;
			}
		} else if (version == '1') {
			if (sProductID == 'dvb') {
				sRealID = 18;
			} else if (sProductID == 'v3') {
				sRealID = 20;
			}
		}
		if (sRealID != -1) {
			var sPrice = getPrice(sRealID, aryCart);
			oEl.innerHTML = CURRENCY + sPrice;
		} else {
			// you can't upgrade from v.3 to v.3, so hide the v.3 option!:
			oEl = document.getElementById('ssV3row1');	
			oEl.setAttribute('style','display: none;');
			oEl = document.getElementById('ssV3row2');	
			oEl.setAttribute('style','display: none;');
			oEl = document.getElementById('ssV3row3');	
			oEl.setAttribute('style','display: none;');
			oEl = document.getElementById('ssV3row4');	
			oEl.setAttribute('style','display: none;');
		}
		sID = 'ch6autoUpgradePrice' + ++i;
		oEl = document.getElementById(sID);
	}
}

// ============================================================================= //
// purpose:		provide dynamic navigation on the client-side.
// param-out:
//						boolean.
// ============================================================================= //
function prevPage() {
	// if we're at the cart, and...
	if (location.href.indexOf(PAGE_CART) >= 0) {
		// ...if we've come from one of the upgrade pages, then go back there:
		if (location.search.indexOf('product=') >= 0) history.go(-1);		// this *actually* takes us to shop.htm.
	}
	var lastPage = popLastVisitedPage();
	if (lastPage != '') {
		if (lastPage != PAGE_BUNDLE_CHECKOUT) {	// normally: return to previous page
			window.location.href = SITE_SHOP + lastPage;
		} else {						// confirm-bundle.htm: append Bundle code to QS, return to previous page
			window.location.href = SITE_SHOP + lastPage + '?Bundle=' + document.frmConfirm.Bundle.value;
		}
	} else {
		window.location.href = SITE_SHOP + PAGE_START;
	}
}

function nextPageFromStart() {
		addVisitedPage(PAGE_START);
		return true;
}

// ============================================================================= //
// disables the "checkout" button, and redirects to checkout.htm:
// ============================================================================= //
function lockCheckout() {
	var oEl = document.getElementById('ch6btnCheckout');
	if (oEl.className == 'enabledButton') {
		oEl.className = 'disabledButton';
		addVisitedPage(PAGE_CART);
		window.location.href = SECURE_SITE + SHOP + PAGE_CHECKOUT;
	} else {
		alert('Proceding to checkout...');	
	}
}

// ============================================================================= //
// locks the "confirm" button on checkout.htm, and redirects to confirm.htm:
// ============================================================================= //
function lockConfirm() {
	var oEl = document.getElementById('ch6btnPay');
	if (oEl.className == 'enabledButton') {
		//setCountryDropDowns(3);	// set *both* drop-downs	
		onCountryChange();
		if (validateCheckoutForm(document.forms['frmCheckout'])) {
			oEl.className = 'disabledButton';
			addVisitedPage(PAGE_CHECKOUT);
			addCheckoutDetails();
			// parse input, escaping dodgy characters:
			parseFormForGET(document.frmCheckout);
			window.location.href = SECURE_SITE + SHOP + PAGE_CONFIRM;
		}
	} else {
		alert('Proceding to final confirmation...');	
	}
}

// ============================================================================= //
// locks the "pay" button on confirm.htm, and redirects to online payment service
// (eg. Secpay):
// ============================================================================= //
function lockPay() {
	var oEl = document.getElementById('ch6btnPay');
	if (oEl.className == 'enabledButton') {
		oEl.className = 'disabledButton';
		addVisitedPage(PAGE_CONFIRM);
		// just warn the user about refreshing their browser
		alert('This may take a little while. During this time do not refresh your browser or click the back button.\n\nClick OK to continue.');
		// submit the form:
		document.frmConfirm.submit();
	} else {
		alert('Proceding to credit-card payment...');	
	}
}

// ============================================================================= //
// locks the "next" button on upgrade.htm, and redirects to /cgi-bin/upgrade.cgi:
// ============================================================================= //
function lockUpgrade() {
	var oEl = document.getElementById('ch6btnNext');
	if (oEl.className == 'enabledButton') {
		oEl.className = 'disabledButton';
		addVisitedPage(PAGE_UPGRADE);
		// submit the form:
		document.upgradechecker.submit();
	} else {
		alert('Proceding to upgrade-checker...');	
	}
	
}

// ============================================================================= //
// purpose:		provide dynamic navigation on the client-side.
// status:		untested
// param-out:
//						boolean.
// ============================================================================= //
function nextPage() {
	var sLocation = window.location.href;
	if (sLocation.indexOf(PAGE_START) >= 0) {
		// no logic: there's no "next" button on this page,
		// navigation is controlled by hyperlinks.
		return false;
	} else if (sLocation.indexOf(PAGE_SOFTWARE) >= 0) {
		addVisitedPage(PAGE_SOFTWARE);
		addSelectedProductsToCart(PAGE_SOFTWARE);
		//window.location.href = SITE_SHOP + PAGE_DIVX;
		//X10 out of stock//window.location.href = SITE_SHOP + PAGE_REMOTE;
		if (getCookie('ssAccessories') == 'true') {
			window.location.href = SITE_SHOP + PAGE_ACCESSORIES;
		} else {
			window.location.href = SITE_SHOP + PAGE_CART;
		}
		return true;
	} else if (sLocation.indexOf(PAGE_UPGRADE) >= 0) {
		addVisitedPage(PAGE_UPGRADE);
		return lockUpgrade();
	} else if (sLocation.indexOf(PAGE_UPGRADE2) >= 0) {
		addVisitedPage(PAGE_UPGRADE2);
		addSelectedProductsToCart(PAGE_UPGRADE2);
		//window.location.href = SITE_SHOP + PAGE_DIVX;
		//X10 out of stock//window.location.href = SITE_SHOP + PAGE_REMOTE;
		if (getCookie('ssAccessories') == 'true') {
			window.location.href = SITE_SHOP + PAGE_ACCESSORIES;
		} else {
			window.location.href = SITE_SHOP + PAGE_CART;
		}
		return true;
	} else if (sLocation.indexOf(PAGE_DIVX) >= 0) {
		addVisitedPage(PAGE_DIVX);
		addSelectedProductsToCart(PAGE_DIVX);
		//X10 out of stock//window.location.href = SITE_SHOP + PAGE_REMOTE;
		if (getCookie('ssAccessories') == 'true') {
			window.location.href = SITE_SHOP + PAGE_ACCESSORIES;
		} else {
			window.location.href = SITE_SHOP + PAGE_CART;
		}
		return true;
	} else if (sLocation.indexOf(PAGE_REMOTE) >= 0) {
		addVisitedPage(PAGE_REMOTE);
		addSelectedProductsToCart(PAGE_REMOTE);
		if (getCookie('ssAccessories') == 'true') {
			window.location.href = SITE_SHOP + PAGE_ACCESSORIES;
		} else {
			window.location.href = SITE_SHOP + PAGE_CART;
		}
		return true;
	} else if (sLocation.indexOf(PAGE_ACCESSORIES) >= 0) {
		addVisitedPage(PAGE_ACCESSORIES);
		addSelectedProductsToCart(PAGE_ACCESSORIES);
		window.location.href = SITE_SHOP + PAGE_CART;
		return true;
	} else if (sLocation.indexOf(PAGE_CART) >= 0) {
		// lock the button (so it can't be pressed twice) and submit:
		return lockCheckout();
	} else if (sLocation.indexOf(PAGE_CHECKOUT) >= 0) {
		// lock the button (so it can't be pressed twice) and submit:
		return lockConfirm();
	} else if (sLocation.indexOf(PAGE_CONFIRM) >= 0) {
		// lock the button (so it can't be pressed twice) and submit:
		return lockPay();
	} else if (sLocation.indexOf(PAGE_FULLSHOP) >= 0) {
		addVisitedPage(PAGE_FULLSHOP);
		window.location.href = SITE_SHOP + PAGE_CART;
		return true;
	} else if (sLocation.indexOf(PAGES_UPGRADE) >= 0) {
		//addVisitedPage() - NO! If the user goes back from the cart,
		//     they should end up back at the start.
		addSelectedProductsToCart(PAGES_UPGRADE);
		var oForm = document.frmUpgrade;
		//if (oForm.radUpgrade1 != null || oForm.radUpgrade2 != null || oForm.radUpgrade3 != null) {
		//	window.location.href = SITE_SHOP + PAGE_DIVX;
		//} else {
		//	window.location.href = SITE_SHOP + PAGE_REMOTE;
		//}
		//X10 out of stock//window.location.href = SITE_SHOP + PAGE_REMOTE;
		if (getCookie('ssAccessories') == 'true') {
			window.location.href = SITE_SHOP + PAGE_ACCESSORIES;
		} else {
			window.location.href = SITE_SHOP + PAGE_CART;
		}
	} else if (sLocation.indexOf(PAGE_BUNDLE_CHECKOUT) >= 0) {
		addVisitedPage(PAGE_BUNDLE_CHECKOUT);
		return lockConfirmBundle();
	} else if (sLocation.indexOf(PAGE_BUNDLE_CONFIRM) >= 0) {
		addVisitedPage(PAGE_BUNDLE_CONFIRM);
		return lockPayBundle();
	}
}

// ============================================================================= //
// logic for product pages:
// ============================================================================= //
function addSelectedProductsToCart(sPage)	{
	switch (sPage) {
		case PAGE_SOFTWARE:
			var oForm = document.frmSoftware;
			if (oForm.radSoftware[0].checked) {
				aryCart = addToCart(14, aryCart);
			//} else if (oForm.radSoftware[1].checked) {				
			//	aryCart = addToCart(14, aryCart);
			} else if (oForm.radSoftware[1].checked) {				
				aryCart = addToCart(29, aryCart);
			}			
			break;
		case PAGE_UPGRADE:
			// no products to add
			break;
		case PAGE_UPGRADE2:
			var oForm = document.frmUpgrading;
			if (oForm.cbxCD.checked) {
				aryCart = addToCart(29, aryCart);
			}
			break;
		case PAGE_DIVX:
			var oForm = document.frmDivX;
			if (oForm.radDivX[0].checked) {
				aryCart = addToCart(2, aryCart);
			}
			break;
		case PAGE_REMOTE:
			var oForm = document.frmRemote;
			if (oForm.radRemote[0].checked) {
				aryCart = addToCart(13, aryCart);
			}
			break;
		case PAGE_ACCESSORIES:
			var oForm = document.frmAccessories;
			if (oForm.radAccessories[0].checked) {
				aryCart = addToCart(39, aryCart);
//			} else if (oForm.radAccessories[1].checked) {
//				aryCart = addToCart(24, aryCart);
			} else if (oForm.radAccessories[1].checked) {
				aryCart = addToCart(25, aryCart);
			} else if (oForm.radAccessories[2].checked) {
//				aryCart = addToCart(26, aryCart);
//			} else if (oForm.radAccessories[3].checked) {
				aryCart = addToCart(12, aryCart);
			}
			break;
		case PAGES_UPGRADE:
			var oForm = document.frmUpgrade;
			if (oForm.radUpgrade1 != null) {
				if (oForm.radUpgrade1.checked) {
					aryCart = addToCart(18, aryCart);
				//} else if (oForm.radUpgrade1[1].checked) {
				//	aryCart = addToCart(20, aryCart);
				}
			} else if (oForm.radUpgrade2 != null) {
				if (oForm.radUpgrade2.checked) {
					aryCart = addToCart(17, aryCart);
				//} else if (oForm.radUpgrade2[1].checked) {
				//	aryCart = addToCart(19, aryCart);
				}
			} else if (oForm.radUpgrade3 != null) {
				if (oForm.radUpgrade3.checked) {
					aryCart = addToCart(16, aryCart);
				}
			}
		default:
			break;
	}
}

// ============================================================================= //
// "submits" to client-side via cookie!
// ============================================================================= //
function addCheckoutDetails() {
	var sElements = '';	// string containing form elements
	var oForm = document.forms['frmCheckout'];
	var bNoShip = false;
	if (document.frmCheckout.ShipFirstName.value == '' && document.frmCheckout.ShipLastName.value == '') bNoShip = true;
	// handle form-fields:
	for (var i = 0; i < oForm.length; i++) {
		var sValue = oForm.elements[i].value;
		// temporarily replace linebreaks:
		while (sValue.indexOf('\n') >= 0) {
			sValue = sValue.replace(/\n/, '##NL##');
		}
		// append to sElements:
		sElements += oForm.elements[i].name + '=' + sValue + '\n';
	}
	
	setCookie(COOKIE_CHECKOUT, sElements);
}

// ============================================================================= //
// checkout.htm CC-Type onChange event-handler:
// ============================================================================= //
function ccChanged(oEl) {
	var cc = oEl[oEl.selectedIndex].value;
	var oElIssue = document.getElementById('ch6switchIssue');
	var oElLabel = document.getElementById('ch6switchLabel');
	if (cc == 'Switch') {
		oElIssue.className = 'fields';
		oElLabel.className = 'enabledLabel';
	} else {
		oElIssue.className = 'disabledField';
		oElLabel.className = 'disabledLabel';
	}
}

// ============================================================================= //
// ch6cart Presentation logic:
// ============================================================================= //


// ============================================================================= //
// draw large cart, ie. on cart.htm and confirm.htm:
// ============================================================================= //
function refreshCart(aryCart) {
	// prepare for cart rendering:
	var quantity = 0;
	for (var i = 0; i < aryCart.length; i++) {
		quantity += (1*getQuantity(i,aryCart));
	}
	if (quantity == 0) {
		alert("The shopping cart is empty.  Returning to Showshifter Shop...");
		window.location.href = SITE_SHOP + PAGE_INTRO;
	}
	// render the cart:
	var oEl = document.getElementById('ch6basket');
	oEl.innerHTML = '';
	var oTable = document.createElement("TABLE");
	oTable.setAttribute('style', 'width: 100%;');
	var oTHead = document.createElement("THEAD");
	var oTBody = document.createElement("TBODY");
	var oTR = document.createElement("TR");
	var sText = '';	// NB. "sText" a var for text nodes.  Should be renamed to "oText" [jn,29-01-2004]
	var sClass = '';
	if (isIE()) {
		sClass = 'className';
	} else {
		sClass = 'class';
	}
	// create headers
	// - Name
	sText = document.createTextNode('Name');		
	var oTH = document.createElement("TH");
	oTH.appendChild(sText);
	oTH.setAttribute(sClass,'ch6cartTableHeader');
	oTR.appendChild(oTH);
	// - Price
	sText = document.createTextNode('Price');		
	var oTH = document.createElement("TH");
	oTH.appendChild(sText);
	oTH.setAttribute(sClass,'ch6cartTableHeader');
	oTH.setAttribute('style','text-align: right;');	// NB. this doesn't work - or doesn't seem to work - in IE6 [jn,29-01-2004]
	oTR.appendChild(oTH);

//	// - Delivery Method
//	sText = document.createTextNode('Delivery Method');		
//	var oTH = document.createElement("TH");
//	oTH.appendChild(sText);
//	oTH.setAttribute(sClass,'ch6cartTableHeader');
//	oTR.appendChild(oTH);

	// - Quantity
	sText = document.createTextNode('Quantity');		
	var oTH = document.createElement("TH");
	oTH.appendChild(sText);
	oTH.setAttribute(sClass,'ch6cartTableHeader');
	oTH.setAttribute('style','text-align: right;');
	oTR.appendChild(oTH);
	// - Total
	sText = document.createTextNode('Total');		
	var oTH = document.createElement("TH");
	oTH.appendChild(sText);
	oTH.setAttribute(sClass,'ch6cartTableHeader');
	oTH.setAttribute('style','text-align: right;');
	oTR.appendChild(oTH);
	// - Control
	if (!(location.href.indexOf(PAGE_CONFIRM) >= 0)) {
		var oTH = document.createElement("TH");
		oTH.innerHTML = '&nbsp;';
		oTH.setAttribute(sClass,'ch6cartTableHeader');
		oTH.setAttribute('style','text-align: right;');
		oTR.appendChild(oTH);
	}
	// add header-row to table:
	oTHead.appendChild(oTR);
	oTable.appendChild(oTHead);
	// loop thru' items in cart:
	for (var i = 0; i < aryCart.length; i++) {
		oTR = document.createElement("TR");
		// loop thru' fields: "name", "price", "description", "quantity", "total price", "control":
		for (var j = 0; j < 5; j++) {
			var oTD = document.createElement("TD");
			oTD.setAttribute('VALIGN','TOP');
			var iProduct = getProduct(i, aryCart);
			var quantity = getQuantity(i, aryCart);
			var price = roundNumber(getPrice(iProduct));
			var subtotal = roundNumber(price * quantity);
			subtotal = roundNumber(subtotal);
			// create TDs/fields:
			var oControl;
			var oSpan;
			switch (j) {
				case 0:
					sText = document.createTextNode(getName(iProduct, aryCart));
					break;
				case 1:
					var price = roundNumber(getPrice(iProduct, aryCart));
					if (!isNaN(price)) {
						sText = document.createTextNode(CURRENCY + price);
					} else {
						sText = document.createTextNode('error: ' + price);
					}
					break;
//				case 2:
//					sText = document.createTextNode(getDescription(iProduct, aryCart));
//					break;
				case 2:
					var oSpanRow = document.createElement('DIV');
					oSpanRow.setAttribute('STYLE','width: 100px;');
					
					if (!(location.href.indexOf(PAGE_CONFIRM) >= 0)) {
						oSpanCtrl = document.createElement('SPAN');
						oSpanCtrl.setAttribute('STYLE','float: left;');
						// + : increase quantity:
						oControl = document.createElement('A');
						oControl.setAttribute('href','javascript:aryCart=addToCart('+iProduct+',aryCart);void(0);');
						oControl.setAttribute('title','Add one '+getName(iProduct,aryCart)+' to your shopping-cart');
						oControl.setAttribute('style','text-decoration: none;');
						if (!isIE()) {
							var oImage = document.createElement('IMG');
							sImage = 'add' + i;
							oImage.setAttribute('ID',sImage);
							oControl.appendChild(oImage);
						} else {
							var sText = '<IMG SRC="../images/butt_add.gif" BORDER="0" WIDTH="12" HEIGHT="12" />';
							oControl.innerHTML = sText;
						}
						oSpanCtrl.appendChild(oControl);
						
						oSpan = document.createElement('SPAN');
						oSpan.innerHTML = '&nbsp;';
						oSpanCtrl.appendChild(oSpan);
						
						// - : decrease quantity:
						oControl = document.createElement('A');
						if (quantity > 1) {
							oControl.setAttribute('href','javascript:aryCart=updateCart('+iProduct+','+((1*quantity)-1)+',aryCart);void(0);');
							oControl.setAttribute('title','Remove one '+getName(iProduct,aryCart)+' from your shopping-cart');
						} else {
							oControl.setAttribute('href','javascript:void(0);');
							oControl.setAttribute('title','Only one '+getName(iProduct,aryCart)+' left in your shopping-cart');
						}
						oControl.setAttribute('style','text-decoration: none;');
						if (!isIE()) {
							var oImage = document.createElement('IMG');
							sImage = 'sub' + i;
							oImage.setAttribute('ID',sImage);
							oControl.appendChild(oImage);
						} else {
							var sText = '<IMG SRC="../images/butt_subtract.gif" BORDER="0" WIDTH="12" HEIGHT="12" />';
							oControl.innerHTML = sText;
						}
						oSpanCtrl.appendChild(oControl);
						
						oSpanRow.appendChild(oSpanCtrl);
						
						if (isIE()) {
							oSpan = document.createElement('SPAN');
							oSpan.innerHTML = '&nbsp;';
							oSpanRow.appendChild(oSpan);
						}
					}
					
					oSpan = document.createElement('SPAN');
					oSpan.setAttribute('STYLE','float: right;');
					sText = document.createTextNode(getQuantity(i, aryCart));
					oSpan.appendChild(sText);
					
					oSpanRow.appendChild(oSpan);
					
					oTD.appendChild(oSpanRow);
					break;
				case 3:
					if (!isNaN(subtotal)) {
						sText = document.createTextNode(CURRENCY + subtotal);
					} else {
						sText = document.createTextNode('error: ' + subtotal);
					}
					break;
				case 4:
					if (!(location.href.indexOf(PAGE_CONFIRM) >= 0)) {
						// -- : delete from cart
						oControl = document.createElement('A');
						oControl.setAttribute('href','javascript:aryCart=removeFromCart('+iProduct+',aryCart);void(0);');
						oControl.setAttribute('title','Remove all '+getName(iProduct,aryCart)+'s from your shopping-cart');
						oControl.setAttribute('style','text-decoration: none;');
						if (!isIE()) {
							var oImage = document.createElement('IMG');
							sImage = 'rem' + i;
							oImage.setAttribute('ID',sImage);
							oControl.appendChild(oImage);
						} else {
							var sText = '<IMG SRC="../images/butt_remove.gif" BORDER="0" WIDTH="49" HEIGHT="17" />';
							oControl.innerHTML = sText;
						}
						oTD.appendChild(oControl);
					}
					break;
			}
			if (sText.length == 0) sText = '&nbsp;';
			// don't appendChild on j==3,5 : it'll already have been done:
			if (j != 2 && j != 4) {					
				var oSpan = document.createElement('SPAN');
				oSpan.setAttribute(sClass,'ie6fix');
				oSpan.appendChild(sText);
				oTD.appendChild(oSpan);
			}
			// edit TDs/fields:
			switch (j) {
				case 0:
					oTD.setAttribute(sClass,'ch6cartItemName');
					break;
				case 1:
					oTD.setAttribute(sClass,'ch6cartItemPrice');
					break;
//				case 2:
//					oTD.setAttribute(sClass,'ch6cartItemDescription');
//					break;
				case 2:
					oTD.setAttribute(sClass,'ch6cartItemQuantity');
					break;
				case 3:
					oTD.setAttribute(sClass,'ch6cartItemTotal');
					break;
				case 4:
					if (!(location.href.indexOf(PAGE_CONFIRM) >= 0)) {
						oTD.setAttribute(sClass,'ch6cartItemControl');
					}
					break;
			}
			// don't do this IIF we're on confirm.htm AND it's case 5 (control column):
			if (!((location.href.indexOf(PAGE_CONFIRM) >= 0) && (j == 4))) {
				oTR.appendChild(oTD);
			}
		}
		oTBody.appendChild(oTR);
	}
	oTable.appendChild(oTBody);
	oTable.setAttribute('ID', 'ch6cartTable');
	oEl.appendChild(oTable);
	
	// preload the images used for cart control:
	var oImageAdd = new Image();
	oImageAdd.src = '../images/butt_add.gif';
	oImageAdd.border = 0;
	var oImageSub = new Image();
	oImageSub.src = '../images/butt_subtract.gif';
	oImageSub.border = 0;
	var oImageRem = new Image();
	oImageRem.src = '../images/butt_remove.gif';
	oImageRem.border = 0;
	var sImage = '';
	
	// post-render, display the images:
	renderControls('add',oImageAdd);
	renderControls('sub',oImageSub);
	renderControls('rem',oImageRem);
	
	// finally...:
	refreshCartSummary(aryCart);
	refreshCartCost(aryCart);
	// and if we're on confirm.htm, display VAT:
	if (window.location.href.indexOf(PAGE_CONFIRM) >= 0) {
		refreshCartVAT(aryCart);
		refreshCartTotal(aryCart);
	}
}

// this function relies upon being on confirm.htm:
function refreshCartVAT(aryCart) {
	var total = getCartCost(aryCart);
	var oEl = document.getElementById('ch6vatValue');
	var bError = false;
	if (total == null) bError = true;
	if (!bError) {
		total = getVAT(total);
		total = roundNumber(total);
		oEl.innerHTML = CURRENCY + total;
	} else {
		oEl.innerHTML = 'error';
		oEl.className = 'anError';
	}
}
// this function relies upon being on confirm.htm:
function refreshCartTotal(aryCart) {
	var total = getCartCost(aryCart);
	var oEl = document.getElementById('ch6totalValue');
	var bError = false;
	if (total == null) bError = true;
	if (!bError) {
		total += getVAT(total);
		total = roundNumber(total);
		oEl.innerHTML = CURRENCY + total;
	} else {
		oEl.innerHTML = 'error';
		oEl.className = 'anError';
	}
}
// this function relies upon being on page:confirm.htm:
function getVAT(amount) {
	var sEU = 'AustriaBelgiumCyprusCzech RepublicDenmarkEstoniaFinlandFranceGermanyGreeceHungaryIrelandItalyLatviaLithuaniaLuxembourgMaltaNetherlandsPolandPortugalSlovakiaSloveniaSpainSwedenUnited Kingdom';
	var sCountry = document.frmConfirm.ShipCountry.value;
	if (sCountry == 'USA' || sCountry == '') {
		sCountry = document.frmConfirm.BillCountry.value;
	}
	// check whether sCountry is contained in the EU country list:
	if (sEU.indexOf(sCountry) >= 0) {
		return amount * 0.175;
	} else {
		return 0;
	}
}

// ============================================================================= //
// render DHTML controls on the large cart:
// ============================================================================= //
function renderControls(sCtrl,oImg) {
	var i = 0;
	var bStop = false;
	do {	
		sImage = sCtrl + i++;
		var oImage = document.images[sImage];
		if (oImage != null) {
			oImage.src = oImg.src;
			oImage.border = 0;
		} else {
			bStop = true
		}
	} while (!bStop);
}

// ============================================================================= //
// draw the value of the large cart:
// ============================================================================= //
function refreshCartCost(aryCart) {
	var total = getCartCost(aryCart);
	var oEl = document.getElementById('ch6basketValue');
	var bError = false;
	if (total == null) bError = true;
	if (!bError) {
		total = roundNumber(total);
		oEl.innerHTML = CURRENCY + total;
	} else {
		oEl.innerHTML = 'error';
		oEl.className = 'anError';
	}
}

// MOVE: business logic, not presentation tier:
// ============================================================================= //
// returns the total value of the items in the cart:
// ============================================================================= //
function getCartCost(aryCart) {
	var total = 0;
	var bError = false;
	for (var i = 0; i < aryCart.length; i++) {
		var product = getProduct(i, aryCart);
		var quantity = getQuantity(i, aryCart);
		var price = getPrice(product);
		var subtotal = price * quantity;
		if (!isNaN(subtotal)) {
			total += subtotal;
		} else {
			bError = true;
		}
	}
	if (!bError) {
		return total;
	} else {
		return null;
	}
}

// ============================================================================= //
// draw the number of items of the large cart:
// ============================================================================= //
function refreshCartSummary(aryCart) {
	var quantity = 0;
	for (var i = 0; i < aryCart.length; i++) {
		quantity += (1*getQuantity(i,aryCart));
	}
	var oEl = document.getElementById('ch6basketSummary');
	oEl.innerHTML = quantity;
}


// ============================================================================= //
// created:		30-01-2004
// purpose:		update the HTML-representation of the mini shopping-cart
// tier:			PRESENTATION
// requirements:
//						a <DIV> or <SPAN> with ID="ssCart"
// ============================================================================= //
function updateHTMLCart(aryCart) {
	var sCart = '';
	for (var i = 0; i < aryCart.length; i++) {
		var iProduct = getProduct(i, aryCart);
		if (iProduct != null && iProduct != '') {
			var sProduct = getName(iProduct);
			var sQuantity = getQuantity(i, aryCart);
			sCart += '<DIV CLASS=\"ch6cartItem\"'
			if (i > 0) {
				sCart += ' STYLE=\"border-top: 1px dotted #CCCCCC;\"'
			}
			sCart += '>' +
					'<SPAN CLASS=\"ch6cartItemRow\">' + sProduct + '</SPAN>' +
					'<SPAN CLASS=\"ch6cartItemRow\">' +
					'<SPAN CLASS=\"ch6cartItemQty\">Quantity ' + sQuantity + '</SPAN>' +
					'<SPAN CLASS=\"ch6cartItemCtrl\">' +
					'<A HREF=\"#\" onClick=\"javascript:aryCart=addToCart(' + iProduct + ',aryCart);return false;\" ' +
					'TITLE=\"Add one ' + sProduct + ' to your shopping-cart\">' +
					'<IMG SRC="../images/butt_add.gif" BORDER="0" HEIGHT=\"12\" WIDTH=\"12\" />' +
					'</A>&nbsp;'
			if (sQuantity > 1) {
				sCart += '<A HREF=\"#\" onClick=\"javascript:aryCart=updateCart(' + iProduct + ',' + ((1*sQuantity) - 1) + ',aryCart);return false;\" ' +
						'TITLE=\"Remove one ' + sProduct + ' from your shopping-cart\">' +
						'<IMG SRC="../images/butt_subtract.gif" BORDER="0" HEIGHT=\"12\" WIDTH=\"12\" />' +
						'</A>&nbsp;';
			} else {
				sCart += '<SPAN><IMG SRC="../images/butt_subtract.gif" BORDER="0" HEIGHT=\"12\" WIDTH=\"12\" /></SPAN>&nbsp;';
			}
			sCart += '</SPAN></SPAN>' +
					'</DIV><DIV STYLE="clear: both;"></DIV>'
		}	// if (iProduct...)
	}		// for (var i...)
	var sCart2 = '';
	if (sCart.length == 0 || aryCart == null) {
		sCart2 = '<SPAN STYLE=\"text-align: left; float: left;\">' +
				'Your cart is empty' +
				'</SPAN>'
	}		// if (sCart.length...)
	sCart += '<DIV STYLE="clear: both;"></DIV>' +
			'<DIV CLASS="ch6cartItem" STYLE="border-top: 2px solid #CCCCCC;">' + sCart2 +
			'<SPAN STYLE="float: right; text-align: right; font-weight: bold;">' +
			'Sub Total' +
			'</SPAN></DIV>' +
			'<DIV CLASS="ch6cartItem"><SPAN ID="ch6basketValue" STYLE="float: right; text-align: right; width: 100%;">' +
			'</SPAN></DIV>'

	var oCart = document.getElementById('ssCart');
	if (oCart != null) {
		oCart.innerHTML = sCart;
		refreshCartCost(aryCart);
	}
	// == persist using a cookie ==
	arrayToCookie(aryCart);
}

// ============================================================================= //
// switch between enabled- and disabled-checkboxes:
// ============================================================================= //
function toggleCheckboxes(sEl1, sEl2) {
	var oEl = document.getElementById(sEl1);
	oEl.className = 'enabledField';
	oEl = document.getElementById(sEl2);
	oEl.className = 'disabledField';
	oEl.checked = false;
}

// ============================================================================= //
// update (enable/disable) the checkboxes on pages: software.htm:
// ============================================================================= //
function updateFormSoftware1() {
	var oForm = document.frmSoftware;
	var oElementDVB = document.getElementById('radSoftwareDVB');
	var oElementTV = document.getElementById('radSoftwareTV');
	var oElementTrial = document.getElementById('radSoftwareTrial');
	var oElementCD = null;
	if (oElementDVB.checked) {
		oElementCD = document.getElementById('cbxCDDVB');
		oElementCD.removeAttribute('DISABLED');
		oElementCD = document.getElementById('cbxCDTV');
		oElementCD.setAttribute('DISABLED','TRUE');
//		oElementCD = document.getElementById('cbxCDTrial');
//		oElementCD.setAttribute('DISABLED','TRUE');
	} else 	if (oElementTV.checked) {
		oElementCD = document.getElementById('cbxCDDVB');
		oElementCD.setAttribute('DISABLED','TRUE');
		oElementCD = document.getElementById('cbxCDTV');
		oElementCD.removeAttribute('DISABLED');
//		oElementCD = document.getElementById('cbxCDTrial');
//		oElementCD.setAttribute('DISABLED','TRUE');
	} else 	if (oElementTrial.checked) {
		oElementCD = document.getElementById('cbxCDDVB');
		oElementCD.setAttribute('DISABLED','TRUE');
		oElementCD = document.getElementById('cbxCDTV');
		oElementCD.setAttribute('DISABLED','TRUE');
//		oElementCD = document.getElementById('cbxCDTrial');
//		oElementCD.removeAttribute('DISABLED');
	}
}

// ============================================================================= //
// update (enable/disable) the checkboxes on pages: software.htm, upgrade-2.htm:
// ============================================================================= //
function updateFormSoftware() {
	var oForm = document.frmSoftware;
	var oElementDVB = document.getElementById('radSoftwareDVB');
	var oElementTV = document.getElementById('radSoftwareTV');
	var oElementTrial = document.getElementById('radSoftwareTrial');
	if (oElementDVB.checked) {
		// enable the current checkbox:
		var oElementCard = document.getElementById('cbxCardDVB');
		oElementCard.className = 'enabledField';
		// disable the other checkbox:
		oElementCard = document.getElementById('cbxCardTV');
		oElementCard.className = 'disabledField';
		oElementCard.checked = false;
		// enable the current labels:
		oElementCard = document.getElementById('spanCardDVB');
		oElementCard.className = 'enabledLabel';
		oElementCard = document.getElementById('spanSoftwareDVB');
		oElementCard.className = 'enabledLabel';
		// disable the other labels:
		oElementCard = document.getElementById('spanCardTV');
		oElementCard.className = 'disabledLabel';
	} else if (oElementTV.checked) {
		// enable the current checkbox:
		var oElementCard = document.getElementById('cbxCardTV');
		oElementCard.className = 'enabledField';
		// disable the other checkbox:
		var oElementCard = document.getElementById('cbxCardDVB');
		oElementCard.className = 'disabledField';
		oElementCard.checked = false;
		// enable the current labels:
		oElementCard = document.getElementById('spanCardTV');
		oElementCard.className = 'enabledLabel';
		oElementCard = document.getElementById('spanSoftwareTV');
		oElementCard.className = 'enabledLabel';
		// disable the other labels:
		oElementCard = document.getElementById('spanCardDVB');
		oElementCard.className = 'disabledLabel';
	}	
}

// ============================================================================= //
// function to redraw a <SELECT...> drop-down of years within a <SPAN>
// params-in:
//		sID			string			ID of <SPAN>
//		sAtt		string			eg. ' STYLE="VISIBILITY: visible" TABINDEX="30" NAME="yy" CLASS="fields"'
//		bFrom		boolean			true if years start from now, false if years end now
// ============================================================================= //
function redrawSelectYear(sID, sAtt, bFrom) {
	var oEl = document.getElementById(sID);
	var dNow = new Date();
	var sHTML = '';
	sHTML += '<SELECT'
	if (sAtt.length > 0) sHTML += ' ' + sAtt;
	if (sID.length > 0) {
		// use the same for both ID and name:
		sHTML += ' ID="' + sID + '" NAME="' + sID + '"';
	}
	sHTML += '>';
	if (bFrom) {
		for (var i = dNow.getFullYear(); i < (dNow.getFullYear() + 10); i++) {
			sHTML += '<OPTION VALUE="' + twoDigits(i) + '"';
			if (i == dNow.getFullYear()) sHTML += ' SELECTED';
			sHTML += '>' + i + '</OPTION>';
		}
	} else {
		for (var i = dNow.getFullYear() - 9; i <= (dNow.getFullYear()); i++) {
			sHTML += '<OPTION VALUE="' + twoDigits(i) + '"';
			if (i == dNow.getFullYear()) sHTML += ' SELECTED';
			sHTML += '>' + i + '</OPTION>';
		}
	}
	sHTML += '</SELECT>'
	oEl.innerHTML = sHTML;
}

// ============================================================================= //
// function to redraw a <SELECT...> drop-down of months within a <SPAN>
// params-in:
//		sID			string			ID of <SPAN>
//		sAtt		string			eg. ' STYLE="VISIBILITY: visible" TABINDEX="30" NAME="yy" CLASS="fields"'
// ============================================================================= //
function redrawSelectMonth(sID, sAtt) {
	var oEl = document.getElementById(sID);
	var dNow = new Date();
	var sHTML = '';

	sHTML += '<SELECT'
	if (sAtt.length > 0) sHTML += ' ' + sAtt;
	if (sID.length > 0) {
		// use the same for both ID and name:
		sHTML += ' ID="' + sID + '" NAME="' + sID + '">';
	}
	for (var i = 1; i <= 12; i++) {
		sHTML += '<OPTION VALUE="' + twoDigits(i) + '"';
		// "our months" go 1..12, ECMAscript months go 0..11, so add 1 to dNow.getMonth():
		if (i == 1+dNow.getMonth()) sHTML += ' SELECTED';
		sHTML += '>' + monthName(i) + '</OPTION>';
	}
	sHTML += '</SELECT>'
	oEl.innerHTML = sHTML;
}

function onCountryChange() {
	var oForm = document.frmCheckout;
	var sForm = oForm.ShipFirstName.value + oForm.ShipLastName.value + oForm.ShipCompany.value +
			oForm.ShipAddress.value + oForm.ShipCity.value + oForm.ShipRegion.value + oForm.ShipPostCode.value;
	// if the Shipping section has no entries:
	if (sForm.length == 0) {
		// set ShipCountry == BillCountry:
		var sBillCountry = oForm.BillCountry[oForm.BillCountry.selectedIndex].value;
		for (var i = 0; i < oForm.ShipCountry.length; i++) {
			var sShipCountry = oForm.ShipCountry[i].value;
			if (sBillCountry == sShipCountry) {
				oForm.ShipCountry.selectedIndex = i;
			}
		}
	}
}

// ============================================================================= //
//###DEPRECATED
// populate the country field(s) based on the relevant dropdown(s).
// iFlag == 1: populate BillCountry
// iFlag == 2: populate ShipCountry
// iFlag == 3: populate both
// ============================================================================= //
function setCountryDropDowns(iFlag) {
/*
	var oCountrySelect = null;
	var oCountry = null;
	var sCountry = '';
	if (iFlag == 1 || iFlag == 3) {
		oCountrySelect = document.getElementById('BillCountrySelect');
		oCountry = document.getElementById('BillCountry');
		sCountry = oCountrySelect[oCountrySelect.selectedIndex].value;
		if (iFlag == 1 || (iFlag == 3 && oCountry.value == '')) {
			oCountry.value = sCountry;
		}
	}
	if (iFlag == 2 || iFlag == 3) {
		oCountrySelect = document.getElementById('ShipCountrySelect');
		oCountry = document.getElementById('ShipCountry');
		sCountry = oCountrySelect[oCountrySelect.selectedIndex].value;
		if (iFlag == 2 || (iFlag == 3 && oCountry.value == '')) {
			oCountry.value = sCountry;
		}
	}
*/
}

// ============================================================================= //
// completes the fields on confirm.htm based on the values in the cookie set
// by checkout.htm:
// ============================================================================= //
function drawConfirmation() {
//	refreshCart(aryCart);
	var sFields = getCookie(COOKIE_CHECKOUT);
	var aryFields = sFields.split('\n');
	var oElement = null;
	var oEcommElement = document.getElementById('ch6ecommerce');
	var sIEHiddenFields = '';
	
	for (var i = 0; i < aryFields.length; i++) {
		var aryPair = aryFields[i].split('=');
		var sName = aryPair[0];
		var sValue = aryPair[1];
		// make sure mulitple line values are OK, and that values won't break SECPAY:
		if (sValue != null && sValue.length > 0) {
			sValue = preMakeSecpaySafe(sValue);			// temporarily change "##NL##" into something that "makeSecpaySafe()" won't break...
			sValue = makeSecpaySafe(sValue);				// escape chars that'll break SECPAY
			sValue = postMakeSecpaySafe(sValue);		// ...with "makeSecpaySafe()" out of the way, change "@@NL@@" into what we always wanted: "<BR />" :)
		}
		// display the field's value:
		oElement = document.getElementById(sName);
		if (oElement != null) {			
			if (sName != 'CCValidMonth' && sName != 'CCValidYear' && sName != 'CCExpMonth' && sName != 'CCExpYear' && sName != 'CCIssue') {
				// handle all fields (except those specified above, and dealt with below):
				if (sName == 'CCNumber') {
					oElement.innerHTML = '<P CLASS="dhtmlField">' + hideCCNumber(sValue) + '</P>';
				} else if (sValue != '') {
					oElement.innerHTML = '<P CLASS="dhtmlField">' + do_unescape(sValue) + '</P>';
				} else {
					oElement.innerHTML = '<P CLASS="dhtmlEmptyField">&nbsp;</P>';
				}
			} else {
				// display credit card dates:
				if (!isIE()) {
					if (sName != 'CCIssue') {
						oElement.innerHTML = '<SPAN STYLE="width: 50px;">' + sValue + '</SPAN>';
					} else {
						oElement.innerHTML = '<P CLASS="dhtmlField" STYLE="width: 20px; text-align: right;">' + sValue + '&nbsp;</P>';
					}
				} else {
					oElement.innerHTML = sValue;
				}
			}
			if (sValue == '&nbsp;') {
				sValue = '';
			}
			// populate hidden form-fields:
			oElement = eval('document.frmConfirm.' + sName);
			oElement.value = sValue;
		}
	}
	
	refreshCart(aryCart);
	
	var cartCost = getCartCost(aryCart);
	var orderID = new Date();
	orderID = Date.parse(orderID.toString());
	
	// cart:
	arrayToHTML(aryCart, document.frmConfirm.CartData);
	document.frmConfirm.CartData.value = prepareCartForSecpay(aryCart);
	// Order Total:
	if (cartCost != null) {
		document.frmConfirm.OrderTotal.value = roundNumber(1*cartCost + 1*getVAT(cartCost));	// jn,29-03-2004
		document.frmConfirm.VAT.value = roundNumber(getVAT(cartCost));	// jn,29-03-2004
	}
	// Transaction ID:
	document.frmConfirm.OrderID.value = makeSecpaySafe(orderID);
	// submission advisory:
	oElement = document.getElementById('secpayAmount');
	oElement.innerHTML = "&euro;" + roundNumber(1*cartCost + 1*getVAT(cartCost));
}

// ============================================================================= //
// return a hidden form-field as a DOM element:
// ============================================================================= //
function getHiddenElement(sName,sValue) {
	var oHidden = document.createElement('INPUT');
	oHidden.setAttribute('TYPE','HIDDEN');
	oHidden.setAttribute('NAME',sName);
	oHidden.setAttribute('VALUE',sValue);
	oHidden.setAttribute('CLASS','dhtmlHiddenField');
	return oHidden;
}

// ============================================================================= //
// loop thru' all IDs "ch6autoPrice...", replace content with price:
// ============================================================================= //
function drawPrices() {
	var i = 1;
	var sID = 'ch6autoPrice' + i;
	var oEl = document.getElementById(sID);
	while(oEl != null) {
		var sProductID = oEl.innerHTML;
		var sPrice = roundNumber(getPrice(sProductID, aryCart));
		oEl.innerHTML = CURRENCY + sPrice;
		oEl.className = 'ssProductPriceVisible';
		sID = 'ch6autoPrice' + ++i;
		oEl = document.getElementById(sID);
	}
}

function showNavForm() {
	var oEl = document.getElementById('ch6nav');
	oEl.className = 'visibleForm';
}

function hideCCNumber(sNumber) {
	var sLastFour = sNumber.slice(12)
	return '************' + sLastFour;
}

// ============================================================================= //
// ch6cart misc functions:
// ============================================================================= //

// ----------------------------------------------------------------------------- //
// loops thru' all fields in a form, escaping the values ready for passing
// on the querystring.
// ----------------------------------------------------------------------------- //
function parseFormForGET(oForm) {
	for(var iItem = 0; iItem < oForm.length; iItem++) {
		var sTemp = oForm.elements[iItem].value;
		sTemp = sTemp.replace(/"/gi, "&quot;");
		sTemp = escape(sTemp);
//		oForm.elements[iItem].value = escape(oForm.elements[iItem].value);
		oForm.elements[iItem].value = sTemp;
	}
}

// ----------------------------------------------------------------------------- //
// unescapes a value, and inserts <BR />s where applicable:
// ----------------------------------------------------------------------------- //
function do_unescape(sValue) {
	sValue = unescape(sValue);
	sValue = sValue.replace(/\n/gi, "<BR />");
	return sValue;
}

// ----------------------------------------------------------------------------- //
// convert a number of any length to a two-digit number.
// eg. 1 => 01
// eg. 2001 => 01
// ----------------------------------------------------------------------------- //
function twoDigits(n) {
	var sN = '' + n;
	if (sN.length == 0) sN = '00';
	if (sN.length == 1) sN = '0' + sN;
	if (sN.length > 2) sN = sN.substring(sN.length-2, sN.length);
	return sN;
}

// ----------------------------------------------------------------------------- //
// params-in:		integer		1..12
// param-out:		string		Jan..Dec
// ----------------------------------------------------------------------------- //
function monthName(n) {
	var months = new Array('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
	if (n > 0 && n <= 12) {
		return months[n-1];
	} else {
		return null;
	}
}

// ----------------------------------------------------------------------------- //
// returns true if the UA is IE:
// ----------------------------------------------------------------------------- //
function isIE() {
	if (navigator.appName == 'Microsoft Internet Explorer') { return true; } else { return false; }
}

// ----------------------------------------------------------------------------- //
// returns a number to 2 decimal places, eg. 1 => 1.00, 1.999 => 2.00
// ----------------------------------------------------------------------------- //
function roundNumber(number) {
	number *= 100;
	number = Math.round(number);
	number /= 100;
//	if (number == Math.round(number)) number += '.00';
	number += '';
	var iDP = number.lastIndexOf('.');
	if (iDP == -1) number += '.00';
	if (iDP == (number.length)-1) number += '00';
	if (iDP == (number.length)-2) number += '0';
	return number;
}

// ----------------------------------------------------------------------------- //
// replace escaped linebreaks with HTML breaks:
// ----------------------------------------------------------------------------- //
function makePretendTextArea(sValue) {
	sValue = quickReplace(sValue, '**NL**', '<BR />');
	return sValue;
}

// ----------------------------------------------------------------------------- //
// "makeSecpaySafe() will remove "#"s, and also "<" and ">", so we need to 
// temporarily preempt it:
// ----------------------------------------------------------------------------- //
function preMakeSecpaySafe(sValue) {
	sValue = quickReplace(sValue, '##NL##', '@@NL@@');
	return sValue;
}

// ----------------------------------------------------------------------------- //
// with "makeSecpaySafe()" out of the way, we can replace the temporary string
// with "<BR />":
// ----------------------------------------------------------------------------- //
function postMakeSecpaySafe(sValue) {
	sValue = quickReplace(sValue, '@@NL@@', '<BR />');
	return sValue;
}

// ----------------------------------------------------------------------------- //
// replace chars that will break SECPAY:
// ----------------------------------------------------------------------------- //
function makeSecpaySafe(sValue) {
	sValue = quickReplace(sValue, '#', '*');	
	sValue = quickReplace(sValue, '<', '*');
	sValue = quickReplace(sValue, '>', '*');
	sValue = quickReplace(sValue, '&', '+');
	sValue = quickReplace(sValue, "'", '’');	// single quote
	sValue = quickReplace(sValue, ',', '¸');	// comma
	sValue = quickReplace(sValue, '?', '*');
	sValue = quickReplace(sValue, '"', '’');	// double quote
	sValue = quickReplace(sValue, '\n', ' ');	// linebreak/newline
	return sValue;
}

// ----------------------------------------------------------------------------- //
// replace *all* occurances of one string with another:
// ----------------------------------------------------------------------------- //
function quickReplace(sValue, sOld, sNew) {
	if (typeof(sValue) == 'string') {
		while (sValue.indexOf(sOld) >= 0) {
			eval('sValue = sValue.replace(/' + sOld + '/, "' + sNew + '");');
		}
	}
	return sValue;
}

// ----------------------------------------------------------------------------- //
// prepare cart data for SECPAY, by (a) "makeSecpaySafe()", and
// (b) changing simple indices with HomeMediaNetwork Product Codes:
// ----------------------------------------------------------------------------- //
function prepareCartForSecpay(aryCart) {
	var cart = '';
	for (var i = 0; i < aryCart.length; i++) {
		var product = getProduct(i, aryCart);
		var quantity = getQuantity(i, aryCart);
		var code = getCode(product);
		var productname = getName(product);
		var unit_price = getPrice(product);
		cart += code + '¸' + productname + '¸' + quantity + '¸' + unit_price + '¦';
	}
	return cart;
}


// ================================================================================
// ch6cart COOKIE API:
// ================================================================================

// ----------------------------------------------------------------------------- //
// nasty kludge to clear all cookies:
// ----------------------------------------------------------------------------- //
function clearCookies() {
	setCookie(COOKIE_CART, '');
	setCookie(COOKIE_VISITED, '');
	setCookie(COOKIE_ACCESSORIES, '');
	setCookie(COOKIE_SS_VERSION, '');
	setCookie(COOKIE_SS_CD, '');
	setCookie(COOKIE_CHECKOUT, '');
	setCookie(COOKIE_AFFILIATE, '');
}

// ----------------------------------------------------------------------------- //
// basic setCookie function:
// ----------------------------------------------------------------------------- //
function setCookie(name, value) {
//	document.cookie = name + "=" + escape(value) + ";DOMAIN=" + escape(DOMAIN) + ";PATH=/";
	document.cookie = name + "=" + escape(value) + ";PATH=/";
}

// ----------------------------------------------------------------------------- //
// added v2.1 - maintain a page list for page navigation.
// page list in form of Pipe-Separated-List/Array
// ----------------------------------------------------------------------------- //
function addVisitedPage(sPage) {
	var pageList = getCookie(COOKIE_VISITED);
	if (pageList == null || pageList.indexOf(sPage) < 0) {
		if (pageList == null || pageList.length == 0) {
			setCookie(COOKIE_VISITED, sPage);
		} else {
			setCookie(COOKIE_VISITED, pageList + S_SEP + sPage);
		}
	}
}

// ----------------------------------------------------------------------------- //
// added v2.1 - maintain a page list for page navigation.
// page list in form of Pipe-Separated-List/Array
// ----------------------------------------------------------------------------- //
function popLastVisitedPage() {
	var pageList = getCookie(COOKIE_VISITED);
	var aryPages = new Array();
	var lastPage = '';
	if (pageList != null && pageList.length > 0 && pageList.indexOf(S_SEP) >= 0) {
		aryPages = pageList.split(S_SEP);
		lastPage = aryPages.pop();
		pageList = '';
		for (var i = 0; i < aryPages.length; i++) {
			pageList += aryPages[i];
			if (i < (aryPages.length-1)) { pageList += S_SEP; }
		}
	} else if (pageList != null && pageList.length > 0) {
		lastPage = pageList;
		pageList = '';
	} else {
		lastPage = '';
		pageList = '';
	}
	setCookie(COOKIE_VISITED, pageList);
	return lastPage;
}

// ----------------------------------------------------------------------------- //
// clear COOKIE_VISITED on PAGE_START:
function clearVisitedPages() {
	setCookie(COOKIE_CART, '');
	setCookie(COOKIE_VISITED, '');
	setCookie(COOKIE_ACCESSORIES, '');
}
// ----------------------------------------------------------------------------- //

// ================================================================================

// ================================================================================
// COOKIE API  v1.0.1
// documentation: http://www.dithered.com/javascript/cookies/index.html
// license: http://creativecommons.org/licenses/by/1.0/
// code (mostly) by Chris Nott (chris[at]dithered[dot]com)
// ================================================================================
// Retrieve a named cookie value
function getCookie(name) {
	var dc = document.cookie;
	// find beginning of cookie value in document.cookie
	var prefix = name + "=";
	var begin = dc.indexOf("; " + prefix);
	if (begin == -1) {
		begin = dc.indexOf(prefix);
		if (begin != 0) return null;
	}
	else begin += 2;
	// find end of cookie value
	var end = document.cookie.indexOf(";", begin);
	if (end == -1) end = dc.length;
	// return cookie value
	return unescape(dc.substring(begin + prefix.length, end));
}

// Delete a named cookie value
function deleteCookie(name, path, domain) {
	var value = getCookie(name);
	if (value != null) document.cookie = name + '=' + ((path) ? '; path=' + path : '') + ((domain) ? '; domain=' + domain : '') + '; expires=Thu, 01-Jan-70 00:00:01 GMT';
	return value;
}
// ================================================================================

// ================================================================================
// ch6cart VALIDATION functions:
// ================================================================================

// validation for CHECKOUT.HTM:
function validateCheckoutForm(oForm) {
	var oError = null;	// location of first error
	var oElement;
	sErrorMessage = '';	// reset error message
	
	oElement = oForm.FirstName;
	if (!validateTextMin(oElement,1,"You must enter your First Name.") && oError == null) oError = oElement;

	oElement = oForm.LastName;
	if (!validateTextMin(oElement,1,"You must enter your Last Name.") && oError == null) oError = oElement;

	oElement = oForm.BillAddress;
	if (!validateTextMin(oElement,1,"You must enter your Address.") && oError == null) oError = oElement;
	
	oElement = oForm.BillCity;
	if (!validateTextMin(oElement,1,"You must enter your City.") && oError == null) oError = oElement;

	oElement = oForm.BillPostCode;
	if (!validateTextMin(oElement,1,"You must enter your Post Code/Zip Code.") && oError == null) oError = oElement;
	
	oElement = oForm.BillCountry;	
	if (!validateDropDown(oElement,"Please select a Billing Country.") && oError == null) oError = oElement;

	oElement = oForm.E_mail;
	if (!validateTextMin(oElement,1,"You must enter your Email.") && oError == null) oError = oElement;
		
	oElement = oForm.CCName;
	if (!validateTextMin(oElement,1,"You must enter your Name as it appears on your Credit Card.") && oError == null) oError = oElement;
		
	oElement = oForm.CCType;
	if (!validateDropDown(oElement,"Please select a Credit Card type.") && oError == null) oError = oElement;	

	oElement = oForm.CCNumber;
	if (!B_DEBUG && !validateCCNumber(oElement) && oError == null) oError = oElement;

	oElement = oForm.CCExpMonth;
	if (!validateDropDown(oElement,"Please select an Expiry Month for your Credit Card.") && oError == null) oError = oElement;

	oElement = oForm.CCExpYear;
	if (!validateDropDown(oElement,"Please select an Expiry Year for your Credit Card.") && oError == null) oError = oElement;

	oElement = oForm.CCValidMonth;
	if (!validateDropDown(oElement,"Please select a 'Valid From' Month for your Credit Card.") && oError == null) oError = oElement;

	oElement = oForm.CCValidYear;
	if (!validateDropDown(oElement,"Please select a 'Valid From' Year for your Credit Card.") && oError == null) oError = oElement;

	oElement = oForm.cv2;
	if (!validateTextMin(oElement,3,"You must enter your CV2 number.") && oError == null) oError = oElement;

	// deal with errors:
	if (oError != null) {
//		displayErrorsNoFocus(oError,sErrorMessage);
		alert(sErrorMessage);
		return false;
	} else {
		return true;
	}
}
// ================================================================================

// ==================== ShowShifter Affiliates - Affiliate ID: ====================
function checkAffiliateID(sQS) {
	// check whether there's a querystring:
	if (sQS.slice(0,1) == "?") {
		sQS = sQS.slice(1, sQS.length);	// strip off the prefix "?"
		arySearch = sQS.split("&");			// split the querystring into name=value pairs
		for (var i = 0; i < arySearch.length; i++) {	// iterate through the pairs
			var sParam = arySearch[i];
			var aryParam = sParam.split("=");
			var sName = aryParam[0], sValue = aryParam[1];
			if (sName == "a") setAffiliateID(sValue);	// check whether the current name=value pair is an affiliate ID
		}
	}
}

function setAffiliateID(sID) {
	var sValue = getCookie(COOKIE_AFFILIATE) + '';
	if (sValue == null || sValue == 'null' || sValue == '') setCookie(COOKIE_AFFILIATE, sID);
}
// ==================== :ShowShifter Affiliates - Affiliate ID ====================


// ============================= ShowShifter Bundles: =============================
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
// gets the HTTP param "Bundle" (from the querystring/GET request) and writes it
// into the checkout form (ready for POST):
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
function drawBundle() {
	// get Bundle code (from Querysting):
	var sQS = location.search;
	sQS = sQS.substr(1, sQS.length - 1);
	var aryQS = sQS.split('&');
	var sName, sValue, sFinalName, sFinalValue;
	sFinalName = '';
	sFinalValue = '';
	for (var iLoop = 0; iLoop < aryQS.length; iLoop++) {
		var aryPair = aryQS[iLoop].split('=');
		sName = aryPair[0];
		sValue = aryPair[1];
		if (sName == 'Bundle') {
			sFinalName = sName;
			sFinalValue = sValue;
		}
	}
	// only proceed if there's a Bundle code:
	if (sFinalValue != '') {
		// put Bundle code (to Form):
		document.frmCheckout.Bundle.value = sFinalValue;
	} else {
		// return to previous page:
		alert('You must choose a bundle!');
		window.history.go(-1);
	}
	// draw price:
	var price = getPrice(sFinalValue);
	oEl = document.getElementById('ch6basketValue');
	oEl.innerHTML = CURRENCY + roundNumber(price);
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
// locks the "confirm" button on checkout-bundle.htm, and redirects to
// confirm-bundle.htm:
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
function lockConfirmBundle() {
	var oEl = document.getElementById('ch6btnPay');
	if (oEl.className == 'enabledButton') {
		//setCountryDropDowns(3);	// set *both* drop-downs	
		onCountryChange();
		if (validateCheckoutForm(document.forms['frmCheckout'])) {
			oEl.className = 'disabledButton';
			addVisitedPage(PAGE_BUNDLE_CHECKOUT);
			addCheckoutDetails();
			// parse input, escaping dodgy characters:
			parseFormForGET(document.frmCheckout);
//			window.location.href = SECURE_SITE + SHOP + PAGE_BUNDLE_CONFIRM;	// this works fine, commented-out for tetsing...
			window.location.href = PAGE_BUNDLE_CONFIRM;
		}
	} else {
		alert('Proceding to final confirmation...');	
	}
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
// completes the fields on confirm.htm based on the values in the cookie set
// by checkout.htm:
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
function drawConfirmationBundle() {
	var sFields = getCookie(COOKIE_CHECKOUT);
	var aryFields = sFields.split('\n');
	var oElement = null;
	var oEcommElement = document.getElementById('ch6ecommerce');
	var sIEHiddenFields = '';
	
	for (var i = 0; i < aryFields.length; i++) {
		var aryPair = aryFields[i].split('=');
		var sName = aryPair[0];
		var sValue = aryPair[1];

		// make sure mulitple line values are OK, and that values won't break SECPAY:
		if (sValue != null && sValue.length > 0) {
			sValue = preMakeSecpaySafe(sValue);			// temporarily change "##NL##" into something that "makeSecpaySafe()" won't break...
			sValue = makeSecpaySafe(sValue);				// escape chars that'll break SECPAY
			sValue = postMakeSecpaySafe(sValue);		// ...with "makeSecpaySafe()" out of the way, change "@@NL@@" into what we always wanted: "<BR />" :)
		}
		// display the field's value:
		oElement = document.getElementById(sName);
		if (oElement != null) {			

			if (sName != 'CCValidMonth' && sName != 'CCValidYear' && sName != 'CCExpMonth' && sName != 'CCExpYear' && sName != 'CCIssue' && sName != 'Bundle') {

				// handle all fields (except those specified above, and dealt with below):
				if (sName == 'CCNumber') {
					oElement.innerHTML = '<P CLASS="dhtmlField">' + hideCCNumber(sValue) + '</P>';
				} else if (sValue != '') {
					oElement.innerHTML = '<P CLASS="dhtmlField">' + do_unescape(sValue) + '</P>';
				} else {
					oElement.innerHTML = '<P CLASS="dhtmlEmptyField">&nbsp;</P>';
				}
			} else {
				// display credit card dates:
				if (!isIE()) {
					if (sName != 'CCIssue') {
						oElement.innerHTML = '<SPAN STYLE="width: 50px;">' + sValue + '</SPAN>';
					} else {
						oElement.innerHTML = '<P CLASS="dhtmlField" STYLE="width: 20px; text-align: right;">' + sValue + '&nbsp;</P>';
					}
				} else {
					if (sName != 'Bundle') {				// skip 'Bundle' as it doesn't map to a displayed field
						oElement.innerHTML = sValue;
					} else {
						// populate hidden form-fields:	// ...or... see if that fixes a funny secpay problem 20041018 - YOU ARE HERE
						oElement = eval('document.frmConfirm.' + sName);
						oElement.value = sValue;
					}
				}
			}
			if (sValue == '&nbsp;') {
				sValue = '';
			}
			// populate hidden form-fields:
			oElement = eval('document.frmConfirm.' + sName);
			oElement.value = sValue;
		} else {
			// populate hidden form-fields (that don't map to displayed fields):
			if (sName != '') {
				oElement = eval('document.frmConfirm.' + sName);
				if (oElement != null) {
					oElement.value = sValue;
				}
			}
		}
	}
	
	refreshCartBundle();

	// OrderID:
	var orderID = new Date();
	orderID = Date.parse(orderID.toString());
	document.frmConfirm.OrderID.value = makeSecpaySafe(orderID);
	
	// Bundle code:
	var sBundle = document.frmConfirm.Bundle.value;

	// OrderTotal and VAT:	
	var cPrice = getPrice(sBundle);
	document.frmConfirm.OrderTotal.value = roundNumber(1*cPrice + 1*getVAT(cPrice));
	document.frmConfirm.VAT.value = roundNumber(getVAT(cPrice));
	
	// CartData:
	var quantity = 1;
	var code = getCode(sBundle);
	var productname = getName(sBundle);
	document.frmConfirm.CartData.value = code + '¸' + productname + '¸' + quantity + '¦';
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
// locks the "pay" button on confirm.htm, and redirects to online payment service
// (eg. Secpay):
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
function lockPayBundle() {
	var oEl = document.getElementById('ch6btnPay');
	if (oEl.className == 'enabledButton') {
		oEl.className = 'disabledButton';
		addVisitedPage(PAGE_BUNDLE_CONFIRM);
		// just warn the user about refreshing their browser
		alert('This may take a little while. During this time do not refresh your browser or click the back button.\n\nClick OK to continue.');
		// submit the form:
		document.frmConfirm.submit();
	} else {
		alert('Proceding to credit-card payment...');	
	}
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
// draw large "cart", ie. confirm-bundle.htm:
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //
function refreshCartBundle() {
	// prepare for cart rendering:
	var quantity = 1;

	// render the cart:
	var oEl = document.getElementById('ch6basket');
	oEl.innerHTML = '';
	var oTable = document.createElement("TABLE");
	oTable.setAttribute('style', 'width: 100%;');
	var oTHead = document.createElement("THEAD");
	var oTBody = document.createElement("TBODY");
	var oTR = document.createElement("TR");
	var sText = '';	// NB. "sText" a var for text nodes.  Should be renamed to "oText" [jn,29-01-2004]
	var sClass = '';
	if (isIE()) {
		sClass = 'className';
	} else {
		sClass = 'class';
	}
	// create headers
	// - Name
	sText = document.createTextNode('Name');		
	var oTH = document.createElement("TH");
	oTH.appendChild(sText);
	oTH.setAttribute(sClass,'ch6cartTableHeader');
	oTR.appendChild(oTH);
	// - Price
	sText = document.createTextNode('Price');		
	var oTH = document.createElement("TH");
	oTH.appendChild(sText);
	oTH.setAttribute(sClass,'ch6cartTableHeader');
	oTH.setAttribute('style','text-align: right;');	// NB. this doesn't work - or doesn't seem to work - in IE6 [jn,29-01-2004]
	oTR.appendChild(oTH);

	// - Quantity
	sText = document.createTextNode('Quantity');		
	var oTH = document.createElement("TH");
	oTH.appendChild(sText);
	oTH.setAttribute(sClass,'ch6cartTableHeader');
	oTH.setAttribute('style','text-align: right;');
	oTR.appendChild(oTH);
	// - Total
	sText = document.createTextNode('Total');		
	var oTH = document.createElement("TH");
	oTH.appendChild(sText);
	oTH.setAttribute(sClass,'ch6cartTableHeader');
	oTH.setAttribute('style','text-align: right;');
	oTR.appendChild(oTH);
	// add header-row to table:
	oTHead.appendChild(oTR);
	oTable.appendChild(oTHead);
	
	oTR = document.createElement("TR");
	// loop thru' fields: "name", "price", "description", "quantity", "total price", "control":
	for (var j = 0; j < 4; j++) {
		var oTD = document.createElement("TD");
		oTD.setAttribute('VALIGN','TOP');
			var sBundle = document.frmConfirm.Bundle.value;
			var sProduct = getName(sBundle);
			
			var quantity = 1;
			var code = getCode(sBundle);
			var price = getPrice(sBundle);
			var subtotal = price;
			
		// create TDs/fields:
		var oControl;
		var oSpan;
		switch (j) {
			case 0:
				sText = document.createTextNode(sProduct);
				break;
			case 1:
				if (!isNaN(price)) {
					sText = document.createTextNode(CURRENCY + price);
				} else {
					sText = document.createTextNode('error: ' + price);
				}
				break;
			case 2:
				var oSpanRow = document.createElement('DIV');
				oSpanRow.setAttribute('STYLE','width: 100px;');
				oSpan = document.createElement('SPAN');
				oSpan.setAttribute('STYLE','float: right;');
				sText = document.createTextNode('1');
				oSpan.appendChild(sText);
				oSpanRow.appendChild(oSpan);
				oTD.appendChild(oSpanRow);
				break;
			case 3:
				if (!isNaN(subtotal)) {
					sText = document.createTextNode(CURRENCY + subtotal);
				} else {
					sText = document.createTextNode('error: ' + subtotal);
				}
				break;
			case 4:
				break;
		}
		if (sText.length == 0) sText = '&nbsp;';
		// don't appendChild on j==3,5 : it'll already have been done:
		if (j != 2 && j != 4) {					
			var oSpan = document.createElement('SPAN');
			oSpan.setAttribute(sClass,'ie6fix');
			oSpan.appendChild(sText);
			oTD.appendChild(oSpan);
		}
		// edit TDs/fields:
		switch (j) {
			case 0:
				oTD.setAttribute(sClass,'ch6cartItemName');
				break;
			case 1:
				oTD.setAttribute(sClass,'ch6cartItemPrice');
				break;
			case 2:
				oTD.setAttribute(sClass,'ch6cartItemQuantity');
				break;
			case 3:
				oTD.setAttribute(sClass,'ch6cartItemTotal');
				break;
			case 4:
				break;
		}
		// don't do this IIF we're on confirm.htm AND it's case 5 (control column):
		if (!((location.href.indexOf(PAGE_CONFIRM) >= 0) && (j == 4))) {
			oTR.appendChild(oTD);
		}
	}
	oTBody.appendChild(oTR);
	oTable.appendChild(oTBody);
	oTable.setAttribute('ID', 'ch6cartTable');
	oEl.appendChild(oTable);
	
	// finally...:
	oEl = document.getElementById('ch6basketValue');
	oEl.innerHTML = CURRENCY + roundNumber(subtotal);
	oEl = document.getElementById('ch6vatValue');
	oEl.innerHTML = CURRENCY + roundNumber(getVAT(subtotal));
	oEl = document.getElementById('ch6totalValue');
	oEl.innerHTML = CURRENCY + roundNumber(1*subtotal + 1*getVAT(subtotal));
}

// ============================= :ShowShifter Bundles =============================

// ===== unescapeForm(oForm): =====
function unescapeForm(oForm) {
	var re = /%20/gi;
	for (var i = 0; i < oForm.length; i++) {
		oForm[i].value = oForm[i].value.replace(re, ' ');		
	}
}
// ===== :unescapeForm(oForm) =====
