validEmail = /^[a-zA-Z0-9._\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,4}$/;


/*********************************************************************************
*														refreshFancyBox
*
*********************************************************************************/
function refreshFancyBox()
{
	if ($("a.LBlargerView").length > 0)
		$("a.LBlargerView").fancybox({
			'overlayShow'	: false,
			'transitionIn'	: 'elastic',
			'transitionOut'	: 'elastic',
			'titlePosition'	: 'inside'
		});


	if ($(".zoom").length > 0)
		$(".zoom").fancybox({
			'overlayShow'		: false,
			'width'				: 840,
			'height'			: 475,
			'autoScale'			: false,
			'transitionIn'		: 'elastic',
			'transitionOut'		: 'elastic',
			'type'				: 'iframe'
		});
}


/*********************************************************************************
*														addCommas
*
*********************************************************************************/
function addCommas(nStr)
{
	nStr2 = decimalOf(nStr);
	if (isNaN(nStr2))
		return " N/A";
	nStr2 += '';
	x = nStr2.split('.');
	x1 = x[0];
	x2 = x.length > 1 ? '.' + x[1] : '';
	var rgx = /(\d+)(\d{3})/;
	while (rgx.test(x1)) {
		x1 = x1.replace(rgx, '$1' + ',' + '$2');
	}
	return x1 + x2;
}


/*********************************************************************************
*														decimalOf
*
*********************************************************************************/
function decimalOf(n) {
	n = (n + 0.005) + "0";
	i = n.indexOf(".");
	n = n.substr(0, i+3);
	return n;
}


/*********************************************************************************
*														in_array
*
*********************************************************************************/
function in_array(needle, haystack) {
	var key = '';
	for (key in haystack) {
		if (haystack[key] == needle)
			return true;
	}
	return false;
}


/*********************************************************************************
*														quick_view
*
*********************************************************************************/
function quick_view(el, the_panel, the_color, the_window)
{
	var url = "/garage-doors/quick-view/" + the_panel;
	if (typeof the_color !== 'undefined') {
		url += "/" + all_colors[the_color][1];
		if (typeof the_window !== 'undefined')
			url += "/" + all_windows[the_window][1];
	}
	el.href = url;
	return true;
}


/*********************************************************************************
*														sizeToFeet
* convert feet-inches to integer feet; 7-3 -> 8
*********************************************************************************/
function sizeToFeet(s)
{
	var pair = s.split("-");
	var feet = pair[0];
	if (pair[1] > 0)
		++feet;	
	return feet;
}


/*********************************************************************************
*														setFavoritesSummary
*
*********************************************************************************/
function setFavoritesSummary(str)
{
	$("#favorites_summary").html(str);
}


/*********************************************************************************
*														browseSaveFave
* saves a step1 URL
*********************************************************************************/
function browseSaveFave(p)
{
// /garage-doors/choose-your-design/material/style/brand/color/panel
	var url = "/garage-doors/choose-your-design/" +
				all_panels[p][3] + "/" +	// material
				all_panels[p][7] + "/" +	// style
				all_panels[p][8] + "/" +	// brand
				all_colors[panel_colors[p]][1] + "/" +	// color
				all_panels[p][2];			// panel
	$.ajax({
			url: "/favorites/ajax_save_fave",
			data: {
				url: url
			},
			type: 'POST',
			dataType: 'text',		// or json
			success: function(data) {
				$("#favorites_summary").html(data);
				alert("This door has been added to your Favorites.");
			}
		});
	return false;
}


/*********************************************************************************
*														favoritesClickContinue
*
*********************************************************************************/
function favoritesClickContinue()
{
	if (favoritesValidate()) {
		$.ajax({
				url: '/garage-doors/share',
				data: {
					name: $("#your-name").val(),
					email: $("#your-email").val(),
					recipient: $("#recipient-email").val(),
					message: $("#message").val()
				},
				type: 'POST',
				dataType: 'text',
				success: function(data) {
					$("#share-message").html(data);
				}
			});
	}
}


/*********************************************************************************
*														favoritesValidate
*
*********************************************************************************/
function favoritesValidate()
{
	var el;
	var required = {
		'your-name': "Your Name", 
		'your-email': "Your Email", 
		'recipient-email': "Recipient's Email", 
		'message': "Message"
	};

	for (var id in required) {
		el = $("#" + id);
		if (el.val() === "")
			return validate_error(el, required[id] + " is required");
		if (id == "your-email" || id =="recipient-email")
			if (!validEmail.test(el.val()))
				return validate_error(el, "Please enter a valid Email address, like jsmith@gmail.com");
	}

	return true;
}


/*********************************************************************************
*														quickviewSaveFave
* saves a step1 URL
*********************************************************************************/
function quickviewSaveFave(el, the_panel, the_color, the_window)
{
// /garage-doors/choose-your-design/material/style/brand/color/panel/window
	var panel = all_panels[the_panel];
	var color = all_colors[the_color][1];
	var url = "/garage-doors/choose-your-design/" +
				panel[2] + "/" +	// material
				panel[6] + "/" +	// style
				panel[7] + "/" +	// brand
				color + "/" +	// color
				panel[1];			// panel
	if (typeof the_window !== 'undefined')
		url += "/" + all_windows[the_window][1];	// window
	$.ajax({
			url: "/favorites/ajax_save_fave",
			data: {
				url: url
			},
			type: 'POST',
			dataType: 'text',		// or json
			success: function(data) {
				window.parent.setFavoritesSummary(data);
				alert("This door has been added to your Favorites.");
			}
		});
	return false;
}


/*********************************************************************************
*														quickview_step1
* go to step1 from quickview
*********************************************************************************/
function quickview_step1(el, p, the_color, the_window)
{
// /garage-doors/choose-your-design/material/style/brand/color/panel/then-whatever-else-comes-afterwards
	var url = "/garage-doors/choose-your-design/" +
				all_panels[p][2] + "/" +	// material
				all_panels[p][6] + "/" +	// style
				all_panels[p][7] + "/" +	// brand
				all_colors[the_color][1] + "/" +	// color
				all_panels[p][1];			// panel
	if (typeof the_window != "undefined")
		if (typeof all_windows == "undefined")
			url += "/" + the_window;
		else
			url += "/" + all_windows[the_window][1];	// window
	el.target='_parent';
	el.href = url;
	return true;
}


/*********************************************************************************
*														go_step1
*
*********************************************************************************/
function go_step1(el, p, the_color, the_window)
{
// /garage-doors/choose-your-design/material/style/brand/color/panel/then-whatever-else-comes-afterwards
	var url = "/garage-doors/choose-your-design/" +
				all_panels[p][3] + "/" +	// material
				all_panels[p][7] + "/" +	// style
				all_panels[p][8] + "/" +	// brand
				all_colors[the_color][1] + "/" +	// color
				all_panels[p][2];			// panel
				
	if (typeof the_window != "undefined")
				if (typeof all_windows == "undefined")
			url += "/" + the_window;
		else
			url += "/" + all_windows[the_window][1];	// window
	el.target='_parent';
	el.href = url;
	return true;
}


/*********************************************************************************
*														go_step1_back
*
*********************************************************************************/
function go_step1_back(el, the_panel, the_color, the_window)
{
	var url = "/garage-doors/choose-your-design/" +
				segments[3] + "/" +				// material
				segments[4] + "/" +				// style
				segments[5] + "/" +					// brand
				all_colors[the_color][1] + "/" +	// color
				segments[7] + "/" +					// panel
				all_windows[the_window][1];			// window
	if (typeof segments[9] != "undefined")
		url += "/" + segments[9];
	el.target='_parent';
	el.href = url;
	return true;
}


/*********************************************************************************
*														go_step2
*
*********************************************************************************/
// /garage-doors/installation/material/style/brand/color/panel/then-whatever-else-comes-afterwards
function go_step2(el, the_panel, the_color, the_window)
{
	// alert('panel=' + the_panel + ", color=" + the_color + ", window=" + the_window);
	var url = "/garage-doors/installation/" +
				segments[3] + "/" +					// material
				segments[4] + "/" +					// style
				segments[5] + "/" +					// brand
				all_colors[the_color][1] + "/" +	// color
				segments[7] + "/" +					// panel
				all_windows[the_window][1];			// window
	if (typeof segments[9] != "undefined")
		url += "/" + segments[9];
	el.target='_parent';
	el.href = url;
	return true;
}


/*********************************************************************************
*														go_step3
*
*********************************************************************************/
// /garage-doors/installation/material/style/brand/color/panel/then-whatever-else-comes-afterwards
function go_step3(el, the_panel, the_color, the_window)
{
	var data = step2BuildConfiguration(true);
	if (!data)
		return false;

	$.ajax({
			url: '/garage-doors/step-2-save',
			data: data,
			type: 'POST',
			dataType: 'text',		// or json
			success: function(code) {
				var url = base_url + "garage-doors/options/" +
							segments[3] + "/" +				// material
							segments[4] + "/" +				// style
							segments[5] + "/" +					// brand
							all_colors[the_color][1] + "/" +	// color
							segments[7] + "/" +					// panel
							all_windows[the_window][1] + "/" +	// window
							code;
				document.location.href = url;
			}
		});

	return false;
}

/*********************************************************************************
*														go_step4
* updates configuration, redirects to your-cart
*********************************************************************************/
function go_step4()
{
	// build list of upgrades
	var upgrades = {};
	for (var u in upgrade)
		upgrades[u] = {added: upgrade[u].added};

	// build list of accessories
	var acc = {};
	for (var sku in accessories) {
		if (qty[sku] > 0 && typeof accessories[sku] != "undefined")
			acc[sku] = {
				name: accessories[sku].name,
				qty: qty[sku]
			};
	}


	// save options
	var data = {
				code: configuration.code,
				quality: qualities.selected_id,
				quality_name: qualities.panels[qualities.selected].name,
				handle: handles.selected_id,
				handle_name: handles.panels[handles.selected].name,
				handle_qty: qty.handles,
				hinge: hinges.selected_id,
				hinge_name: hinges.panels[hinges.selected].name,
				hinge_qty: qty.hinges,
				opener: openers.selected_id,
				opener_name: openers.panels[openers.selected].name,
				opener_qty: qty.openers,
				wind: winds.selected_id,
				wind_name: winds.panels[winds.selected].name,
				accessories: acc,
				upgrades: upgrades,
				total_price: prices.total
	};
	// alert(JSON.stringify(data));
	$.ajax({
			url: '/garage-doors/step-3-save',
			data: data,
			type: 'POST',
			dataType: 'text',		// or json
			error:function (xhr, ajaxOptions, thrownError){
				alert("Error Status: " + xhr.status + "\n" + thrownError);
			},
			success: function(url) {
				document.location.href = base_url + url;
			}
		});

	return false;
}


/*********************************************************************************
*														number_format
*
*********************************************************************************/
function number_format (number, decimals) {
	// Formats a number with grouped thousands  
	// Strip all characters but numerical ones.
	number = (number + '').replace(/[^0-9+\-Ee.]/g, '');
	var n = !isFinite(+number) ? 0 : +number,
		prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
		sep = ',',
		dec = '.',
		s = '',
		toFixedFix = function (n, prec) {
			var k = Math.pow(10, prec);
			return '' + Math.round(n * k) / k;
		};
	// Fix for IE parseFloat(0.55).toFixed(0) = 0;
	s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
	if (s[0].length > 3) {
		s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
	}
	if ((s[1] || '').length < prec) {
		s[1] = s[1] || '';
		s[1] += new Array(prec - s[1].length + 1).join('0');
	}
	return s.join(dec);
}


/*********************************************************************************
*														show_door_with_color
*
*********************************************************************************/
function show_door_with_color(p, panel, color)
{
	if (panel !== "" && color !== "") {
		panel_colors[p] = color;
		var image = panel + "-" + color + ".jpg";
		$("#debug").html(image);
		var name = all_colors[color][0];
		$("#thumbnail-" + p).attr({src: "/images/door-colors/" + image, title: name, alt: name});
	}
	return false;
}


/*********************************************************************************
*														
*											BROWSE ALL DOORS related functions
*
*********************************************************************************/
// BROWSE ALL DOORS related functions

var material_filter = null;
var collection_filter = null;
var color_filter = null;
var brand_filter = null;

function clear_filters()
{
material_filter = null;
collection_filter = null;
color_filter = null;
brand_filter = null;
}

function filter_all()
{
	clear_filters();
	panels = [];
	for (var f in all_panels)
		panels[panels.length] = f;
	refresh_panels();
	return false;
}


function filter_material(el, material)
{
	var $el = $(el);
	if (material_filter == material) {
		$el.parent().removeClass('reset'); 
		material_filter = null;
		return filter_all();
	}
	clear_filters();
	material_filter = material;
	$el.parent().siblings().removeClass('reset');
	$el.parent().addClass('reset'); 
	panels = [];
	for (var f in all_panels)
		if (all_panels[f][3] == material)
			panels[panels.length] = f;
	refresh_panels();
	return false;
}

function filter_collection(el, collection)
{
	var $el = $(el);
	if (collection_filter == collection) {
		$el.parent().removeClass('reset'); 
		collection_filter = null;
		return filter_all();
	}
	clear_filters();
	collection_filter = collection;
	$el.parent().siblings().removeClass('reset');
	$el.parent().addClass('reset'); 
	panels = [];
	for (var f in all_panels) {
		panel = all_panels[f];
		found = false;
		for (var c in panel[6]) {
			if (panel[6][c] == collection)
				found = true;
		}
		if (found)
			panels[panels.length] = f;
	}
	refresh_panels();
	return false;
}


function filter_color(el, color)
{
	var $el = $(el);
	if (color_filter == color) {
		$el.parent().removeClass('reset'); 
		color_filter = null;
		return filter_all();
	}
	clear_filters();
	color_filter = color;
	$el.parent().siblings().removeClass('reset');
	$el.parent().addClass('reset'); 
	panels = [];
	for (var f in all_panels) {
		panel = all_panels[f];
		found = false;
		for (var c in panel[5]) {
			if (panel[5][c] == color)
				found = true;
		}
		if (found)
			panels[panels.length] = f;
	}
	refresh_panels();
	return false;
}


function filter_brand(el, brand)
{
	var $el = $(el);
	if (brand_filter == brand) {
		$el.parent().removeClass('reset'); 
		brand_filter = null;
		return filter_all();
	}
	clear_filters();
	brand_filter = brand;
	$el.parent().siblings().removeClass('reset');
	$el.parent().addClass('reset'); 
	panels = [];
	for (var f in all_panels)
		if (all_panels[f][8] == brand)
			panels[panels.length] = f;
	refresh_panels();
	return false;
}


function refresh_panels()
{
	$("#panel-list").empty();
	var seq = 0;
	for (var i in panels) {
		++seq;
		if (mode == "browse") {
			while (typeof promo_cards[seq] != "undefined") {
				$("#panel-list").append(promo_card(promo_cards[seq]));
				++seq;
			}
		}
		$("#panel-list").append(door_card(panels[i], $(".door").length));
	}
	// display remaining promo cards
	if (mode == "browse") {
		for (i in promo_cards)
			if (i > seq)
				$("#panel-list").append(promo_card(promo_cards[i]));
	}

	// display message if there are no favorites
	if (seq === 0)
		$("#no-favorites").show();
}

function promo_card(copy)
{
	var html = "";
	html += '<div class="door">' + "\n";
	html += copy;
	html += '</div><!-- end door card -->' + "\n\n";

	return html;	
}


function door_card(p, i)
{
	var panel = all_panels[p];
	var panel_id = panel[0];
	var panel_slug = panel[2];
	var material = panel[3];
	var style = panel[7];
	var brand = panel[8];

	var selected_color = (color_filter === null) ? panel[5][0] : color_filter;
	panel_colors[p] = selected_color;
	var color_name = all_colors[selected_color][0];
	var color_slug = all_colors[selected_color][1];
	var window = (typeof panel[11] == "undefined") ? '' : panel[11];
	var url = "/garage-doors/choose-your-design/" + material + "/" + style + "/" + brand + "/" + color_slug + "/" + panel_slug + "/" + window;

	// /garage-doors/choose-your-design/steel/traditional/amarr/white/long-panel/

	var onclick = 'onclick="return go_step1(this, ' + i + ', panel_colors[\'' + i + '\'], \'' + window + '\');"';
	var html = "";
	html += '<div class="door">' + "\n";
	if (panel[9] !== "")
		html += '<div class="banner"><img src="/images/banners/' + panel[9] + '" width="75" height="75" alt="Sale"></div>';

	if (mode == "favorites")
		html += '	<div class="favorite remove"><a href="/favorites/remove/' + panel[12] + '" title="Remove Favorite">Add Favorite</a></div>' + "\n";
	else
		html += '	<div class="favorite add"><a href="#" title="Add Favorite"  onclick="return browseSaveFave(' + p + ');">Add Favorite</a></div>' + "\n";

	html += '	<div class="thumbnail">' + "\n";
	var src;
	if (typeof panel[10] == "undefined" || panel[10] === "")
		src = '/images/door-colors/' + panel_id + '-' + selected_color + '.jpg';
	else
		src = panel[10];
	html += '		<a href="' + url + '" ' + onclick + '><img id="thumbnail-' + i + '" src="' + src + '" width="139" height="126" ' +
						'alt="' + color_name + '" title="' + color_name + '"></a>' + "\n";
	html += '	</div>' + "\n";
	html += '	<p><span class="name"><a href="' + url + '" ' + onclick + '>' + panel[1] + '</a></span><br>' + "\n";
	html += '		<span class="material">' + all_materials[panel[3]] + '</span><br />' + "\n";

	html += '		<span class="designSelector">' + "\n";
	for (var c in panel[5]) {
		var color_id = panel[5][c];
		color_name = all_colors[color_id][0];
		color_slug = all_colors[color_id][1];
		var onmouseover = 'onmouseover="return show_door_with_color(' + i + ',\'' + panel_id + '\', \'' + color_id + '\')"';
		var onclick_swatch = 'onclick="return false"';
		var chip_url = "/garage-doors/choose-your-design/" + material + "/" + style + "/" + brand + "/" + color_slug + "/" + panel_slug;
		if (typeof panel[10] == "undefined" || panel[10] === "")
			onclick_swatch = 'onclick="return show_door_with_color(' + i + ',\'' + panel_id + '\', \'' + color_id + '\')"';
		html += '			<a href="' + chip_url + '" ' + onclick_swatch + '>';
		html += '			<img src="/images/colors/' + color_slug + '.jpg" width="19" height="19" alt="' + color_name + '" title="' + color_name + '">';
		html += '			</a>' + "\n";
	}
	html += '		</span><br />' + "\n";

	if (panel[4] > 0)
		html += '		<span class="price">From $' + number_format(panel[4], 0) + '</span><br />' + "\n";

	html += '		<span class="actions">' + "\n";
	html += '			<a href="' + url + '" onclick="return quick_view(this, \'' + panel[2] + '\', panel_colors[\'' + p + '\']);" class="button quickView">Quick View</a>' + "\n";
	html += '			<a href="' + url + '" ' + onclick + ' class="button primary">Pricing &amp; Details</a>' + "\n";
	html += '		</span>' + "\n";

	html += '	</p>' + "\n";
	html += '</div><!-- end door card -->' + "\n\n";

	return html;
}


/*********************************************************************************
*														QUICKVIEW WINDOW related functions
*
*********************************************************************************/

function quickview_color(c)
{
	the_color = c;
		$(".color").removeClass("selected");
		$("#color-" + c).addClass("selected");
		the_color_name = all_colors[c][0];
		$("#color-name").html(the_color_name);
		$(".detail-color").html(the_color_name);
	return quickview_update();
}

function quickview_window(w)
{
	the_window = w;
	$(".window").removeClass("selected");
	$("#window-" + w).addClass("selected");
	the_window_name = all_windows[w][0];
	$("#window-name").html(the_window_name);
	$(".detail-window").html(the_window_name);

	return quickview_update();
}

function quickview_update()
{
	if (the_window === "")
		return;
	var w = the_window;
	if (w > 0 && w < 10)
		w = "0" + w;
	the_preview = "/images/doors/" + the_panel + "/" + the_panel_id + "_" + w + "_" + the_color + "_S.jpg";
	$("#debug").html(the_preview);
	$("#quickview-preview").attr({src: the_preview});

	if (step < 2)
		step1UpdatePrice();

	return false;
}


/*********************************************************************************
*														step1ShowTabNumber
*
*********************************************************************************/
function step1ShowTabNumber(n)
{
	switch (n)
	{
		case 1:
			$("#step1-tab1").addClass("selected");
			$("#step1-tab2").removeClass("selected");
			$("#productInformation").show();
			$("#productReviews").hide();
			break;

		case 2:
			$("#step1-tab1").removeClass("selected");
			$("#step1-tab2").addClass("selected");
			$("#productInformation").hide();
			$("#productReviews").show();
			break;
	}
}


/*********************************************************************************
*														step1BuildConfiguration
*
*********************************************************************************/
function step1BuildConfiguration()
{
	var data = {
				id: "",
				url: "",
				material: "",
				material_name: "",
				style: "",
				brand: "",
				color: all_colors[the_color][1],
				color_name: the_color_name,
				panel: the_panel,
				panel_name: the_panel_name,
				'window': all_windows[the_window][1],
				window_name: the_window_name,
				preview: the_preview,
				installation: "diy",
				installation_name: "",
				zip: "",
				door_count: 1,
				doors: [
					{
						width_feet: 7,
						height_feet: 6,
						opener: "none",
						headroom: "standard",
						qty: 1
					}
				]
	};
	return data;
}


/*********************************************************************************
*														step1UpdatePrice
*
*********************************************************************************/
function step1UpdatePrice()
{
	// alert("step1UpdatePrice()")
	var data = step1BuildConfiguration();
	// alert("step1: " + JSON.stringify(data))

	$('.currentPrice').html('<img src="/images/spinner.gif">');

	$.ajax({
		url: '/ajax/cheapest_configuration/' + step,
		data: data,
		type: 'POST',
		dataType: 'json',
		error:function (xhr, ajaxOptions, thrownError){
			alert("ERROR: status " + xhr.status + "\n" + thrownError);
		},
		success: function(data) {
			prices = data;
			// alert(data.request);
			// alert(JSON.stringify(data));

			// display any errors
			for (var e in data.errors)
				alert(data.errors[e]);

			var single_price = prices.doors[1].ext_price;
			$('.singleCarDoor').html("$" + addCommas(single_price));
			$('.currentPrice').html("$" + addCommas(single_price));

			if (step === 0) {
				var double_price = prices.doors[2].ext_price;
				$('.doubleCarDoor').html("$" + addCommas(double_price));
			}

		}
	});

}


/*********************************************************************************
*														step2AddDoor
*
*********************************************************************************/
function step2AddDoor(update_price, width, height, opener, headroom, qty)
{
	var data = {
		n: ++door_count,
		min_width: widths[0],
		max_width: widths[1],
		inc_width: widths[2],
		min_height: heights[0],
		max_height: heights[1],
		inc_height: heights[2],
		width: width,
		height: height,
		opener: opener,
		headroom: headroom,
		qty: qty
	};
	html = step2AddDoorHTML(data);
	$(html).insertBefore("tr#table-insert");	

	html = step2DoorSummaryHTML(door_count);
	$(html).insertBefore("#installation-type");
	step2UpdateHeadroom(door_count, update_price);
}


/*********************************************************************************
*														step2AddDoorHTML
*
*********************************************************************************/
function step2AddDoorHTML(data)
{
	var n = data.n;
	var qty = (data.qty < 1) ? 1 : data.qty;

	var widths = data.width.split("-");
	var width_feet = widths[0];
	var width_inches = widths[1];

	var heights = data.height.split("-");
	var height_feet = heights[0];
	var height_inches = heights[1];

	var html =	'<tr id="door-' + n + '" class="doorSize">' + "\n" +
				'	<td>' + "\n" +
				'		<span class="widthHeightLabel">W</span>' + "\n" +
				'		<select id="width-feet-' + n + '" name="width-feet-' + n + '" onchange="step2UpdatePrice();">' + "\n";

	for (var feet=data.min_width; feet<=data.max_width; ++feet) {
		html +=	'			<option value="' + feet + '"';
		if (feet == width_feet)
			html += ' selected';
		html +=	'>' + feet + '\'</option>';
	}
	html +=		'		</select>' + "\n" +
				'		<select id="width-inches-' + n + '" name="width-inches-' + n + '" onchange="step2UpdatePrice();">' + "\n";

	for (var inches=0; inches<12; inches+=data.inc_width) {
		html +=	'			<option value="' + inches + '"';
		if (inches == width_inches)
			html += ' selected';
		html +=	'>' + inches + '&quot;</option>';
	}
	html +=		'		</select><br />' + "\n" +
				'		<span class="widthHeightLabel">H</span>' + "\n" +
				'		<select id="height-feet-' + n + '" name="height-feet-' + n + '" onchange="step2HeightChanged(' + n + ');">' + "\n";
		
	for (feet=data.min_height; feet<=data.max_height; ++feet) {
		html +=	'			<option value="' + feet + '"';
		if (feet == height_feet)
			html += ' selected';
		html +=	'>' + feet + '\'</option>';
	}
	html +=		'		</select>' + "\n" +
				'		<select id="height-inches-' + n + '" name="height-inches-' + n + '" onchange="step2HeightChanged(' + n + ');">' + "\n";

	for (inches=0; inches<12; inches+=data.inc_height) {
		html +=	'			<option value="' + inches + '"';
		if (inches == height_inches)
			html += ' selected';
		html +=	'>' + inches + '&quot;</option>';
	}
	html +=		'		</select><br />' + "\n" +
				'	</td>' + "\n" + 
				'	<td>' + "\n" +
				'		<select name="opener-' + n + '" id="opener-' + n + '" onchange="step2UpdateHeadroom(' + n + ', true)">' + "\n";
	var options = {
		'none': 'No opener',
		'buy': 'Show me openers',
		'my': 'Use existing opener'
	};
	for (var k in options) {
		html +=	'			<option value="' + k + '"';
		if (k == data.opener)
			html += ' selected';
		html +=	'>' + options[k] + '</option>' + "\n";
	}
	html +=		'		</select>' + "\n" +
				'	</td>' + "\n" +
				'	<td>' + "\n" +
				'		<select name="headroom-' + n + '" id="headroom-' + n + '" onchange="step2UpdatePrice();" >' + "\n" +
				'			<option selected>Select...</option>' + "\n" +
				'		</select>' + "\n" +
				'	</td>' + "\n" +
				'	<td style="text-align:center;">' + "\n" +
				'		<input name="qty-' + n + '" type="text" id="qty-' + n + '" value="' + qty + '" size="5" onchange="step2UpdatePrice();" ><br>' + "\n";
	if (n > 1)
		html +=	'		<a href="#" onclick="return step2RemoveDoor(' + n + ')" class="smallType">Remove</a>' + "\n";
	html +=		'	</td>' + "\n" +
				'</tr>' + "\n";

	return html;
}


/*********************************************************************************
*														step2BuildConfiguration
*
*********************************************************************************/
function step2BuildConfiguration(noisy)
{
	var data = {
				code: configuration_code,
				url: url,
				material: segments[3],
				material_name: "",
				style: segments[4],
				brand: segments[5],
				color: all_colors[the_color][1],
				color_name: the_color_name,
				panel: segments[7],
				panel_name: the_panel_name,
				'window': all_windows[the_window][1],
				window_name: the_window_name,
				preview: the_preview,
				installation: $("#installation-difm").attr("checked") ? 'difm' : 'diy',
				installation_name: installation_name,
				zip: $("#zip").val(),
				door_count: 0,
				doors: []
	};
	if (data.installation == "difm" && !zip_valid) {
		if (noisy) {
			alert("Please enter a valid zip code for Do It For Me, or choose Do It Yourself instead.");
		}
		return false;
	}

	var i = 0;
	for (var d=1; d<=door_count; ++d) {
		if ($("#width-feet-" + d).length > 0) {
			//data.door_count = ++i;
			var door = {};
			door.width = $("#width-feet-" + d).val() + '-' + $("#width-inches-" + d).val();
			door.height = $("#height-feet-" + d).val() + '-' + $("#height-inches-" + d).val();
			var size = "";
			var width = parseInt($("#width-feet-" + d).val(), 10);
			size += width + "'";
			var inches = $("#width-inches-" + d).val();
			if (inches > 0) {
				++width;
				size += " " + inches + "&quot;";
			}
			var height = parseInt($("#height-feet-" + d).val(), 10);
			size += " x " + height + "'";
			inches = $("#height-inches-" + d).val();
			if (inches > 0) {
				++height;
				size += " " + inches + "&quot;";
			}

			door.width_feet = width;
			door.height_feet = height;
			door.size = size;

			$("#door-size-" + d).html(size);

			var opener = $("#opener-" + d).val();
			var opener_name = "?";
			if (opener !== "") {
				$("#opener-" + d + " option:selected").each(function () {
					opener_name = $(this).text();
				});
			}
			$("#door-opener-" + d).html(opener_name);

			door.opener = opener;
			door.opener_name = opener_name;

			var headroom = $("#headroom-" + d).val();
			var headroom_name = "?";
			if (headroom !== "") {
				$("#headroom-" + d + " option:selected").each(function () {
					headroom_name = $(this).text();
				});
			}
			$("#door-headroom-" + d).html(headroom_name);

			door.headroom = headroom;
			door.headroom_name = headroom_name;

			var qty = parseInt($("#qty-" + d).val(), 10);
			$("#door-quantity-" + d).html(qty);
			door.qty = qty;
			data.door_count += qty;

			data.doors.push(door);

			if (door.opener === "") {
				if (noisy) {
					if (d==1 && door_count==1)
						alert("Please specify an Opener option for your door");
					else
						alert("Please specify an Opener option for door #" + d);
					return false;
				}
			}
			if (door.headroom === "") {
				if (noisy) {
					if (d==1 && door_count==1)
						alert("Please specify a Headroom option for your door");
					else
						alert("Please specify a Headroom option for door #" + d);
					return false;
				}
			}
		}
	}
	return data;
}



/*********************************************************************************
*														step2CheckZip
*
*********************************************************************************/
function step2CheckZip()
{
	zip_valid = false;
	var zip = (segments[2] == "installation") ? $("#zip").val() : configuration.zip;
	// if (zip !== "")
	//	$("#installation-difm").attr({checked: true});

	var is_difm = (segments[2] == "installation") ? $("#installation-difm").attr("checked") : (configuration.installation == "difm");

	if (is_difm) {
		installation_name = "Do It For Me";
		$("#installation-note").html(installation_name);
	}
	else {
		installation_name = "Do It Yourself";
		$("#installation-note").html(installation_name);
	}

	validZip = /^\d\d\d\d\d$/;
	if (is_difm && !validZip.test(zip)) {
		$("#zip-note").html('<img src="/images/silk/exclamation.png" />');
		$("#summary-zip").html('Not a valid zip code');
		difm = {zip: 0};
		step2UpdatePrice();
		return;
	}
	$("#summary-zip").html(zip);
	
	if (is_difm) {
		$("#zip-note").html('<img src="/images/spinner.gif" />');
		$.ajax({
				url: '/ajax/difm_lookup/',
				data: {zip: zip},
				type: 'POST',
				dataType: 'json',
				success: function(data) {
					// alert(JSON.stringify(data))
					difm = data;
					if (data.zone === 0) {
						$("#zip-note").html("not available");
						$("#installation-difm").attr({checked: ""});
						$("#installation-diy").attr({checked: "checked"});
					}
					else {
						zip_valid = true;
						$("#zip-note").html('<img src="/images/silk/tick.png" />');
					}
					step2UpdatePrice();
				},
				error: function(jqXHR, textStatus, errorThrown) {
					alert("/ajax/difm_lookup error: " + textStatus);
				}
			});

	}
	else {
		$("#zip-note").html("");
		difm = {zone: 0};
		step2UpdatePrice();
	}
}


/*********************************************************************************
*														step2DoorSummaryHTML
*
*********************************************************************************/
function step2DoorSummaryHTML(d)
{
	return	'<dd id="door-summary-' + d + '">' + "\n" +
			'  <span id="door-price-' + d + '" class="price"></span>' + "\n" +
			'  <span class="details">' + "\n" +
			'	<span class="detailName">Size: </span>' + 
			'		<span id="door-size-' + d + '"></span><br />' + "\n" +
			'	<span class="detailName">Opener: </span>' +
			'		<span id="door-opener-' + d + '"></span><br />' + "\n" +
			'	<span class="detailName">Headroom: </span>' +
			'		<span id="door-headroom-' + d + '"></span><br />' + "\n" +
			'	<span class="detailName">Quantity: </span>' +
			'		<span id="door-quantity-' + d + '"></span><br />' + "\n" +
			'  </span>' + "\n" +
			'</dd>' + "\n";
}


/*********************************************************************************
*														step2RemoveDoor
*
*********************************************************************************/
function step2RemoveDoor(n)
{
	$("#door-" + n).remove();
	$("dd#door-summary-" + n).remove();
	step2UpdatePrice();
	return false;
}


/*********************************************************************************
*														step2UpdateHeadroom
*
*********************************************************************************/
function step2UpdateHeadroom(d, update_price)
{
	var headroom = "";
	if (typeof configuration != "undefined")
		if (typeof configuration.doors != "undefined")
			if (typeof configuration.doors[d-1] != "undefined")
				headroom = configuration.doors[d-1].headroom;
	var opener = (segments[2] == "installation") ? $("#opener-" + d).val() : configuration.opener;
	$("#headroom-" + d).empty();
	$("#headroom-" + d).append('<option value="">Select...</option>');
	if (opener == 'none') {
		$("#headroom-" + d).append('<option value="standard" ' + (headroom == "standard" ? "selected" : "") + '>' + 
			"At least " + headrooms.standard_headroom + "&quot;</option>\n");
		$("#headroom-" + d).append('<option value="low" ' + (headroom == "low" ? "selected" : "") + '>' + 
			"Between " + headrooms.low1_headroom + "&quot; - " + (headrooms.standard_headroom - .25) + "&quot;</option>\n");
		$("#headroom-" + d).append('<option value="low2" ' + (headroom == "low2" ? "selected" : "") + '>' + 
			"Between " + headrooms.low2_headroom + "&quot; - " + (headrooms.low1_headroom - .25) + "&quot;</option>\n");
	}
	else if (opener !== "") {
		$("#headroom-" + d).append('<option value="standard" ' + (headroom == "standard" ? "selected" : "") + '>' + 
			"At least " + headrooms.standard_headroom_opener + "&quot;</option>\n");
		$("#headroom-" + d).append('<option value="low" ' + (headroom == "low" ? "selected" : "") + '>' + 
			"Between " + headrooms.low1_headroom_opener + "&quot; - " + (headrooms.standard_headroom_opener - .25) + "&quot;</option>\n");
		$("#headroom-" + d).append('<option value="low2" ' + (headroom == "low2" ? "selected" : "") + '>' + 
			"Between " + headrooms.low2_headroom_opener + "&quot; - " + (headrooms.low1_headroom_opener - .25) + "&quot;</option>\n");
	}
	if (update_price)
		step2UpdatePrice();
}


/*********************************************************************************
*														step2HeightChanged
*
*********************************************************************************/
function step2HeightChanged(n)
{
	var feet = $("#height-feet-" + n).val();
	var inches = $("#height-inches-" + n).val();
	var collection = all_panels[the_panel_id][5][0];
	if (collection == "Classica" && feet == "7" && inches == "3") {
		alert("This door is not available in 7'3\" height. Please choose a different height.");
		$("#height-inches-" + n).val("0");
	}
	step2UpdatePrice();
}

/*********************************************************************************
*														step2UpdatePrice
*
*********************************************************************************/
function step2UpdatePrice()
{
	if (door_count === 0)
		return;

	var data = step2BuildConfiguration(false);
	// alert("step2: " + JSON.stringify(data))
	if (!data) {
		$('.currentPrice').html('$N/A');
		return;
	}

	$('.currentPrice').html('<img src="/images/spinner.gif">');

	$.ajax({
		url: '/ajax/cheapest_configuration/' + step,
		data: data,
		type: 'POST',
		dataType: 'json',
		error:function (xhr, ajaxOptions, thrownError){
			alert("ERROR: status " + xhr.status + "\n" + thrownError);
		},
		success: function(data) {
			prices = data;
			// alert(data.request);
			// alert(JSON.stringify(data));

			// display any errors
			for (var e in data.errors)
				alert(data.errors[e]);

			for (var d in data.doors) {
				$("#door-price-" + d).html("$" + addCommas(data.doors[d].price));
			}
			$("#installation-price").html("$" + addCommas(prices.installation));

			if (prices.shipping === 0)
				$("#shipping-price").html("Free Shipping!");
			else
				$("#shipping-price").html("$" + addCommas(prices.shipping));

			$('.currentPrice').html("$" + addCommas(prices.total));
		}
	});

}


/*********************************************************************************
*														step3FreezePrice
*
*********************************************************************************/
var step3_freeze_price = false;

function step3FreezePrice(bool)
{
	step3_freeze_price = bool;
}


/*********************************************************************************
*														step3UpdatePrice
*
*********************************************************************************/
function step3UpdatePrice()
{
	if (step3_freeze_price)
		return;

	$('.currentPrice').html('<img src="/images/spinner.gif">');

	// build list of upgrades
	var upgrades = {};
	for (var u in upgrade)
		upgrades[u] = {added: upgrade[u].added};

	// build list of accessories
	var acc = {};
	for (var sku in accessories) {
		if (qty[sku] > 0 && typeof accessories[sku] != "undefined")
			acc[sku] = {
				name: all_accessories[sku][0],
				qty: parseInt(qty[sku], 10)
			};
	}		
	// alert(JSON.stringify(acc));

	// build a list of addons
	var add = {};
	for (sku in addons) {
		if (addons[sku] > 0)
			add[sku] = addons[sku];
	}

	// get the price for this configuration
	var data = {
		code: configuration.code,
		quality: qualities.selected_id,
		handle: [handles.selected_id == "no_thanks" ? "" : handles.selected_id, '', qty.handles],
		hinge: [hinges.selected_id == "no_thanks" ? "" : hinges.selected_id, '', qty.hinges],
		opener: [openers.selected_id == "no_thanks" ? "" : openers.selected_id, '', qty.openers],
		wind: [winds.selected_id == "no_thanks" ? "" : winds.selected_id, '', 1],
		upgrades: upgrades,
		accessories: acc,
		addons: add
	};
	// alert(JSON.stringify(data));

	$.ajax({
		url: '/ajax/step3_prices',
		data: data,
		type: 'POST',
		dataType: 'json',
		error:function (xhr, ajaxOptions, thrownError){
			alert("Status: " + xhr.status + "\n" + thrownError);
		},
		success: function(data) {
			prices = data;
			// alert(data.request);
			// alert(JSON.stringify(data));

			// display any errors
			for (var e in data.errors)
				alert(data.errors[e]);

			for (var d in data.doors) {
				$("#door-price-" + d).html("$" + addCommas(data.doors[d].price));
			}
			$("#installation-price").html("$" + addCommas(prices.installation));

			if (prices.shipping === 0)
				$("#shipping-price").html("Free Shipping!");
			else
				$("#shipping-price").html("$" + addCommas(prices.shipping));

			$("#summary-handles-price").html( prices.handle === 0 ? "" : "$" + addCommas(prices.handle));
			$("#summary-hinges-price").html( prices.hinge === 0 ? "" : "$" + addCommas(prices.hinge));
			$("#summary-openers-price").html( prices.opener_subtotal === 0 ? "" : "$" + addCommas(prices.opener_subtotal));
			$("#summary-winds-price").html( prices.wind === 0 ? "" : "$" + addCommas(prices.wind));
			$("#summary-obscure-price").html( prices.obscure_subtotal === 0 ? "" : "$" + addCommas(prices.obscure_subtotal));
			$("#summary-insulated-price").html( prices.insulated_subtotal === 0 ? "" : "$" + addCommas(prices.insulated_subtotal));

			$('.currentPrice').html("$" + addCommas(prices.total));

			step3Accessories();
		}
	});

}



/*********************************************************************************
*														step3ShowConfiguration
*
*********************************************************************************/
function step3ShowConfiguration()
{
	for (d=1; d<=configuration.door_count; ++d) {
		info = configuration.doors[d-1];
		$("#door-size-" + d).html(info.size);
		$("#door-opener-" + d).html(info.opener_name);
		$("#door-headroom-" + d).html(info.headroom_name);
		$("#door-quantity-" + d).html(info.qty);
	}

	$("#installation-note").html(configuration.installation_name);
	$("#summary-zip").html(configuration.zip);

	if (configuration.upgrades) {
		if (configuration.upgrades.obscure.added == "true")
			upgrade.obscure.added = true;
		if (configuration.upgrades.insulated.added == "true")
			upgrade.insulated.added = true;
		if (configuration.upgrades.torsion.added == "true")
			upgrade.torsion.added = true;
		if (configuration.upgrades.torsion.added == "true")
			upgrade.torsion.added = true;
		if (configuration.upgrades.winder.added == "true")
			upgrade.winder.added = true;
		if (configuration.upgrades.roller.added == "true")
			upgrade.roller.added = true;
		if (configuration.upgrades.windbar.added == "true")
			upgrade.windbar.added = true;

	}


	for (var sku in configuration.accessories) {
		acc = configuration.accessories[sku];
		accessories[sku] = {
			name: acc.name,
			price: 0
		};
		qty[sku] = acc.qty;
	}

}


/*********************************************************************************
*														step3AddAccessory
*
*********************************************************************************/
function step3AddAccessory()
{
	var sku = $("#sku").val();
	if (sku === "") {
		alert("Please enter a sku for this accessory");
		$("#sku").focus();
		return;
	}
	var qty = parseInt($("#qty").val(), 10);
	qty[sku] = qty;

	if (qty <= 0)
		delete addons[sku];
	else
		addons[sku] = qty;

	step3UpdatePrice();
}


/*********************************************************************************
*														qtyEdit
*
*********************************************************************************/
function qtyEdit(what)
{
	what2 = what.replace(/ /g, '_', what);
	$("#summary-" + what2 + "-qty").hide();
	$("#summary-" + what2 + "-change").hide();
	$("#summary-" + what2 + "-edit").show();
	$("#summary-" + what2 + "-edit input").val(qty[what]);
	return false;
}


/*********************************************************************************
*														qtySave
*
*********************************************************************************/
function qtySave(what)
{
	what2 = what.replace(/ /g, '_', what);
	q = parseInt($("#summary-" + what2 + "-edit input").val(), 10);
	qty[what] = q;
	$("#summary-" + what2 + "-qty").html(qty[what]).show();
	$("#summary-" + what2 + "-change").show();
	$("#summary-" + what2 + "-edit").hide();


	// if this is an accessory with qty 0, remove it from accessories{} and qty{}
	if (q === 0 && typeof all_accessories[what] != "undefined") {
		delete accessories[what];
		delete qty[what];
	}

	step3UpdatePrice();
	return false;
}


/*********************************************************************************
*														checkout1DupeInfo
*
*********************************************************************************/
function checkout1DupeInfo()
{
	if ($("#same").attr("checked")) {
	$("#ship-firstname").val($("#bill-firstname").val());
	$("#ship-lastname").val($("#bill-lastname").val());
	$("#ship-address").val($("#bill-address").val());
	$("#ship-city").val($("#bill-city").val());
	$("#ship-state").val($("#bill-state").val());
	$("#ship-zip").val($("#bill-zip").val());
	$("#ship-phone").val($("#bill-phone").val());
	}
}


/*********************************************************************************
*														checkout1ClickContinue
*
*********************************************************************************/
function checkout1ClickContinue()
{
	if (checkout1Validate())
		$('#checkout1-form').submit();
}


/*********************************************************************************
*														checkout1Validate
*
*********************************************************************************/
function checkout1Validate()
{

var el;
var required = {
	'bill-firstname': "Billing First Name", 
	'bill-lastname': "Billing Last Name", 
	'bill-address': "Billing Address", 
	'bill-city': "Billing City", 
	'bill-state': "Billing State", 
	'bill-zip': "Billing Zip Code",
	'email': "Email Address",
	'bill-phone': "Billing Phone Number",
	'ship-firstname': "Shipping First Name", 
	'ship-lastname': "Shipping Last Name", 
	'ship-address': "Shipping Address", 
	'ship-city': "Shipping City", 
	'ship-state': "Shipping State", 
	'ship-zip': "Shipping Zip Code"
};

for (var id in required) {
	el = $("#" + id);
	if (el.val() === "")
		return validate_error(el, required[id] + " is required");
	if (id == "email")
		if (!validEmail.test(el.val()))
			return validate_error(el, "Please enter a valid Email address, like jsmith@gmail.com");
}

el = $("#agree");
if (!el.attr("checked"))
	return validate_error(el, "You must agree to our Terms and Conditions to continue.");
	

return true;
}


/*********************************************************************************
*														checkout2ClickContinue
*
*********************************************************************************/
function checkout2ClickContinue()
{
	if (checkout2Validate())
		$('#checkout2-form').submit();
}


/*********************************************************************************
*														checkout2Validate
*
*********************************************************************************/
function checkout2Validate()
{
	// alert("js validates true");
	// return true;

	if ($("#card-type").length === 0)
		return true;
	
	var d = new Date();
	var el;
	var required = {
		'card-type': "Credit card type", 
		'card-number': "Credit card number", 
		'card-ccv': "CCV2 code", 
		'card-month': "Expiration month", 
		'card-year': "Expiration year"
	};

	for (var id in required) {
		el = $("#" + id);
		if (el.val() === "")
			return validate_error(el, required[id] + " is required");
		if (id == "email")
			if (!validEmail.test(el.val()))
				return validate_error(el, "Please enter a valid Email address, like jsmith@gmail.com");
	}

	var $month = $("#card-month");
	var $year = $("#card-year");
	var month = parseInt($month.val(), 10);
	var year = parseInt($year.val(), 10);
	var current_month = d.getMonth() + 1;
	var current_year = d.getFullYear();
	if (year < current_year || (year == current_year && month < current_month))
		return validate_error($year, "Card is expired");

	return true;
}


/*********************************************************************************
*														contactClickContinue
*
*********************************************************************************/
function contactClickContinue()
{
	if (contactValidate())
		$('#contact-form').submit();
}


/*********************************************************************************
*														contactValidate
*
*********************************************************************************/
function contactValidate()
{

var el;
var required = {
	'email': "Email Address", 
	'comment': "Comment"
};

for (var id in required) {
	el = $("#" + id);
	if (el.val() === "")
		return validate_error(el, required[id] + " is required");
	if (id == "email")
		if (!validEmail.test(el.val()))
			return validate_error(el, "Please enter a valid Email address, like jsmith@gmail.com");
}


return true;
}


/*********************************************************************************
*														validate_error
*
*********************************************************************************/
function validate_error(el, msg) {
	alert(msg);
	el.focus();
	el.select();
	return false;
}


/*********************************************************************************
*														generateQualities
*
*********************************************************************************/
function generateQualities()
{
	var selected_id = qualities.selected_id ? qualities.selected_id : configuration.quality[0];
	qualities.reset();
	var n = 0;
	for (var m in models) {
		++n;
		var model = models[m];
		var thumb = m + "_t.jpg";
		var photo = m + ".jpg";
		var zoom = "/garage-doors/quality/" + model[1];
		qualities.addPanel(m, model[2], model[2], thumb, zoom);
		if (m == configuration.quality)
			qualities.selected = n;
	}
	if (qualities.selected === 0)
		qualities.selected = 1;
	qualities.select(qualities.selected);
	if (qualities.count === 0)
		$("#quality").hide();
	else
		$("#quality").show();
	qualities.show(1);
}


/*********************************************************************************
*														generateHandles
*
*********************************************************************************/
function generateHandles()
{
	var selected_id = handles.selected_id ? handles.selected_id : configuration.handle[0];
	handles.reset();
	handles.addNoThanks();
	var i = 1;
	for (var h in all_handles) {
		var handle = all_handles[h];
		if (in_array(qualities.selected_id, handle[2])) {
			++i;
			var thumb = handle[1] + "_t.jpg";
			var photo = handle[1] + ".jpg";
			var zoom = "/garage-doors/handle/" + handle[1];
			handles.addPanel(handle[1], handle[0], handle[0], thumb, zoom);
			if (handle[1] == selected_id)
				handles.selected = i;
		}
	}
	if (handles.selected === 0)
		handles.selected = 1;
	handles.select(handles.selected);
	if (handles.count < 2)
		$("#handle").hide();
	else
		$("#handle").show();
	handles.show(1);
}


/*********************************************************************************
*														generateHinges
*
*********************************************************************************/
function generateHinges()
{
	var selected_id = hinges.selected_id ? hinges.selected_id : configuration.hinge[0];
	hinges.reset();
	hinges.addNoThanks();
	var i = 1;
	for (var h in all_hinges) {
		var hinge = all_hinges[h];
		if (in_array(qualities.selected_id, hinge[2])) {
			++i;
			var thumb = hinge[1] + "_t.jpg";
			var photo = hinge[1] + ".jpg";
			var zoom = "/garage-doors/hinge/" + hinge[1];
			hinges.addPanel(hinge[1], hinge[0], hinge[0], thumb, zoom);
			if (hinge[1] == selected_id)
				hinges.selected = i;
		}
	}
	if (hinges.selected === 0)
		hinges.selected = 1;
	hinges.select(hinges.selected);
	if (hinges.count < 2)
		$("#hinge").hide();
	else
		$("#hinge").show();

	hinges.show(1);
}


/*********************************************************************************
*														generateOpeners
*
*********************************************************************************/
function generateOpeners()
{
	var selected_id = openers.selected_id ? openers.selected_id : configuration.opener[0];
	openers.reset();
	openers.addNoThanks();

	// make sure at least one door is "buy"
	var buy_count = 0;
	for (var d in configuration.doors) {
		if (configuration.doors[d].opener == "buy")
			++ buy_count;
	}

	if (buy_count > 0) {
		var i = 1;
		for (var h in all_openers) {
			var opener = all_openers[h];
			if (in_array(qualities.selected_id, opener[2])) {
				++i;
				var thumb = opener[1] + "_t.jpg";
				var photo = opener[1] + ".jpg";
				var zoom = "/garage-doors/opener/" + opener[1];
				openers.addPanel(opener[1], opener[0], opener[0], thumb, zoom);
				if (opener[1] == selected_id)
					openers.selected = i;
			}
		}
	}

	if (openers.selected === 0)
		openers.selected = 1;
	openers.select(openers.selected);
	if (openers.count < 2)
		$("#opener").hide();
	else
		$("#opener").show();
	openers.show(1);
}


/*********************************************************************************
*														generateWinds
*
*********************************************************************************/
function generateWinds()
{
	var selected_id = winds.selected_id ? winds.selected_id : configuration.wind[0];
	winds.reset();
	winds.addNoThanks();
	var i = 1;
	for (var w in all_winds) {
		var wind = all_winds[w];
		if (in_array(qualities.selected_id, wind[1])) {
			++i;
			var thumb = w + "_t.jpg";
			var photo = w + ".jpg";
			var zoom = "/garage-doors/wind/" + w;
			winds.addPanel(w, wind[0], wind[0], thumb, zoom);
			if (w == selected_id)
				winds.selected = i;
		}
	}
	if (winds.selected === 0)
		winds.selected = 1;
	winds.select(winds.selected);
	if (winds.count < 2)
		$("#wind").hide();
	else
		$("#wind").show();
	winds.show(1);
}


/*********************************************************************************
*														step3Accessories
*
*********************************************************************************/
var accessory_count = 0;
var accessory_prices = [];

function step3Accessories()
{
	$("#accessories div").remove();
	accessory_count = 0;
	var html;
	var sku;

	if (prices.options.obscure > 0) {
		html = accessoryHTML(
				'Obscure Glass Upgrade',
				'/images/accessories/OBSCURE_t.jpg', 
				'/garage-doors/accessory/OBSCURE', 
				0,
				prices.options.obscure,
				"addObscureToOrder()",
				upgrade.obscure.added
			);
		$("#accessories").append(html);
	}

	if (prices.options.insulated > 0) {
		html = accessoryHTML(
				'Insulated Glass Upgrade', 
				'/images/accessories/INSULATED_t.jpg', 
				'/garage-doors/accessory/INSULATED', 
				0,
				prices.options.insulated,
				"addInsulatedToOrder()",
				upgrade.insulated.added
			);
		$("#accessories").append(html);
	}

	if (prices.options.torsion > 0) {
		html = accessoryHTML(
				'Torsion Spring Upgrade', 
				'/images/accessories/TORSION_t.jpg', 
				'/garage-doors/accessory/TORSION', 
				0,
				prices.options.torsion,
				"addTorsionToOrder()",
				upgrade.torsion.added
			);
		$("#accessories").append(html);
	}

	if (prices.options.winder > 0) {
		html = accessoryHTML(
				'Simple Set Winder Upgrade', 
				'/images/accessories/WINDER_t.jpg', 
				'/garage-doors/accessory/SWIND-S', 
				0,
				prices.options.winder,
				"addWinderToOrder()",
				upgrade.winder.added
			);
		$("#accessories").append(html);
	}

	if (prices.options.roller > 0) {
		html = accessoryHTML(
				'Roller Upgrade', 
				'/images/accessories/ROLLER_t.jpg', 
				'/garage-doors/accessory/ROLLER', 
				0,
				prices.options.roller,
				"addRollerToOrder()",
				upgrade.roller.added
			);
		$("#accessories").append(html);
	}

	if (prices.options.windbar > 0) {
		html = accessoryHTML(
				'Winding Bar Upgrade', 
				'/images/accessories/WINDBAR_t.jpg', 
				'/garage-doors/accessory/WINDBAR', 
				0,
				prices.options.windbar,
				"addWindbarToOrder()",
				upgrade.windbar.added
			);
		$("#accessories").append(html);
	}

	// add accessories that match the chosen opener OR OR are in addons
	var selected_opener_id = openers.selected > 1 ? openers.selected_id : "";
	for (sku in all_accessories) {
		acc = all_accessories[sku];
		if (qty[sku] > 0) {
			accessories[sku].price = acc[2];
		}
		found = false;
		if (acc[1].length === 0 && acc[3])
			found = true;
		else for (var o in acc[1]) {
			if (acc[1][o] == selected_opener_id) {
				found = true;
				break;
			}
		}
		if (typeof addons[sku] != "undefined")
			found = true;
		if (found) {
			html = accessoryHTML(
					acc[0], 
					"/images/accessories/" + sku + "_t.jpg", 
					'/garage-doors/accessory/' + sku, 
					0,
					acc[2],
					"addAccessoryToOrder('" + sku + "')",
					qty[sku] > 0
				);
			$("#accessories").append(html);
		}
	}

	for (var u in upgrade) {
		if (upgrade[u].added) {
			if (prices.options[u] > 0) {
				// show it in the summary
				$("#summary-" + u).show();
				$("#summary-" + u + "-price").html('$' + addCommas(prices.options[u]));
			}
			else {
				// upgrade no longer available, hide it from the summary
				upgrade[u].added = false;
				$("#summary-" + u).hide();
				$("#summary-" + u + "-price").html("");
			}
		}
	}


	// remove all summary accessories
	$("#summaryStep3 dd.accessory").remove();

	// add in current accessories
	for (sku in accessories) {
		var acc = accessories[sku];
		var price = acc.price * qty[sku];
		html = summaryHTML(sku, acc.name, price, qty[sku]);
		$("#summaryStep3").append(html);
	}

	refreshFancyBox();
}


/*********************************************************************************
*														summaryHTML
*
*********************************************************************************/
function summaryHTML(sku, name, price, qty)
{
	var sku2 = sku.replace(/ /g, '_');
	var html = "";
	html += '<dd class="accessory">' + "\n";
	html += '	<span class="price" id="summary-' + sku2 + '-price">$' + addCommas(price) + '</span>' + "\n";
	html += '	<span class="details">' + "\n";
	html += '		<span class="detailName">Accessory: </span>' + "\n";
	html += '			<span id="summary-' + sku2 + '-name">' + name + '</span><br />' + "\n";
	html += '		<span class="detailName">Quantity: </span>' + "\n";
	html += '			<span id="summary-' + sku2 + '-qty">' + qty + '</span> &nbsp;' + "\n";
	html += '				<a href="#" id="summary-' + sku2 + '-change" class="smallType" onclick="return qtyEdit(\'' + sku + '\')"' + "\n";
	html += '					style="">Change</a> &nbsp;' + "\n";
	html += '		<span id="summary-' + sku2 + '-edit" style="display: none">' + "\n";
	html += '			<input type="text" value="" size="5" />' + "\n";
	html += '			<a href="#" class="small button" onclick="return qtySave(\'' + sku + '\')">Save</a>' + "\n";
	html += '			<a href="#" id="summary-' + sku2 + '-remove" class="smallType" onclick="return removeAccessory(\'' + sku + '\')"' + "\n";
	html += '				style="">Remove</a>' + "\n";
	html += '	</span>' + "\n";
	html += '</dd>' + "\n";

	return html;
}



/*********************************************************************************
*														accessoryHTML
*
*********************************************************************************/
function accessoryHTML(name, thumb, zoom, qty, price, onclick, added)
{
	var n = ++accessory_count;
	accessory_prices[n] = price;
	var html = '';
	html += '<div class="accessory">' + "\n";
	html += '	<img src="' + thumb + '" width="82" height="82" alt=" " />' + "\n";
	html += '	<div class="name">' + name + "<br />\n";
	html += '		<a href="' + zoom + '" class="button secondary small zoom">Details</a>' + "\n";
	html += '	</div>' + "\n";
	html += '	<div class="quantity">' + "\n";
	if (qty === 0) {
		html += "$" + addCommas(price) + '<input id="accessory-qty-' + n + '" type="hidden" value="1" />' + "\n";
	}
	else {
		html += '		Quantity: <input id="accessory-qty-' + n + '" type="text" value="' + qty + '" size="5" />' + "\n";
	}
	html += '	</div>' + "\n";
	html += '	 <div class="actions">' + "\n";
	if (added)
		html += '		<br />(added to order)' + "\n";
	else
		html += '		<a href="#" onclick="return ' + onclick + '" class="button primary">Add to Order</a>' + "\n";
	html += '	</div>' + "\n";
	html += '</div>' + "\n";

	return html;
}


/*********************************************************************************
*														addAccessoryToOrder
*
*********************************************************************************/
function addAccessoryToOrder(sku) {
	if (typeof accessories[sku] == "undefined") {
		accessories[sku] = {
			name: all_accessories[sku][0],
			price: all_accessories[sku][2]
		};
		qty[sku] = 1;
	}
	step3UpdatePrice();
	return false;
}


/*********************************************************************************
*														addWindbarToOrder
*
*********************************************************************************/
function addWindbarToOrder()
{
	if (prices.options.windbar === 0 || upgrade.windbar.added)
		return false;
	upgrade.windbar.added = true;
	$("#summary-windbar").show();
	$("#summary-windbar-price").html('$' + addCommas(prices.options.windbar));
	step3UpdatePrice();
	return false;
}


/*********************************************************************************
*														addRollerToOrder
*
*********************************************************************************/
function addRollerToOrder()
{
	if (prices.options.roller === 0 || upgrade.roller.added)
		return false;
	upgrade.roller.added = true;
	$("#summary-roller").show();
	$("#summary-roller-price").html('$' + addCommas(prices.options.roller));
	step3UpdatePrice();
	return false;
}


/*********************************************************************************
*														addWinderToOrder
*
*********************************************************************************/
function addWinderToOrder()
{
	if (prices.options.winder === 0 || upgrade.winder.added)
		return false;
	upgrade.winder.added = true;
	$("#summary-winder").show();
	$("#summary-winder-price").html('$' + addCommas(prices.options.winder));
	step3UpdatePrice();
	return false;
}


/*********************************************************************************
*														addTorsionToOrder
*
*********************************************************************************/
function addTorsionToOrder()
{
	if (prices.options.torsion === 0 || upgrade.torsion.added)
		return false;
	upgrade.torsion.added = true;
	$("#summary-torsion").show();
	$("#summary-torsion-price").html('$' + addCommas(prices.options.torsion));
	step3UpdatePrice();
	return false;
}


/*********************************************************************************
*														addObscureToOrder
*
*********************************************************************************/
function addObscureToOrder()
{
	if (prices.options.obscure === 0 || upgrade.obscure.added)
		return false;
	upgrade.obscure.added = true;
	$("#summary-obscure").show();
	$("#summary-obscure-price").html('$' + addCommas(prices.options.obscure));
	step3UpdatePrice();
	return false;
}


/*********************************************************************************
*														removeAccessory
*
*********************************************************************************/
function removeAccessory(what)
{
	what2 = what.replace(/ /g, '_', what);
	$("#summary-" + what2 + "-edit input").val(0);
	return qtySave(what);
}


/*********************************************************************************
*														removeObscure
*
*********************************************************************************/
function removeObscure()
{
	upgrade.obscure.added = false;
	$("#summary-obscure").hide();
	$("#summary-obscure-price").html("");
	step3UpdatePrice();
	return false;
}


/*********************************************************************************
*														addInsulatedToOrder
*
*********************************************************************************/
function addInsulatedToOrder()
{
	if (prices.options.insulated === 0 || upgrade.insulated.added)
		return false;
	upgrade.insulated.added = true;
	$("#summary-insulated").show();
	$("#summary-insulated-price").html('$' + addCommas(prices.options.insulated));
	step3UpdatePrice();
	return false;
}


/*********************************************************************************
*														removeInsulated
*
*********************************************************************************/
function removeInsulated()
{
	upgrade.insulated.added = false;
	$("#summary-insulated").hide();
	$("#summary-insulated-price").html("");
	step3UpdatePrice();
	return false;
}


/*********************************************************************************
*														removeTorsion
*
*********************************************************************************/
function removeTorsion()
{
	upgrade.torsion.added = false;
	$("#summary-torsion").hide();
	$("#summary-torsion-price").html("");
	// remove winder also
	removeWinder();
	return false;
}


/*********************************************************************************
*														removeWinder
*
*********************************************************************************/
function removeWinder()
{
	upgrade.winder.added = false;
	$("#summary-winder").hide();
	$("#summary-winder-price").html("");
	step3UpdatePrice();
	return false;
}


/*********************************************************************************
*														removeRoller
*
*********************************************************************************/
function removeRoller()
{
	upgrade.roller.added = false;
	$("#summary-roller").hide();
	$("#summary-roller-price").html("");
	step3UpdatePrice();
	return false;
}


/*********************************************************************************
*														removeWindbar
*
*********************************************************************************/
function removeWindbar()
{
	upgrade.windbar.added = false;
	$("#summary-windbar").hide();
	$("#summary-windbar-price").html("");
	step3UpdatePrice();
	return false;
}


/*********************************************************************************
*														trackOrders
*
*********************************************************************************/
function trackOrders()
{
	var el;
	
	el = $("#email");
	var email = el.val();
	if (el.val() === "")
		return validate_error(el, "Email address is required");
	if (!validEmail.test(el.val()))
		return validate_error(el, "Please enter a valid Email address, like jsmith@gmail.com");

	el = $("#order");
	var order = el.val();
	if (el.val() === "")
		return validate_error(el, "Order Number is required");
	

	$.ajax({
			url: '/ajax/tracking',
			data: {
				email: email,
				order: order
			},
			type: 'POST',
			dataType: 'text',		// or json
			success: function(data) {
				$("#order-status").html(data);
			}
		});


}


/*********************************************************************************
*														trackOrders
*
*********************************************************************************/
function trackOrdersUsingCode(code)
{
	if (typeof code == "undefined" || code === "")
		return;
	
	$.ajax({
			url: '/ajax/tracking',
			data: {
				code: code
			},
			type: 'POST',
			dataType: 'text',		// or json
			error:function (xhr, ajaxOptions, thrownError){
				alert("Error Status: " + xhr.status + "\n" + thrownError);
			},
			success: function(data) {
				$("#order-status").html(data);
			}
		});


}



/*********************************************************************************
*														why
*
*********************************************************************************/
var form = null;

function why()
{
	if (form === null)
		form = document.createElement("form");
	form.setAttribute("target", "_blank");
	form.setAttribute("method", "post");
	form.setAttribute("action", "/ajax/why");

	document.body.appendChild(form);

	var hiddenField = document.createElement("input");
	hiddenField.setAttribute("id", "hiddenValue");
	hiddenField.setAttribute("name", "ID");
	hiddenField.setAttribute("value", JSON.stringify(prices));

	form.appendChild(hiddenField);

	//Below line I added to fix the new input text field that was visible
	document.getElementById("hiddenValue").style.visibility = 'hidden';

	form.submit();

	return false;
}

