/* Virtual Bookstore */

/* Global Vars ---------------------------------------------------------------------------------- */

var alreadySubmitted = false;

var max_unshrunk_lines = 5;		// number of lines to show before we need to start shrinking
var num_shrunk_lines = 3;		// if shrinking, number of lines to shrink to
var expandedMessages;

var curDetailsShowing = false;
var curDetailsId = '';

var bY	= 0;
var lPY	= 0;
var lId	= '';

/* Prototypes ----------------------------------------------------------------------------------- */

String.prototype.trim = function() {
	return this.replace(/^\s*(.*?)\s*$/, '$1');
};

String.prototype.isEmail = function() {
	var tmp_atom = '[a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~-]';
	var tmp_domain = '([a-zA-Z0-9]([-a-zA-Z0-9]*[a-zA-Z0-9]+)?)';
	var RegExpEmail = new RegExp('^' + tmp_atom + '*(\\.' + tmp_atom + '+)*@(' + tmp_domain + '{1,63}\\.)+' + tmp_domain + '{2,63}$');
	return RegExpEmail.test(this.trim());
};

String.prototype.isVBPassword = function() {
	var regex = /^[a-zA-Z0-9]{5,10}$/;
	return regex.test(this.trim());
};

String.prototype.isCCN = function(kind) {
	var s = this.replace(/[\s-]+/g, '');
	if (s == '') return false;
	if (kind == 'V') {
		if (/^\*{9}\*{3}?\d{4}$/.test(s)) return true; /* unchanged */
		if (! /^4\d{12}\d{3}?$/.test(s) ) return false;
	}
	else if (kind == 'M') {
		if (/^\*{12}\d{4}$/.test(s)) return true; /* unchanged */
		if (! /^5[1-5]\d{14}$/.test(s) ) return false;
	}
	else if (kind == 'D') {
		if (/^\*{12}\d{4}$/.test(s)) return true; /* unchanged */
		if (! /^6011\d{12}$/.test(s) ) return false;
	}
	else if (kind == 'F') {
		if (/^\*{11}\d{4}$/.test(s)) return true; /* unchanged */
		if (! /^3[47]\d{13}$/.test(s) ) return false;
	}
	else return false;
	var sum = 0;
	var even = true;
	for (var i = s.length-1; i >= 0; i--) {
		var ch = s.charAt(i);
		digit = parseInt(ch);
		if (!even) {
			digit *= 2;
			if (digit > 9)	digit -= 9;
		}
		sum += digit;
		even = !even;
	}
	return ((sum % 10) == 0);
};

String.prototype.isCCV = function(kind) {
	var len = (kind == 'F') ? 4 : 3;
	var s = this.trim();
	return (/^\d+$/.test(s) && s.length == len);
};

Number.prototype.toMoney = function() {
	var n = Math.floor(this.valueOf() * 100.0);
	var dollars = (n / 100).toString();
	var cents = (n % 100).toString();
	if (cents.length == 1) cents = '0' + cents;
	return dollars + '.' + cents;
};

Number.prototype.ppPrice = function(commas) {
	if (commas == true) {
		var nStr = this.toFixed(2) + '';
		var x = nStr.split('.');
		var x1 = x[0];
		var x2 = x.length > 1 ? '.' + x[1] : '';
		var rgx = /(\d+)(\d{3})/;
		while (rgx.test(x1)) {
			x1 = x1.replace(rgx, '$1' + ',' + '$2');
		}
		return x1 + x2;
	}
	else
		return this.toFixed(2);
};

/* Functions ------------------------------------------------------------------------------------ */

function addClass(ctl, className) {
	if (!ctl) return;
	var s = ctl.className.trim();
	if (s.length == 0)
		ctl.className = className;
	else {
		var classes = s.split(' ');
		for (var i = 0; i < classes.length; ++i) {
			if (classes[i] == className) return;
		}
		ctl.className = s + ' ' + className;
	}
}

function removeClass(ctl, className) {
	if (!ctl) return;
	var s = ctl.className.trim();
	if (s.length == 0)
		return;
	var classes = s.split(' ');
	var newClasses = new Array();
	var found = false;
	for (var i = 0; i < classes.length; ++i) {
		if (classes[i] == className)
			found = true;
		else
			newClasses.push(classes[i]);
	}
	if (found) {
		if (newClasses.length > 0)
			ctl.className = newClasses.join(' ');
		else
			ctl.className = '';
	}
}

function hasClass(ctl, className) {
	if (!ctl) return;
	var s = ctl.className.trim();
	if (s.length == 0)
		return false;
	var classes = s.split(' ');
	for (var i = 0; i < classes.length; ++i) {
		if (classes[i] == className) {
			return true;
		}
	}
	return false;
}

function firstChildClass(cParent, className) {
	var node = cParent.firstChild;
	while (node) {
		if (node.nodeType == 1) {
			if (hasClass(node, className)) return node;
			var t = firstChildClass(node, className);
			if (t) return t;
		}
		node = node.nextSibling;
	}
	return null;
}

/**
 * Show/Hide Extra Details
 */
function toggleElementPosition(cell, elem, show, xOffset, yOffset) {
	if (!cell || !elem) return;

	// hide current element
	if (show != 'Y') {
		elem.style.display = 'none';
		return;
	}

	// fix up our offsets
	if (xOffset == undefined)
		var xOffset = 0;
	if (yOffset == undefined)
		var yOffset = 0;

	// get coordinates of current cell
	var coords = findPos(cell);
	var x = (coords[0] + xOffset) + 'px';
	var y = (coords[1] + yOffset) + 'px';

	// now show current element
	elem.style.left = x;
	elem.style.top = y;
	elem.style.display = 'block';

	return;
}

function popup(mylink, windowname, width, height, scrollbars) {
	if (! window.focus) return;
	var href;
	if (typeof(mylink) == 'string') href=mylink;
	else href=mylink.href;
	window.open(href, windowname, 'width=' + width + ',height=' + height + ',scrollbars=' + scrollbars);
	//return false;
}

function DoFail(ctl, msg) {

	// do not error out if we cannot focus
	try { ctl.focus(); } catch(e) {	}

	alert(msg);
	return false;
}

function LogInLoaded() {
	if (document.frmLogin && document.frmLogin.fvEmailLogIn && document.frmLogin.fvLoginPassword
		&& document.frmLogin.fvEmailLogIn.value.trim() != '') {
		document.frmLogin.fvLoginPassword.focus();
		return;
	}
	if (document.frmLoginNew && document.frmLoginNew.fvEmailNew) {
		document.frmLoginNew.fvEmailNew.focus();
		return;
	}
	if (document.frmLogin && document.frmLogin.fvEmailLogIn) {
		document.frmLogin.fvEmailLogIn.focus();
		return;
	}
}

function CanLogIn(frm) {
	if (alreadySubmitted) {
		alert("Please wait while we gather your information.");
		return false;
	}
	var s = frm.fvEmailLogIn.value.trim();
	if (s == '')
		return DoFail(frm.fvEmailLogIn, "You must enter your Email Address.");
	if (!s.isEmail())
		return DoFail(frm.fvEmailLogIn, "Your Email Address must be a valid email address.");
	s = frm.fvLoginPassword.value.trim();
	if (s == '')
		return DoFail(frm.fvLoginPassword, "You must enter your Password.");
	if (!s.isVBPassword())
		return DoFail(frm.fvLoginPassword, "Your Password must be between 5 and 10 alphanumeric characters.\n"
			+ "Please do not use spaces or punctuation - just letters and/or numbers.");
	alreadySubmitted = true;
	return true;
}

function CanLogInNew(frm) {
	if (alreadySubmitted) {
		alert("Please wait while we process your request.");
		return false;
	}

	var fvEmailNew = $.trim($(frm).find("input[name='fvEmailNew']").val());

	if (fvEmailNew == '')
		return DoFail(frm.fvEmailNew, "You must enter your Email Address.");
	if (!fvEmailNew.isEmail())
		return DoFail(frm.fvEmailNew, "Your Email Address must be a valid email address.");

	if ($(frm).find("input[name='fvUserType']").length) {
		var fvUserType = $(frm).find("input[name='fvUserType']:checked").val();
		if (fvUserType == undefined)
			return DoFail(frm.fvUserType[0], "Please select what type of customer you are.");
	}

	alreadySubmitted = true;
	return true;
}

function CanGetPassword(ctl) {
	var s = ctl.value.trim();
	if (s == '')
		return DoFail(ctl, "You must enter your email Address.");
	if (!s.isEmail())
		return DoFail(ctl, "Your email Address must be a valid email address.");
	return true;
}

/**
 * Validate Password reset form.
 */
function CanResetPassword(frm){

	if (!frm) return false;

	if (frm.fvPassword.value.trim() == '')
		return DoFail( frm.fvPassword, "Please enter your New Password");
	if (!frm.fvPassword.value.isVBPassword())
		return DoFail( frm.fvPassword, "Your password must be 5-10 letters and/or numbers.");
	if (frm.fvConfirmPassword.value.trim() == '')
		return DoFail( frm.fvConfirmPassword, "Please Confirm your New Password");
	if (frm.fvPassword.value.trim() != frm.fvConfirmPassword.value.trim())
		return DoFail( frm.fvPassword, "New Passwords do not match. Please re-enter your New Password");

	return true;
}

function EmailOkay(ctl) {
	var s = ctl.value.trim();
	if (s == '')
		return DoFail(ctl, "You must enter your email Address.");
	if (!s.isEmail())
		return DoFail(ctl, "Your email Address must be a valid email address.");
	return true;
}

function StudentIDOkay(ctl) {
	var regex = /^.{1,16}$/;
	var s = ctl.value.trim();

	if (s == '')
		return DoFail(ctl, "You must enter your Student ID.");
	if (!regex.test(s))
		return DoFail(ctl, "Your Student ID must be 1-16 letters and/or numbers.");
	return true;
}

function CanBuybackSearch(frm, singular) {
	var ctl = frm.isbns;
	var ISBNs = singular ? 'an ISBN' : 'any ISBNs';

	if (ctl.value.trim() == '') {
		ctl.focus();
		alert('You have not entered ' + ISBNs + ' to search for.');
		return false;
	}
	return true;
}

function CanUpdateBuybackCart(frm) {
	if (alreadySubmitted) {
		alert("Please wait while we process your request.\n"
			+ "If you got here by backing up, try using the My Buyback Cart "
			+ "menu item and make your updates there.");
		return false;
	}
	var ctl;
	var idx = 1;
	while (ctl = eval("frm.seq_" + idx)) {
		if (ctl.checked) {
			alreadySubmitted = true;
			return true;
		}
		idx++;
	}
	if (idx == 1)
		alert("Your cart is empty.");
	else
		alert("There is nothing to update.\n"
			+ "If you want to remove items from your cart, check the checkbox to the left of the item(s) and click UPDATE.");
	return false;
}

function CanBuybackFromResults(frm) {
	if (alreadySubmitted) {
		alert("Please wait while we process your request.\n"
			+ "If you got here by backing up, try using the My Buyback Cart "
			+ "menu item and search for your ISBN(s) again.");
		return false;
	}
	/* Even if no items checked, let them post to get back to the search form */
	alreadySubmitted = true;
	return true;
}

function CanBuybackFromHistory(frm) {
	if (alreadySubmitted) {
		alert("Please wait while we process your request.\n"
			+ "If you got here by backing up, try using the My Previous Purchases "
			+ "menu item.");
		return false;
	}
	/* nothing to check */
	alreadySubmitted = true;
	return true;
}

function CanAddQuotes(frm) {
	alert("Not yet.");
	return false;
}

function CanBuybackCheckout(frm) {
	var subtotal = parseFloat(frm.subtotal.value);
	if (minBuyback > 0.0 && subtotal < minBuyback) {
		if (!document.frmCart.seq_1)
			alert("Your buyback cart is empty.");
		else
			alert("You must have at least $" + minBuyback.toMoney() + " in your cart to check out.");
		return false;
	}
	return true;
}

function FocusBuybackMailing() {
	with (document.frmBBmailing) {
		if (FVFIRSTNAME.value.trim() == '')
			FVFIRSTNAME.focus();
		else if (FVLASTNAME.value.trim() == '')
			FVLASTNAME.focus();
		else if (FVADDRESS1.value.trim() == '')
			FVADDRESS1.focus();
		else if (FVCITY.value.trim() == '')
			FVCITY.focus();
		else if (FVSTATE.selectedIndex < 1)
			FVSTATE.focus();
		else if (FVZIPPOSTAL.value.trim() == '')
			FVZIPPOSTAL.focus();
		else {
			if (document.frmBBmailing.FVEMAIL) {
				if (FVEMAIL.value.trim() == '')
					FVEMAIL.focus();
				else if (document.frmBBmailing.FVPASSWORD)
					FVPASSWORD.focus();
			}
			else
				FVACCEPT.focus();
		}
	}
}

function CanBuybackMailing(frm) {
	if (alreadySubmitted) {
		alert("Please wait while we process your request.\n"
			+ "If you got here by backing up, this message is just here to protect "
			+ "you from submitting your quote multiple times.");
		return false;
	}
	var ctl = frm.FVFIRSTNAME;
	if (ctl.value.trim() == '') {
		alert("Please enter your First Name.");
		ctl.focus();
		return false;
	}
	ctl = frm.FVLASTNAME;
	if (ctl.value.trim() == '') {
		alert("Please enter your Last Name.");
		ctl.focus();
		return false;
	}
	ctl = frm.FVADDRESS1;
	if (ctl.value.trim() == '') {
		alert("Please enter your street address.");
		ctl.focus();
		return false;
	}
	ctl = frm.FVCITY;
	if (ctl.value.trim() == '') {
		alert("Please enter your City.");
		ctl.focus();
		return false;
	}
	ctl = frm.FVSTATE;
	if (ctl.selectedIndex < 1) {
		alert("Please enter your State.");
		ctl.focus();
		return false;
	}
	ctl = frm.FVZIPPOSTAL;
	var s = ctl.value.trim();
	if (s == '') {
		alert("Please enter your Zip Code.");
		ctl.focus();
		return false;
	}
	if (!/^\d{5}([-]\d{4})?$/.test(s)) {
		alert("Please enter either a 5-digit number or 5+4 (eg: 12345-1234) for your Zip Code.");
		ctl.focus();
		return false;
	}
	ctl = frm.FVGRADYEAR;
	if (ctl && ctl.selectedIndex < 1) {
		alert("Please enter your Expected Graduation Year.");
		ctl.focus();
		return false;
	}

	ctl = frm.FVEMAIL;
	ctl2 = frm.FVCURRENTEMAIL;
	if (ctl && ctl2) {
		s = ctl.value.trim();
		s2 = ctl2.value.trim();
		if ((s.length > 0 && !s.isEmail()) || (s.length == 0 && s2.length > 0)) {
			alert("Please enter a valid Email Address.");
			ctl.focus();
			return false;
		}
	}
	else if (ctl) {
		s = ctl.value.trim();
		if (s == '') {
			alert("Please enter your Email Address.");
			ctl.focus();
			return false;
		}
		if (!s.isEmail()) {
			alert("Please enter a valid Email Address.");
			ctl.focus();
			return false;
		}
		ctl = frm.FVPASSWORD;
		s = ctl.value.trim();
		if (s == '') {
			alert("Please enter a Password for your account.");
			ctl.focus();
			return false;
		}
		if (!/^[a-zA-Z0-9]{5,10}$/.test(s)) {
			alert("The Password for your account must be 5-10 letters and/or numbers.");
			ctl.focus();
			return false;
		}
		if (s != frm.FVPASSWORD2.value.trim()) {
			alert("Please Confirm your password by entering the same value you did for Password.");
			frm.FVPASSWORD2.value = '';
			frm.FVPASSWORD2.focus();
			return false;
		}
	}

	if (frm.FVPAYMENT) {
		if (frm.FVPAYMENT[0] && frm.FVPAYMENT[0].type == 'radio') {
			if (!frm.FVPAYMENT[0].checked && !frm.FVPAYMENT[1].checked) {
				alert("Please select a Payment Option.");
				frm.FVPAYMENT[0].focus();
				return false;
			}
			else if (frm.FVPAYMENT[1].checked) {
				ctl = frm.FVPAYPALEMAIL;
				s = ctl.value.trim();
				if (s == '') {
					alert("Please enter your PayPal Email Address.");
					ctl.focus();
					return false;
				}
				else if (!s.isEmail()) {
					alert("Please enter a valid PayPal Email Address.");
					ctl.focus();
					return false;
				}

				ctl2 = frm.FVVERIFYPAYPALEMAIL;
				s2 = ctl2.value.trim();
				if (s2 == '') {
					alert("Please Verify your PayPal Email Address.");
					ctl2.focus();
					return false;
				}
				else if (s != s2) {
					alert("PayPal Email Addresses do not match. Please re-enter and verify your PayPal Email Address.");
					ctl.focus();
					return false;
				}
			}
		}
	}

	ctl = frm.FVACCEPT;
	if (ctl.type == 'checkbox' && !ctl.checked) {
		alert('You must accept the Terms and Conditions to sell books to Your School\'s Official Bookstore.\n' +
			'You accept by checking the "I accept the Terms and Conditions" checkbox before clicking Submit.');
		return false;
	}
	alreadySubmitted = true;
	return true;
}

function CookiesEnabled() {
	var tmp = new Date();
	tmp.setTime(tmp.getTime() + 24*60*60*1000);
	document.cookie = 'cookie-test=true; expires=' + tmp.toGMTString() + '; path=/';
	tmp = document.cookie.split(';');
	var tmp2 = new Date();
	tmp2.setTime(tmp2.getTime() - 24*60*60*1000);
	document.cookie = 'cookie-test=; expires=' + tmp2.toGMTString() + '; path=/';
	for (var i = 0; i < tmp.length; ++i) {
		var c = tmp[i];
		while (c.charAt(0) == ' ') c = c.substring(1, c.length);
		if (c.indexOf('cookie-test=') == 0) return true;
	}
	return false;
}

/* Do not double-post when submitting adoptions
 */
function CanAdopt(thisForm, page) {
	if (alreadySubmitted) {
		var str = "Please wait while we process your request.\n";
		if (page != 'detail')
			str += "If you got here by backing up, try using the Select Course(s) menu item instead.";

		alert(str);
		return false;
	}

	var count = countAdoptionSelections();
	var rentalCount = countRentalSelections();
	if (count <= 0) {
		if (!confirm("No items are selected to add to the cart. Are you sure you want to continue?"))
			return false;
	}
	else if (rentalCount > 0) {
		if (thisForm.find("input[name='rentalTOS']").val() != "Y") {
			updateRentalRequirementsModal();

			$("#rental-requirements").addClass("in-focus");
			centerModal();
			triggerFocus();	
			$("#rental-requirements").fadeIn("slow");
			return false;
		}
	}

	if (count > 0)
		$("#page-footer .step-button").text('Reserving Your Books...');

	alreadySubmitted = true;
	return true;
}

/* Do not double-post when submitting supplements
 */
function CanSupplement(frm) {
	if (alreadySubmitted) {
		alert("Please wait while we process your request.\n"
			+ "If you got here by backing up, try using the Select Course(s) menu item instead.");
		return false;
	}
	alreadySubmitted = true;
	return true;
}

/* Do what needs to be done when selecting given fillopt and shiptype.
 *
 * Note that either parm can be null and the script will use the
 * *currently selected* value for that. The currently selected
 * value will NOT be the one the user is attempting to select,
 * but rather the one that was selected prior to the event
 * that calls this firing.
 *
 */
function shipping_page_set_shiptype(fillopt, shiptype){

	// we weren't passed a fillopt parm. figure it out from selected value.
	if( fillopt == null ){
		if( document.frmShipping.FILLOPTION ){
			if( document.frmShipping.FILLOPTION[0].checked )
				fillopt = 'D';
			else
				fillopt = 'A';
		}
		else{
			fillopt = 'O';
		}
	}

	// we weren't passed a shiptype parm. figure it out from selected value.
	if(shiptype == null){
		if( document.frmShipping.SHIPTYPE ){
			for( var i=0; i < document.frmShipping.SHIPTYPE.length; i++ ){
				if(document.frmShipping.SHIPTYPE[i].checked){
					shiptype=document.frmShipping.SHIPTYPE[i].value;
					break;
				}
			}
		}
	}

	// PDR: the hidden var containing the cost
	var name = "shipcost_" + fillopt + "_" + shiptype.replace(/[^a-zA-Z0-9\.]/g, '_');

	// if we have a fillopt and a shiptype (or no shipping), set value in order summary section.
	/*
	var ship_cost = 0;
	if( fillopt != null && (shiptype != null || ar_ship_cost.length == 0 ) ){

		if( shiptype != null ){
			ship_cost = ar_ship_cost[fillopt][shiptype];
		}
	}
	*/
	// get ship cost
	var ship_cost = null;
	eval("var elem = document.frmShipping." + name + ";");
	if (elem){
		// eval("var ship_cost = parseFloat(document.frmShipping." + name + ".value);");
		ship_cost = parseFloat(elem.value);
	}
	// set ship cost in summary
	var elem=document.getElementById('shippingamountdisplay');
	if(elem){
		if (ship_cost !== null)
			elem.innerHTML='$' + ship_cost.ppPrice(true);
		else
			elem.innerHTML='';
	}

	var total = subtotal + tax_amount + ship_cost;
	var total_voucherable = 0;

	if( subtotal_voucherable != null ){

		var total_voucherable = subtotal_voucherable + tax_voucherable;

		if (fillopt != null && shiptype != null ){
			if( ar_ship_covered[fillopt][shiptype] ){
				total_voucherable += shipping_amount_voucherable(ship_cost);
			}
		}
	}

	elem=document.getElementById('ordertotaldisplay');
	if(elem){
		elem.innerHTML='$' + total.ppPrice(true);
	}

	elem=document.getElementById('vch_total');
	if(elem){
		elem.innerHTML='$' + total_voucherable.ppPrice(true);
	}

	elem=document.getElementById('amount_due');
	if(elem){

		if (total_voucherable >= total){
			elem.innerHTML='$0.00';

			document.getElementById('checkout_address_static').style.display = 'none';
			document.getElementById('bill_address_inputs').style.display = 'none';
			document.frmShipping.BILLINGINPUTS.value = '0';
			document.getElementById('cc_info').style.display = 'none';
		}else{
			var amt_due = total - total_voucherable;
			elem.innerHTML='$' + amt_due.ppPrice(true);

			if( ! have_billing_adr ){
				document.getElementById('checkout_address_static').style.display = 'none';
				document.getElementById('bill_address_inputs').style.display = 'block';
				document.frmShipping.BILLINGINPUTS.value = '1';
			}else{
				document.getElementById('bill_address_inputs').style.display = 'none';
				document.frmShipping.BILLINGINPUTS.value = '0';
				document.getElementById('checkout_address_static').style.display = 'block';
			}

			document.getElementById('cc_info').style.display = 'block';
		}
	}

	return true;
}

// assumes it's a type that can be covered.
function shipping_amount_voucherable(ship_cost){

	if( typeof(ship_cost) == 'string' ) ship_cost = parseFloat(ship_cost);

	var covered=0;
	var ship_covered = 0;
	var i = 0;
	for (i = 0; i < ar_vch_info.length ;i++ ){
		if( ar_vch_info[i]['PCT'] ){
			if(subtotal>0)
				factor=(subtotal_voucherable/ar_vch_info[i]['PCT'])/subtotal;
			else
				factor=1;
			covered=ship_cost*ar_vch_info[i]['PCT']*factor;
			covered=Math.round(covered*100)/100;
			if( ( ar_vch_info[i]['MAX'] > 0 ) && covered + ar_vch_scoreboard['pct_used'] > ar_vch_info[i]['MAX'] )
				covered = ar_vch_info[i]['MAX'] - ar_vch_scoreboard['pct_used'];
			ship_cost -= covered;
			ship_covered += covered;
		}
		else{
			factor =(subtotal>0)?subtotal_voucherable / subtotal:1;
			covered=Math.round((ship_cost*factor)*100)/100;
			if( !is_proxy )
				if( covered + ar_vch_scoreboard['reg_used'] > ar_vch_info[i]['AMT'] )
					covered = ar_vch_info[i]['AMT'] - ar_vch_scoreboard['reg_used'];
			ship_cost -= covered;
			ship_covered += covered;
		}
	}

	// hmmm, something above causes ship_covered to be a string. should not, don't know what, so casting here.
	ship_covered = parseFloat(ship_covered);
	return ship_covered;
}

function shipping_page_set_fillopt(fillopt){
	// PDR: changed so that ALL options are written into tables id'd "options[fillopt]"
	// Algorithm: show the given table (remove "hide" from class), hide any other
	// table (add "hide" to class), and check radio buttons as associated
	// We ONLY do this for fillopt == A | D, so take that into account

	if (!document.getElementById) return;
	var e = document.getElementById("options" + fillopt);
	if (!e) return;
	if (fillopt == "D") var eOther = "A";
	else var eOther = "D";
	var eOther = document.getElementById("options" + eOther);
	if (!eOther) return;

	// e = table element containing the fillopt options; eOther = table element containing the to-be-hidden options
	// If the to-be-hidden table has a radio button checked we want to un-check it (PERIOD - whether it has an associated
	// to-be-shown radio button or not). If the to-be-shown table has an associated rb (same value) we want to check it.
	// This is not as bad as it sounds because we can just iterate the inputs and if the name is SHIPTYPE we have a winner.

	var inputsOther = eOther.getElementsByTagName("INPUT");
	if (!inputsOther)	return;
	var typeChecked = false;
	for (var i = 0; i < inputsOther.length; ++i)
	{
		if (inputsOther[i].name == "SHIPTYPE" && inputsOther[i].checked)
		{
			typeChecked = inputsOther[i].value;
			inputsOther[i].checked = false;
			break;
		}
	}

	addClass(eOther, "hide");
	removeClass(e, "hide");

	if (typeChecked)
	{
		var inputs = e.getElementsByTagName("INPUT");
		if (inputs)
		{
			for (var i = 0; i < inputs.length; ++i)
			{
				if (inputs[i].name == "SHIPTYPE" && inputs[i].value == typeChecked)
				{
					inputs[i].checked = true;
					break;
				}
			}
		}
		shipping_page_set_shiptype(fillopt, typeChecked);
	}

	return true;
}

function shipping_page_init(need_payment_info,need_billing_adr,show_static_billing){

	// hide appropriate divs based on parms
	if( ! need_payment_info ){
		document.getElementById('cc_info').style.display = 'none';
	}

	if( !show_static_billing ){
		document.getElementById('checkout_address_static').style.display = 'none';
	}

	if( need_billing_adr ){
		document.getElementById('checkout_address_static').style.display = 'none';
	}else{
		document.getElementById('bill_address_inputs').style.display = 'none';
		document.frmShipping.BILLINGINPUTS.value = '0';
	}

	// do we have a fill option and/or a fill option checked?
	// if so, set price display values for prices.
	if( document.frmShipping.FILLOPTION ){
		if( document.frmShipping.FILLOPTION[0].checked )
			shipping_page_set_fillopt('D');
		else
			shipping_page_set_fillopt('A');
	}else{
		shipping_page_set_fillopt('O');
	}

	if( document.frmShipping.BILLSHIPPERACCOUNT ){
		if( ! document.frmShipping.BILLSHIPPERACCOUNT[1].checked ){
			document.getElementById('shipper_account').style.display='none';
		}
	}
	return true;

}

function set_shipping_account_vis( newvis ){

	document.getElementById('shipper_account').style.display=newvis;
	if (newvis != 'none' && document.frmShipping.SHIPTYPE){
		if(document.frmShipping.SHIPTYPE.length){
			for( i=0; i < document.frmShipping.SHIPTYPE.length; i++ ){
				if(document.frmShipping.SHIPTYPE[i].checked){
					document.frmShipping.SHIPTYPE[i].checked = false;
				}
				document.frmShipping.SHIPTYPE[i].disabled=true;
			}
		}
		else{
			if(document.frmShipping.SHIPTYPE.checked){
				document.frmShipping.SHIPTYPE.checked = false;
			}
			document.frmShipping.SHIPTYPE.disabled=true;
		}
		shipping_page_set_shiptype(null, null);
	}
	else if(document.frmShipping.SHIPTYPE){
		if(document.frmShipping.SHIPTYPE.length){
			for( i=0; i < document.frmShipping.SHIPTYPE.length; i++ ){
				document.frmShipping.SHIPTYPE[i].disabled=false;
			}
		}
		else{
			document.frmShipping.SHIPTYPE.disabled=false;
		}
	}
}

/**
 * Validate Address form data.
 *
 * (could smarten up a little with real validation of US ZIP codes).
 */
function validate_frmAddress(frm){

	if( ! frm ) return false;

	if( frm.BILLINGINPUTS ){

		var checkBillCity = frm.BILLINGCITY.value.trim();
		checkBillCity = checkBillCity.toUpperCase();
		var checkBillState = frm.BILLINGSTATE[frm.BILLINGSTATE.selectedIndex].value.trim();

		if(frm.BILLINGFIRSTNAME.value.trim() == '' ){
			return DoFail( frm.BILLINGFIRSTNAME, "Please enter a Billing Address First Name" );
		}
		if(frm.BILLINGLASTNAME.value.trim() == '' ){
			return DoFail( frm.BILLINGLASTNAME, "Please enter a Billing Address Last Name" );
		}
		if(frm.BILLINGADDRESS1.value.trim() == '' ){
			return DoFail( frm.BILLINGADDRESS1, "Please enter a Billing Address Line 1" );
		}
		if(frm.BILLINGCITY.value.trim() == '' ){
			return DoFail( frm.BILLINGCITY, "Please enter a Billing Address City" );
		}
		if(frm.BILLINGCOUNTRY[frm.BILLINGCOUNTRY.selectedIndex].value.trim() == '' ){
			return DoFail( frm.BILLINGCOUNTRY, "Please select a Billing Address Country" );
		}

		var us = (frm.BILLINGCOUNTRY.options[frm.BILLINGCOUNTRY.selectedIndex].value == 'US');

		if(checkBillCity == 'APO' || checkBillCity == 'FPO'){
			if(checkBillState!='AA' && checkBillState!='AE' && checkBillState!='AP'){
				return DoFail( frm.BILLINGSTATE, "Please select Billing Address State of Armed Forces (AA, AE, or AP) for APO/FPO addresses" );
			}
			if(frm.BILLINGCOUNTRY[frm.BILLINGCOUNTRY.selectedIndex].value != 'US'){
				return DoFail( frm.BILLINGCOUNTRY, "Please select Billing Address Country of United States for APO/FPO addresses" );
			}
		}
		else if(us){
			if(checkBillState==''){
				return DoFail( frm.BILLINGSTATE, "Please select a Billing Address State" );
			}
			if(frm.BILLINGZIP.value.trim() == '' ){
				return DoFail( frm.BILLINGZIP, "Please enter a Billing Address Zip/Postal Code" );
			}
		}
		else{
			if(checkBillState!=''){
				return DoFail( frm.BILLINGSTATE, "Please do NOT select a Billing Address State when Billing Address Country is not United States" );
			}
			if(frm.BILLINGZIP.value.trim() == '' ){
				/*
				if(!confirm("Billing Address Zip/Postal Code is missing. Continue without one?")){
					frm.BILLINGZIP.focus();
					return false;
				}
				*/
				/* Allow blank non-US postal (eg Lebanon, Afghanistan, etc).
				 * return DoFail( frm.BILLINGZIP, "Please enter a Billing Address Zip/Postal Code" );
				 */

			}
		}

		var billhomephone = frm.BILLINGPHONEHOME.value.replace(/[^\d]+/g, '');
		if( billhomephone == '' )
			return DoFail( frm.BILLINGPHONEHOME, "Please enter a Billing Address Home Phone" );
		else{
			if(!us && billhomephone.length > 15 )
				return DoFail( frm.BILLINGPHONEHOME, "Maximum length for Billing Address Home Phone is fifteen digits" );
			if (us && !/^1?\d{10}$/.test(billhomephone))
				return DoFail( frm.BILLINGPHONEHOME, "The maximum length for a US Billing Address Home Phone is ten digits" );
		}

		var billworkphone = frm.BILLINGPHONEWORK.value.replace(/[^\d]+/g, '');
		if(!us && billworkphone.length > 15 )
			return DoFail( frm.BILLINGPHONEWORK, "Maximum length for Billing Address Work Phone is fifteen digits" );
		if (us && billworkphone.length > 0 && !/^1?\d{10}$/.test(billworkphone))
			return DoFail( frm.BILLINGPHONEWORK, "THe maximum length for a US Billing Address Work Phone is ten digits" );

		var billworkphoneext = frm.BILLINGWORKEXT.value.replace(/[\(\) -]/g, '');  // This matches server-side validation. Non-sensical, maybe, but consistently so.
		if( ! /^\d{0,5}$/.test(billworkphoneext) )
			return DoFail( frm.BILLINGWORKEXT, "Maximum length for Billing Address Work Phone Extention is five digits" );
	}

	if( frm.SHIPPINGINPUTS ){

		var validate_shipping = (frm.SHIPPINGINPUTS && ! frm.SHIPPINGS2B);
		var school_shipping = false;
		var store_shipping = false;

		if( frm.SHIPPINGS2B ){
			if( frm.SHIPPINGS2B[0] && frm.SHIPPINGS2B[0].type == 'radio' ){

				var ctrl = frm.SHIPPINGS2B;
				var shippingSelected = false;
				var radioCount = ctrl.length;

				for (var i=0; i < radioCount; i++) {
					if (ctrl[i].checked) {
						if (ctrl[i].value == 'sameasbill')
							validate_shipping = false;
						else if (ctrl[i].value == 'unlikebill')
							validate_shipping = true;
						else if (ctrl[i].value == 'school') {
							validate_shipping = true;
							school_shipping = true;
						}
						else if (ctrl[i].value == 'store') {
							validate_shipping = true;
							store_shipping = true;
						}

						shippingSelected = true;
						break;
					}
				}

				if (!shippingSelected)
					return DoFail( ctrl[0], "Please select a Shipping Location." );

			}
			else if( frm.SHIPPINGS2B.type == 'checkbox' ){
				validate_shipping = (frm.SHIPPINGS2B && ! frm.SHIPPINGS2B.checked);
			}
			else if( frm.SHIPPINGS2B.type == 'hidden' ){
				var ctrl = frm.SHIPPINGS2B;

				if (ctrl.value == 'sameasbill')
					validate_shipping = false;
				else if (ctrl.value == 'unlikebill')
					validate_shipping = true;
				else if (ctrl.value == 'school') {
					validate_shipping = true;
					school_shipping = true;
				}
				else if (ctrl.value == 'store') {
					validate_shipping = true;
					store_shipping = true;
				}
			}
		}

		if( validate_shipping ){ // shipping to shipping address.

			var checkShipCity = frm.SHIPPINGCITY.value.trim();
			checkShipCity = checkShipCity.toUpperCase();
			var checkShipState = frm.SHIPPINGSTATE[frm.SHIPPINGSTATE.selectedIndex].value.trim();

			if (school_shipping) {
				if(frm.SHIPPINGSTOREFIRSTNAME.value.trim() == '' )
					return DoFail( frm.SHIPPINGSTOREFIRSTNAME, "Please enter a Shipping Address First Name" );
				if(frm.SHIPPINGSTORELASTNAME.value.trim() == '' )
					return DoFail( frm.SHIPPINGSTORELASTNAME, "Please enter a Shipping Address Last Name" );
			}
			else if(!store_shipping) {
				if(frm.SHIPPINGFIRSTNAME.value.trim() == '' )
					return DoFail( frm.SHIPPINGFIRSTNAME, "Please enter a Shipping Address First Name" );
				if(frm.SHIPPINGLASTNAME.value.trim() == '' )
					return DoFail( frm.SHIPPINGLASTNAME, "Please enter a Shipping Address Last Name" );
			}

			if (!store_shipping && !school_shipping) {
				if(frm.SHIPPINGADDRESS1.value.trim() == '' ){
					return DoFail( frm.SHIPPINGADDRESS1, "Please enter a Shipping Address Line 1" );
				}
				if(checkShipCity == '' ){
					return DoFail( frm.SHIPPINGCITY, "Please enter a Shipping Address City" );
				}
				if(frm.SHIPPINGCOUNTRY[frm.SHIPPINGCOUNTRY.selectedIndex].value.trim() == '' ){
					return DoFail( frm.SHIPPINGCOUNTRY, "Please select a Shipping Address Country" );
				}
				if(checkShipCity == 'APO' || checkShipCity == 'FPO'){
					if(checkShipState!='AA' && checkShipState!='AE' && checkShipState!='AP'){
						return DoFail( frm.SHIPPINGSTATE, "Please select Shipping Address State of Armed Forces (AA, AE, or AP) for APO/FPO addresses" );
					}
					if(frm.SHIPPINGCOUNTRY[frm.SHIPPINGCOUNTRY.selectedIndex].value != 'US'){
						return DoFail( frm.SHIPPINGCOUNTRY, "Please select Shipping Address Country of United States for APO/FPO addresses" );
					}
				}
				else if(frm.SHIPPINGCOUNTRY[frm.SHIPPINGCOUNTRY.selectedIndex].value == 'US'){
					if(checkShipState==''){
						return DoFail( frm.SHIPPINGSTATE, "Please select a Shipping Address State" );
					}
					if(frm.SHIPPINGZIP.value.trim() == '' ){
						return DoFail( frm.SHIPPINGZIP, "Please enter a Shipping Address Zip/Postal Code" );
					}
				}
				else{
					if(checkShipState!=''){
						return DoFail( frm.SHIPPINGSTATE, "Please do NOT select a Shipping Address State when Shipping Address Country is not United States" );
					}
					if(frm.SHIPPINGZIP.value.trim() == '' ){
						/*
						if(!confirm("Shipping Address Zip/Postal Code is missing. Continue without one?")){
							frm.SHIPPINGZIP.focus();
							return false;
						}
						*/
						/* Allow blank non-US postal (eg Afghanistan and Lebanon do not use postal codes)
						 * return DoFail( frm.SHIPPINGZIP, "Please enter a Shipping Address Zip/Postal Code" );
						 */
					}
				}
			}

			if ( frm.BILLINGPHONEHOME ) {
				var us = (frm.SHIPPINGCOUNTRY[frm.SHIPPINGCOUNTRY.selectedIndex].value == 'US');
				var billhomephone = frm.BILLINGPHONEHOME.value.replace(/[^\d]+/g, '');
				if( billhomephone == '' )
					return DoFail( frm.BILLINGPHONEHOME, "Please enter a Shipping Address Home Phone" );
				else{
					if(!us && billhomephone.length > 15 )
						return DoFail( frm.BILLINGPHONEHOME, "Maximum length for Shipping Address Home Phone is fifteen digits" );
					if (us && !/^1?\d{10}$/.test(billhomephone))
						return DoFail( frm.BILLINGPHONEHOME, "The maximum length for a US Shipping Address Home Phone is ten digits" );
				}
			}
		}
	}

	if( frm.email && frm.email.type == 'text'){

		if (frm.emailoptional && frm.emailoptional.value == 'yes'){
			if( frm.email.value.trim() != '' && !frm.email.value.trim().isEmail()){
				return DoFail(frm.email, "Your Email Address must be a valid email address.");
			}
		}
		else{
			if( frm.email.value.trim() == '' ){
				return DoFail(frm.email, "You must enter your Email Address.");
			}
			if( !frm.email.value.trim().isEmail()){
				return DoFail(frm.email, "Your Email Address must be a valid email address.");
			}
		}
	}

	if( frm.PWORD ){
		if( ! frm.PWORD.value.isVBPassword() ){
			return DoFail( frm.PWORD, "Password must be 5-10 characters long and consist of letters and/or numbers");
		}

		if( frm.PWORD.value != frm.PWORDV.value){
			return DoFail( frm.PWORD, "Password and Password verification do not match");
		}
	}

	if( frm.NAMEINPUTS ){
		if(frm.BILLINGFIRSTNAME.value.trim() == '' ){
			return DoFail( frm.BILLINGFIRSTNAME, "Please enter a First Name" );
		}
		if(frm.BILLINGLASTNAME.value.trim() == '' ){
			return DoFail( frm.BILLINGLASTNAME, "Please enter a Last Name" );
		}
	}

	if( frm.fvvchid ){

		var vch_id_desc = frm.vch_id_desc.value.trim();

		if( vch_id_desc == '' ) vch_id_desc = 'Voucher ID';

		if (frm.fvvchid.value.trim() == '' )
			return DoFail(frm.fvvchid, "You must enter a " + vch_id_desc + ".");
	}

	alreadySubmitted = true;
	$("#page-footer .step-button").text('Submitting...');

	return true;
}

function validate_frmShipping(){
	if (alreadySubmitted) {
		alert("Please wait while we gather your information.");
		return false;
	}

	// need ship type selected
	if( !document.frmShipping.BILLSHIPPERACCOUNT || (document.frmShipping.BILLSHIPPERACCOUNT && document.frmShipping.BILLSHIPPERACCOUNT[0].checked) ){
		if( document.frmShipping.SHIPTYPE ){

			if (document.frmShipping.SHIPTYPE[0]) {
				// check multiple radio buttons
				var shiptype_checked = false;
				for (i=0; i < document.frmShipping.SHIPTYPE.length; i++) {
					if (document.frmShipping.SHIPTYPE[i].checked) {
						shiptype_checked = true;
						break;
					}
				}
				if (!shiptype_checked) {
					DoFail( document.frmShipping.SHIPTYPE[0], "Please select a Shipping Method" );
					return false;
				}
			}
			else {
				// check one radio button or text
				var shiptype_checked = false;

				if (document.frmShipping.SHIPTYPE.type == 'radio') {
					if (document.frmShipping.SHIPTYPE.checked)
						shiptype_checked = true;
				}
				else if (document.frmShipping.SHIPTYPE.value.trim() != '')
					shiptype_checked = true;

				if (!shiptype_checked) {
					DoFail( document.frmShipping.SHIPTYPE, "Please select a Shipping Method" );
					return false;
				}
			}

		}
	}

	if( document.getElementById('cc_info').style.display != 'none' ){

		if( !document.frmShipping.CCPAYROLL || document.frmShipping.CCPAYROLL.checked == false){

			var ccType = document.frmShipping.CCTYPE.value.trim();
			if( ccType == '' ){
				DoFail( document.frmShipping.CCTYPE, "Please select a Credit Card type" );
				return false;
			}

			var ccNum = document.frmShipping.CCNUM.value.trim();
			if( ccNum == '' ){
				DoFail( document.frmShipping.CCNUM, "Please enter a Credit Card number" );
				return false;
			}
			else if (!ccNum.isCCN(ccType)) {
				var name = (ccType == 'V') ? 'Visa' : (ccType == 'M') ? 'Mastercard'
					: (ccType == 'D') ? 'Discover' : 'American Express';
				DoFail( document.frmShipping.CCNUM, "Please enter a valid " + name
					+ " Credit Card number." );
				return false;
			}

			if( document.frmShipping.CCEXPMON.value.trim() == '' ){
				DoFail( document.frmShipping.CCEXPMON, "Please enter data for a non-expired credit card." );
				return false;
			}

			if( document.frmShipping.CCEXPYEAR.value.trim() == '' ){
				DoFail( document.frmShipping.CCEXPYEAR, "Please enter data for a non-expired credit card." );
				return false;
			}

			var month = parseInt(document.frmShipping.CCEXPMON.value.replace(/^0*(\d+)$/, '$1'));
			var year = parseInt(document.frmShipping.CCEXPYEAR.value);
			var d = new Date();
			expdate = d.getDate();
			var exp = new Date();
			exp.setFullYear(year, month-1, expdate);

			if (exp < d) {
				alert("Please enter data for a non-expired credit card.");
				return false;
			}

			if( document.frmShipping.CCCODE ) {
				var ccv = document.frmShipping.CCCODE.value.trim();
				if (ccv == '' )
				{
					DoFail( document.frmShipping.CCCODE, "Please enter a Credit Card Security Code" );
					return false;
				}
				if (! ccv.isCCV(ccType)) {
					DoFail( document.frmShipping.CCCODE, "Please enter a valid Credit Card Security Code" );
					return false;
				}
			}
		}
	}

	if( document.getElementById('bill_address_inputs').style.display == 'block' ){

		if(document.frmShipping.BILLINGFIRSTNAME.value.trim() == '' ){
			DoFail( document.frmShipping.BILLINGFIRSTNAME, "Please enter a Billing Address First Name" );
			return false;
		}
		if(document.frmShipping.BILLINGLASTNAME.value.trim() == '' ){
			DoFail( document.frmShipping.BILLINGLASTNAME, "Please enter a Billing Address Last Name" );
			return false;
		}
		if(document.frmShipping.BILLINGADDRESS1.value.trim() == '' ){
			DoFail( document.frmShipping.BILLINGADDRESS1, "Please enter a Billing Address Line 1" );
			return false;
		}
		if(document.frmShipping.BILLINGCITY.value.trim() == '' ){
			DoFail( document.frmShipping.BILLINGCITY, "Please enter a Billing Address City" );
			return false;
		}
		if(document.frmShipping.BILLINGSTATE.selectedIndex < 1 ){
			DoFail( document.frmShipping.BILLINGSTATE, "Please select a Billing Address State" );
			return false;
		}
		if(document.frmShipping.BILLINGCOUNTRY.selectedIndex < 1 ){
			DoFail( document.frmShipping.BILLINGCOUNTRY, "Please select a Billing Address Country" );
			return false;
		}
		if(document.frmShipping.BILLINGZIP.value.trim() == '' ){
			DoFail( document.frmShipping.BILLINGZIP, "Please enter a Billing Address Zip/Postal Code" );
			return false;
		}
		if( document.frmShipping.BILLINGPHONEHOME.value.trim() == '' ){
			DoFail( document.frmShipping.BILLINGPHONEHOME, "Please enter a Billing Address Home Phone" );
			return false;
		}
		else{
			if(frm.BILLINGPHONEHOME.value.trim().length > 11 ){
				return DoFail( frm.BILLINGPHONEHOME, "Maximum length for Billing Address Home Phone is eleven digits" );
			}
		}
	}

	if( document.frmShipping.BILLSHIPPERACCOUNT ){
		if( document.frmShipping.BILLSHIPPERACCOUNT[1].checked ){
			if( document.frmShipping.SHIPPERACCOUNT.value.trim() == '' ){
				DoFail( document.frmShipping.SHIPPERACCOUNT, "Please enter a Shipper Account Number" );
				return false;
			}
		}
	}

	if (document.frmShipping.external_cust_id) {
		if (document.frmShipping.external_cust_id.value.trim() == 'Please enter your student ID here.') {
			document.frmShipping.external_cust_id.value = '';
		}

		if (document.frmShipping.external_cust_id.value.trim() == '') {
			DoFail( document.frmShipping.external_cust_id, "Please enter your student ID" );
			return false;
		}
	}

	alreadySubmitted = true;

	with (document.frmShipping) {
		if (CCNUM) {
			CCNUM_post.value = CCNUM.value;
			CCNUM.value = '';
		}
		if (CCCODE) {
			CCCODE_post.value = CCCODE.value;
			CCCODE.value = '';
		}
	}
	return true;

}

function CanSubmitRegion(frm) {
	var ctl = frm.FVCUSNO;
	for (var i = 0; i < ctl.length; i++)
		if (ctl[i].checked) return true;
	alert("Please select your region.");
	return false;
}

function CanUpdateShopCart(frm) {
	if (alreadySubmitted) {
		alert("Please wait while we process your request.\n"
			+ "If you got here by backing up, try using the My Cart "
			+ "menu item and make your changes there.");
		return false;
	}
	var idx = 1;
	while (eval("frm.FVNUM_" + idx)) {
		var ctl = eval("frm.FVSEQ_" + idx);
		if (ctl && ctl.checked) {
			alreadySubmitted = true;
			return true;
		}
		idx++;
	}

	alert("Nothing to do.");
	return false;
}

function CanModifyCreditCard(frm) {
	var ctl = frm.CTFULLNAME;
	if (ctl.value.trim() == '') {
		ctl.focus();
		alert('Please enter your Name (as it appears on card).');
		return false;
	}
	ctl = frm.CTTYPE;
	if (ctl.selectedIndex < 1) {
		ctl.focus();
		alert('Please select the Credit Card Type.');
		return false;
	}
	var ctype = ctl.value;
	var cName = ctl.options[ctl.selectedIndex].text.trim();
	ctl = frm.CTNUMBER;
	if (ctl.value.trim() == '') {
		ctl.focus();
		alert('Please enter your Credit Card Number.');
		return false;
	}
	if (!ctl.value.isCCN(ctype)) {
		ctl.focus();
		alert('Please enter a valid ' + cName + ' Credit Card Number.');
		return false;
	}
	ctl = frm.CTEXPMONTH;
	var month = parseInt(ctl.value);
	var year = parseInt(frm.CTEXPYEAR.value);
	var d = new Date();
	var expdate = d.getDate();
	var exp = new Date();
	exp.setFullYear(year, month-1, expdate);
	if (exp < d) {
		ctl.focus();
		alert("Please change your Credit Card Expiration date, or enter the data for an un-expired credit card.");
		return false;
	}
	return true;
}

function CanDeleteCreditCard(frm) {
	for (var i = 0; i < frm.delete_me.length; i++)
		if (frm.delete_me[i].checked)
			return true;
	alert('In order to delete your credit card information you must first check the "Yes, I want to delete it" radio button.'
		+ "\n"
		+ 'If you want to leave it on record and return to the previous screen you must first check the '
		+ '"No, I want to keep my credit card information" radio button.');
	return false;
}

function validate_vch_inputs(frm){

	var submitButton = $("#CHTP_vchSubmit");
	if (submitButton.length) {
		// if not showing 'Continue', inputs have not been shown
		if (submitButton.val() != 'Continue') {
			submitButton.val('Continue');
			submitButton.next('span').html('Continue');
			// inputs are shown via simpler-trigger binding
			return false;
		}
	}

	if( frm.vch_stu ){
		if( frm.vch_stu.value.trim() == '' ){
			DoFail( frm.vch_stu, "Please enter your SFA information." );
			return false;
		}
	}
	if( frm.vch_id.value.trim() == '' ){
		DoFail( frm.vch_id, "Please enter your SFA information." );
		return false;
	}
	if (frm.vch_stu) {
		frm.vch_stu_post.value = frm.vch_stu.value;
		frm.vch_stu.value = '';
	}
	frm.vch_id_post.value = frm.vch_id.value;
	frm.vch_id.value = '';
	return true;
}

function RemoveLastWord(node) {
	// Return codes:
	//	0 = OK, removed a word and am done
	//	1 = OK, removed a word but remove node from it's parent
	//	-1 = Did not remove a word; remove node from it's parent
	if (!node || !node.nodeType) return -1;
	if (node.nodeType == 1) {	// an element
		while (node.lastChild) {
			var n = RemoveLastWord(node.lastChild);
			if (n == 0) return 0;
			if (n == 1) {
				try {
					node.removeChild(node.lastChild);
				} catch(e) {
					IEremoveChild(node.lastChild);
				}
				if (!node.lastChild) return 1;
				else return 0;
			} else {
				try {
					node.removeChild(node.lastChild);
				} catch(e) {
					IEremoveChild(node.lastChild);
				}
			}
		}
		return -1;
	}
	else if (node.nodeType == 3) {	// a text node
		var text = node.nodeValue;
		if (/\S+\s+\S+/.test(text)) {
			// has multiple words
			node.nodeValue = text.replace(/\s+\S+\s*$/, '').trim();
			return 0;
		}
		else if (/^\s*$/.test(text))
			// is all whitespace
			return -1;
		else
			// is a single word
			return 1;
	}
	else if (node.nodeType == 5) {	// an entity reference
		return 1;
	}
	else
		return -1;
}

function IEremoveChild(node) {
	return node.parentNode.removeChild(node);
}

function ShrinkMessages() {
	expandedMessages = new Array();
	if (!document.getElementsByTagName) return;
	var divs = document.getElementsByTagName('div');
	if (!divs || !divs.length) return;

	for (var i = 0; i < divs.length; i++) {
		var div = divs[i];
		if (/^.*Messaging$/.test(div.className)) {

			/* This is a message-type div; shrink it */

			// find the line-height to calculate number of lines against
			var lineHeight = 12;
			var original = div.innerHTML;
			div.innerHTML = '&nbsp;';
			var thisHeight = $(div).height();
			if (thisHeight > lineHeight)
				lineHeight = thisHeight;
			div.innerHTML = original;

			var height = $(div).height();	// was: div.offsetHeight
			var lines = Math.round(height / lineHeight);

			if (height && lines > max_unshrunk_lines) {
				/* Hide the div so it is not visibly twitching on the screen */
				div.visibility = 'hidden';
				var expanded = div.innerHTML.trim();	/* this is the original content */
				var currentContent = '';
				var count = 0; /* just to be sure we do not end up with an endless loop */
				var retcode = -1;
				while (lines > num_shrunk_lines) {
					if (++count > 1000) break;	/* Only remove up to 1000 words */
					retcode = RemoveLastWord(div);
					if (retcode != 0) break;	/* For one reason or another could not remove last word */

					/* We have to add the '...click to expand' text so we can tell if it makes
					 * a wrap and adds another line. */
					currentContent = div.innerHTML;
					div.innerHTML += '<a class="expandor" href="#">... click to expand &raquo;</a>';

					/* Re-calculate the number of lines */
					height = $(div).height();	// was: div.offsetHeight
					lines = Math.round(height / lineHeight);

					/* Remove the '... click to expand' text because we will keep looping. */
					div.innerHTML = currentContent;
				}

				if (lines > num_shrunk_lines || retcode != 0) {
					/* Cannot shrink the message, revert back to original content */
					div.innerHTML = expanded;
				}
				else {
					/* Our data will be appended to expandedMessages[], so the index to our data
					 * is the current length of expandedMessages[] */
					var ofs = expandedMessages.length;
					/* Append a '... click to collapse' element */
					expanded += '<a class="expandor" href="javascript:ShrinkThisMessage(' + ofs + ')">... click to collapse &laquo;</a>';
					var shrunk = div.innerHTML + '<a class="expandor" href="javascript:ExpandMessage(' + ofs + ')">... click to expand &raquo;</a>';
					expandedMessages[ofs] = new Array(div, expanded, shrunk);
					div.innerHTML = shrunk;
				}
				div.visibility = 'visible';
			}
		}
	}
}

function ExpandMessage(idx) {
	if (idx >= 0 && expandedMessages[idx] && expandedMessages[idx][0] && expandedMessages[idx][1]) {
		var div = expandedMessages[idx][0];
		var markup = expandedMessages[idx][1];
		div.innerHTML = markup;
	}
}

function ShrinkThisMessage(idx) {
	if (idx >= 0 && expandedMessages[idx] && expandedMessages[idx][0] && expandedMessages[idx][2]) {
		var div = expandedMessages[idx][0];
		var markup = expandedMessages[idx][2];
		div.innerHTML = markup;
	}
}

/**
 * Validate Email update form data.
 *
 *
 */
function validate_accountEmail(frm){

	if( ! frm ) return false;

	if(frm.fvOriginalEmailAddress.value.trim() == '' ){
		return DoFail( frm.fvOriginalEmailAddress, "Please enter your Current Email Address" );
	}
	if(frm.fvEmailAddress.value.trim() == '' ){
		return DoFail( frm.fvEmailAddress, "Please enter your New Email Address" );
	}
	if(frm.fvConfirmEmailAddress.value.trim() == '' ){
		return DoFail( frm.fvConfirmEmailAddress, "Please Confirm your New Email Address" );
	}
	if(frm.fvEmailAddress.value.trim() != frm.fvConfirmEmailAddress.value.trim()){
		return DoFail( frm.fvEmailAddress, "New Email Addresses do not match. Please re-enter your New Email Address" );
	}
	if( ! frm.fvEmailAddress.value.isEmail() ){
		return DoFail( frm.fvEmailAddress, "Please enter a valid email Address" );
	}

	return true;
}


/**
 * Validate Password update form data.
 *
 */
function validate_accountPassword(frm){

	if( ! frm ) return false;

	if(frm.fvOriginalPassword.value.trim() == '' ){
		return DoFail( frm.fvOriginalPassword, "Please enter your Current Password" );
	}
	if(frm.fvPassword.value.trim() == '' ){
		return DoFail( frm.fvPassword, "Please enter your New Password" );
	}
	if( !frm.fvPassword.value.isVBPassword() ){
		return DoFail( frm.fvPassword, "Your password must be 5-10 letters and/or numbers." );
	}
	if(frm.fvConfirmPassword.value.trim() == '' ){
		return DoFail( frm.fvConfirmPassword, "Please Confirm your New Password" );
	}
	if(frm.fvPassword.value.trim() != frm.fvConfirmPassword.value.trim()){
		return DoFail( frm.fvPassword, "New Passwords do not match. Please re-enter your New Password" );
	}

	return true;
}


/**
 * Validate Email Prefs form data.
 *
 */
function validate_accountEmailPrefs(frm){

	if( ! frm ) return false;

	if ( ! (frm.fvEmailType[0].checked || frm.fvEmailType[1].checked ) ){
		return DoFail( frm.fvEmailType[0], "Please select your Prefered Email type." );
	}
	return true;
}


/**
 * Validate School Prefs form data.
 *
 *
 */
function validate_accountSchoolPrefs(frm){

	if( ! frm ) return false;

	if( ! ValidateLevelOfStudy(frm) )
		return false;

	// Do not force Grad Year selection for Faculty
	if ( !(frm.fvEducationLevel.length == 11 && frm.fvEducationLevel[9].checked) ){
		if (frm.fvGradYear.value.trim() == ''){
			return DoFail(frm.fvGradYear,"Please select your Expected Graduation Year.");
		}
	}

	if ( ! ValidateMyInterests(frm) )
		return false;

	return true;
}

function ValidateLevelOfStudy(frm){
	var temp = 0;
	var temp2;

	for (i=0;i<11;i++){
		if ( frm.fvEducationLevel[i].checked == true){
			temp = temp + 1;
			temp2 = frm.fvEducationLevel[i].value;
		}
	}

	if (temp == 0){
		return DoFail(frm.fvEducationLevel[0], "Please select your Level of Study.");
	}

	if (temp2 == 'O'){
		if (frm.fvOther.value.trim() == ''){
			return DoFail(frm.fvOther, "Please provide a short description for your Level of Study.");
		}
	}

	return true;
}


function ValidateMyInterests(frm){

	if (frm.fvGeneralArea.value == -1){
		return DoFail(frm.fvGeneralArea, "Please select a General Area of Study or Interest.");
	}

	var item = "fvInterestArea" + frm.fvGeneralArea.value + "[]";
	var valid = false;
	for(i=0;i<frm[item].length;i++){
		if(frm[item][i].checked){
			valid = true;
			break;
		}
	}

	if( !valid ){
		return DoFail(frm[item][0], "Please choose a Specific Area of Study or Interest");
	}

	return true;
}

/**
 * Show/Hide Bundle Details
 */

function findPos(obj) {
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		do {
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
		} while (obj = obj.offsetParent);
	}
	return [curleft,curtop];
}

function hideBundle(id) {
	if (!document.getElementById) return;
	var elem = document.getElementById(id);
	if (!elem) return;
	elem.style.display = 'none';
	curDetailsShowing = false;
}

function showBundle(cell, id) {
	if (curDetailsShowing) {
		if (id == curDetailsId) return;
		hideBundle(curDetailsId);
	}

	if (!document.getElementById) return;
	var elem = document.getElementById(id);
	if (!elem) return;

	var coords = findPos(cell);
	var x = coords[0];
	var y = coords[1] + cell.offsetHeight + 4;

	elem.style.left = x + 'px';
	elem.style.top = y + 'px';
	elem.style.display = 'block';

	curDetailsId = id;
	curDetailsShowing = true;
}

function confirm_logout(has_cart){

	var str = 'You have selected to log off of the Online Bookstore.\n';

	if (has_cart)
		str += 'All inventory you have reserved in your cart will be released.\n';

	str += '\nContinue?';

	if(confirm(str))		return true;
	else					return false;
}

function CanEmailVoucher(frm) {
	var ctl = document.email_voucher.stuid;
	if (ctl.value.trim().length == 0) {
		ctl.focus();
		alert("Please enter your " + student_id_name + ".");
		return false;
	}
	return true;
}

function checkProxyLogin(frm) {

	if (frm.fvStudentIDLogIn.value.trim() != "")
		return StudentIDOkay(frm.fvStudentIDLogIn);
	else if (frm.fvEmailLogIn.value.trim() != "") {
		return EmailOkay(frm.fvEmailLogIn);
	}

	return true;
}

/**********************
 * Lightbox functions *
 **********************/

function tbShowLightbox(sHtml, sHeading, blnContentContainsClose) {

	// find our fade element
	thisEl = document.getElementById('fade');

	// return if the element is already shown
	if (!thisEl || thisEl.style.display == 'block')
		return;

	var sLBContent	= new String("");

	blnContentContainsClose	= (blnContentContainsClose == null)?false:blnContentContainsClose;

	if (sHeading != null && sHeading != "") {
		sLBContent	= "<b>"+sHeading+"</b><P>";
	}

	sLBContent	+= sHtml;

	document.getElementById('divLBC').className	= (blnContentContainsClose)?'hid':'lbClose';
	document.getElementById('lbCnt').className	= 'lbContent';
	document.getElementById('lbCnt').innerHTML	= sLBContent;
	high(document.getElementById('light'));

	thisEl.style.display = 'block';

	floatSideBar('light');
}

function tbHideLightbox() {

	// find our fade element
	thisEl = document.getElementById('fade');

	// return if the element is already hidden
	if (!thisEl || thisEl.style.display == 'none')
		return;

	low(document.getElementById('light'));

	thisEl.style.display ='none';
}

/* OPACITY RELATED */
function opacity(id, opacStart, opacEnd, millisec, whichDir) {

	if (window.opacTimer)
		clearTimeout(opacTimer);

	//speed for each frame
	var speed = 30; // Math.round(millisec / 100);

	changeOpac(opacStart, id);

    //determine the direction for the blending, if start and end are the same nothing happens
    if (whichDir < 0) {
	if (opacStart == 0) {
		document.getElementById(id).style.display	= 'none';
	}
	else {
		opacStart	= opacStart-10;
		if (opacStart <= 0) opacStart = 0;

		opacTimer	= setTimeout("opacity('"+id+"',"+opacStart+","+opacEnd+","+millisec+","+whichDir+")", speed);
	}
    }
    else {
	if (opacStart < 10)
		document.getElementById(id).style.display	= 'block';

	opacStart	= opacStart+10;
	if (opacStart >= 100) opacStart = 100;

	if (opacStart <= 100) {
		opacTimer	= setTimeout("opacity('"+id+"',"+opacStart+","+opacEnd+","+millisec+","+whichDir+")", speed);
	}
    }
}

//change the opacity for different browsers
function changeOpac(opacity, id) {
    var object = document.getElementById(id).style;
    object.opacity = (opacity / 100);
    object.MozOpacity = (opacity / 100);
    object.KhtmlOpacity = (opacity / 100);
    object.filter = "alpha(opacity=" + opacity + ")";
}

function high(which2) {
	opacity(which2.id, 0, 100, 50, 1)
}

function low(which2) {
	opacity(which2.id, 100, 0, 50, -1)
}

function floatSideBar(id) {
	if (id == null || String(id) == 'undefined') id = (lId != '')?lId:'light';
	//pageY, pageHeight, boxHeight
	var pY,pH,bH	= 'light';

	var pDims	= getDimsWH();
	var sDims	= getScrollXY();

	pY	=  sDims[1]; // (navigator.appName.indexOf("Netscape")!=-1)?pageYOffset:((nn&&document.html.scrollTop)?document.html.scrollTop:truebody().scrollTop);

	var lPx	= ((pDims[0]-document.getElementById(id).offsetWidth)/2);

//	if (pY != lPY || id != lId) { //they scrolled or new item called

	pH = pDims[1];
	bH = document.getElementById(id).offsetHeight;

	bY = (pH/2)-(bH/2)+pY;

	document.getElementById(id).style.top = bY+'px';
	document.getElementById(id).style.left = lPx+'px';

//	}
	lPY	= pY;
	lId	= id;

}

function getDimsWH() {
  var myWidth = 0, myHeight = 0;
//  if( typeof( window.innerWidth ) == 'number' ) {
  if( false ) {
    //Non-IE
    myWidth	= window.innerWidth;
    myHeight	= window.innerHeight;
  }
  else {
    //IE compatible
    myWidth	= truebody().clientWidth;
    myHeight= truebody().clientHeight;
  }
  return Array(myWidth,myHeight);
}

function getScrollXY() {
  var scrOfX = 0, scrOfY = 0;
  if( typeof( window.pageYOffset ) == 'number' ) {
    //Netscape compliant
    scrOfY = window.pageYOffset;
    scrOfX = window.pageXOffset;
  }
  else {
    // IE standards compliant mode
    scrOfY = truebody().scrollTop;
    scrOfX = truebody().scrollLeft;
  }
  return Array(scrOfX, scrOfY);
}

/**
* Determines which hierarchy to use for referring to the document body
*/
function truebody() {
	return (document.compatMode && document.compatMode!="BackCompat")?document.documentElement:document.body;
}

function init_external_cust_id() {
	if (document.frmShipping && document.frmShipping.external_cust_id) {
		eci = document.frmShipping.external_cust_id;

		if (eci.value.trim() == '') {
			eci.value = 'Please enter your student ID here.';
		}

		eci.onfocus = function(e) {
			if (this.value.trim() == 'Please enter your student ID here.') {
				this.value = '';
			}
		};

		eci.onblur = function(e) {
			if (this.value.trim() == '') {
				this.value = 'Please enter your student ID here.';
			}
		};
	}
}

