﻿
/// <reference path="Common/jQuery/jquery-1.4.1-vsdoc.js" />
/// <reference path="Common/Common.js" />

var Application = {
	oUser: false,
	cOldHash: "",
	disableSounds: false,
	docReady: function () {
		User.ProviderAccountID = $.cookie('tr_account_id') ? $.cookie('tr_account_id') : '';

		$("#ShopOpening").position({ at: "center center", of: "body", my: "center center" });
		$(".currentYear").text((new Date()).getFullYear());
		$(".ui-table").find("th").addClass("ui-state-default")

		Application.oUser = User;
		//$.sound.enabled = false;
		// ($.cookie("SoundsEnabled") == "false") ? false : true;
		//$.sound.play("fanfare.wav", { timeout: 15000 });

		if (navigator.userAgent.match(/Android|iOS|iPhone/gim)) {
			$.fx.off = true;
		} 
		else document.body.style.backgroundAttachment = "fixed";
		
		$(window).resize(function () {
			if (window.location.hash == "#Rewards") { Catalog.windowResized(); }
			if (window.location.hash == "#Awards") { Awards.resize(); }
		});

		$("#btnRewards").button({ icons: { primary: "ui-icon-cart"} });
		$("#btnOrders").button({ icons: { primary: "ui-icon-cart"} });
		$("#btnAwards").button({ icons: { primary: "ui-icon-star" }, disabled: true });
		$("#btnAccount").button({ icons: { primary: "ui-icon-person" }, disabled: true });
		$("#btnLogOut").button({ disabled: true });

		$("#btnDepoCert").button({ disabled: true }).click(function () {
			$("#accountTabs").tabs("select", 1);
			window.location.hash = "#Account";
		});
		$("#MenuBar .ui-button").removeClass("ui-corner-all").addClass("ui-corner-bl ui-corner-br");
		$("label[for=btnOrders]").hide();

		$("#MenuBar").show();

		$("#TokenLogoImage").click(function () {
			$.cookie("session_account", null);
			window.location = "http://TokenRewards.com"
		});
		Catalog.initPageNavBtns();

		Email.init();

		Login.init(function () {
			$("#PageHeader").show();
			if (!User.key) {
				Catalog.fetchProducts(function () {
					$("#ShopOpening").fadeOut(5000, function () { return; });
					$("#CodeEntry").css({ "top": "0px" });

					window.location.replace("#Rewards");
					Application.hashChanged();
				});
			}
			else {
				$("#ShopOpening").fadeOut(2000, function () { return; });
				if (!$.inArray(window.location.hash, ["#Rewards", "#Awards", "#Account", "#NewAccount"])
					|| window.location.hash == '') {
					window.location.replace("#Rewards");
				}
				Application.hashChanged();
			}
		});

		LogEntry("Shop opened " + navigator.userAgent);
	},
	hashChanged: function () {
		if (Application.cOldHash == window.location.hash) return;
		LogEntry("Hash changed to " + window.location.hash);
		var showNewHashPane = function () {
			if ((!User.key && $.inArray(window.location.hash, ["#Rewards", "#NewAccount"]) == -1)
				|| $.inArray(window.location.hash, ["#Rewards", "#NewAccount", "#Account", "#Awards"]) == -1) {
				window.location.hash = "#Rewards";
			}
			$("#btnsHashes input[value='" + window.location.hash + "']").eq(0).attr("checked", true);
			$("#btnsHashes input").button("refresh");

			Application.cOldHash = window.location.hash;
			switch (window.location.hash) {
				case "#Rewards": Catalog.show(); break;
				case "#NewAccount": NewAccount.show(); break;
				case "#Account": Account.show(); break;
				case "#Awards": Awards.show(); break;
			}
		};

		switch (Application.cOldHash) {
			case "#NewAccount": NewAccount.hide(showNewHashPane); break;
			case "#Rewards": Catalog.hide(showNewHashPane); break;
			case "#Awards": Awards.hide(showNewHashPane); break;
			case "#Account": Account.hide(showNewHashPane); break;
			default: showNewHashPane(); break;
		}
	}
};

var Catalog = {
	cDefaultCategory: "Everything",
	bProductsLoaded: false,
	nCurrentPage: -1,
	nCurrentCatIndex: -1,
	aPopups: new Array(),
	aDisplayProducts: new Array(),
	aMasterProducts: new Array(),
	aProductDescriptions: new Array(),

	oDimensions: {
		thumb: { width: 126, height: 158 },
		header: { width: $(window).width(), height: 90 }
	},
	thumbsPerPage: {
		min: 8,
		max: 105,
		prev: 0,
		current: 12,
		setCurrent: function () {
			var nX = Math.floor($(window).width() / Catalog.oDimensions.thumb.width)
						* Math.floor(($(window).height() - Catalog.oDimensions.header.height) / Catalog.oDimensions.thumb.height);
			if (nX < Catalog.thumbsPerPage.min) {
				nX = Catalog.thumbsPerPage.min;
				$('body').css("overflow", "visible");
			} else $('body').css("overflow", "");
			if (nX > Catalog.thumbsPerPage.max) nX = Catalog.thumbsPerPage.max;
			Catalog.thumbsPerPage.current = nX;

			if (!Catalog.bProductsLoaded) {
				Catalog.thumbsPerPage.prev = Catalog.thumbsPerPage.current;
			}
		}
	},
	show: function () {
		$("#NavigationWrapper").hide();
		$("#NavigationWrapper").fadeIn();
		Catalog.windowResized();
		$("#Rewards").show();
		Catalog.categoryChanged("static,leftright", function () {
			if (!User.key) {
				Login.showTip();
			}
		});
	},
	hide: function (callback) {
		Catalog.pageChanged("leftright,hide", function () {
			$("#Rewards").fadeOut();
			if (callback) callback();
		});
	},
	windowResized: function () {
		if ($(document).width() < 700)
			$("#TokenLogo").hide();
		else
			$("#TokenLogo").show();

		if (!Catalog.bProductsLoaded) return;

		var catThumbs = Catalog.thumbsPerPage;
		catThumbs.setCurrent();

		if (catThumbs.current == catThumbs.prev) return;

		var nFirstVisible = $(".ProductThumb:first").data("index");
		var bLastPage = ($("#selPageFilter").val() == $("#selPageFilter option").length) ? true : false;
		if (bLastPage) {
			$(".ProductThumb").addClass("hidden");
		}
		var nX = 0;
		if (catThumbs.current < catThumbs.prev) {
			//remove thumbs, recalc page filters
			for (nX = catThumbs.prev - 1; nX > catThumbs.current - 1; nX--) {
				$(".ProductThumb").eq(nX).remove();
			}
		}
		if (catThumbs.current > catThumbs.prev) {
			//add thumbs, recalc page filters
			for (nX = catThumbs.prev; nX < catThumbs.current; nX++) {
				Catalog.appendProduct($(".ProductThumb:last").data("index") + 1);
			}
			if (User.bLoggedIn) SetRewardUnitElements(".ProductThumb .ProductThumb-Price");
		}
		catThumbs.prev = catThumbs.current;
		Catalog.createPageOptions();
		var nNewPageCnt = $("#selPageFilter option").length;
		if (bLastPage) {
			$("#selPageFilter").val(nNewPageCnt);
			Catalog.pageChanged("none");
			return;
		}
		//find which page the last visible product is now on, and changed to that page.
		var nNewPage = Math.ceil(nFirstVisible / Catalog.thumbsPerPage.current) + 1;
		$("#selPageFilter").val(nNewPage);
		Catalog.pageChanged("none");
	},

	fetchProducts: function (callback) {
		ui.elap.on();
		new execQuery("select * from shop$products(null," + User.ProviderAccountID.prepSQL(true) + ");",
			function (aTables) {
				Catalog.productsFetched(aTables, callback);
			}
		);
	},
	productsFetched: function (aTables, callback) {
		if (!aTables[0] || aTables[0].length == 0) {
			$("body").append('<div>We appear to be having technical difficulties showing our products. Please try reloading the web site.</div>');
			return;
		}

		Catalog.aMasterProducts = $.extend(true, [], aTables);
		$("#RewardObjects").empty();
		Catalog.thumbsPerPage.setCurrent();
		for (var nX = 0; nX < Catalog.aMasterProducts.length; nX++) {
			if (Catalog.aMasterProducts[nX].CUSTOM_REWARD != "1")
				preLoadImages("http://tokenrewards.com/product_images/small/" + Catalog.aMasterProducts[nX].CODE + ".gif");

			Catalog.createCategories.appendArray(Catalog.aMasterProducts[nX].CATEGORIES);
			if (nX < Catalog.thumbsPerPage.current) { Catalog.appendProduct(nX); }
		}

		if (Catalog.aMasterProducts[0].TOKENUNIT) {
			// Products fetched pre-login with admin cookie in place
			$(".ProductThumb-Price").find(".TextRewardUnits").text(Catalog.aMasterProducts[0].TOKENUNIT + "s").end().removeClass('hidden');
			User.bShowPrices = true;
			User.oData.TOKENRATE = Catalog.aMasterProducts[0].TOKENRATE;
			User.oData.TOKENUNIT = Catalog.aMasterProducts[0].TOKENUNIT;
			Application.oUser.TOKENUNIT = User.oData.TOKENUNIT;
			Application.oUser.TOKENRATE = User.oData.TOKENRATE;

			$("#Navigator, #selPageFilter").addClass("showPrices");
			$("#NewsTicker").append(
				'<div class="tickerItem providerInfo">' +
					'<span class="providerLabel">Your rewards are provided by:</span>' +
					'<span class="providerName">' + Catalog.aMasterProducts[0].PROVIDER_NAME + '</span>' +
				'</div>'
			);
			NewsTicker.begin();
		}

		Catalog.createCategories.appendHTML();

		ui.elap.off();
		if (callback) callback();
	},
	appendProduct: function (nProductIndex) {
		var jThumb = $(".ProductThumb.prototype").clone().removeClass("prototype").attr("index", nProductIndex)
		.click(function (event) {
			event.stopPropagation();
			Catalog.thumbClicked(this);
		});
		$(".ProductThumb-Ordered", jThumb).click(function (event) {
			event.stopPropagation();
			$(this).parent().click();
		});
		$("#RewardObjects").append(jThumb);
	},
	createCategories: {
		aCats: [],
		appendArray: function (cCategories) {

			var aX = cCategories.split(/,/);
			if (aX[0].length == 0) return;
			var aCats = Catalog.createCategories.aCats;
			var bCatFound = false;

			for (var nX = 0; nX < aX.length; nX++) {
				bCatFound = false;
				for (var nY = 0; nY < aCats.length; nY++) {
					if (aX[nX] == aCats[nY].name) { aCats[nY].count++; bCatFound = true; break; }
				}
				if (!bCatFound) { aCats[aCats.length] = { name: aX[nX], count: 1 }; }
			}
		},
		appendHTML: function () {

			var aCats = Catalog.createCategories.aCats;
			aCats.sort(function (a, b) {
				var compA = a.name.toUpperCase();
				var compB = b.name.toUpperCase();
				return (compA < compB) ? -1 : (compA > compB) ? 1 : 0;
			})
			var jSelCategory = $("#selCategory").empty();
			jSelCategory.append('<option value="All" style="font-weight:bold">Everything</option>');
			for (var nX = 0; nX < aCats.length; nX++) {
				jSelCategory.append('<option value="' + aCats[nX].name + '" count="' + aCats[nX].count + '">&nbsp;' + aCats[nX].name + '</option>');
			}
			jSelCategory.append('<option value="OrderedItems" style="font-weight:bold">My Orders</option>');

			//IE6 workaround - DOM needs a millisec to "catchup" before setting default value
			try { jSelCategory.val(Catalog.cDefaultCategory); }
			catch (ex) { setTimeout(function () { jSelCategory.val(Catalog.cDefaultCategory); }, 1); }

			Catalog.bProductsLoaded = true;
		}
	},
	updateDisplayProducts: function () {
		Catalog.aDisplayProducts = $.extend(true, [], Catalog.aMasterProducts);
		var oSel = $("#selCategory");
		if (oSel.val() != "All" && oSel.val() != "OrderedItems") {
			Catalog.aDisplayProducts = $.grep(Catalog.aDisplayProducts, function (oProduct, nIndex) {
				return (oProduct.CATEGORIES.indexOf(oSel.val()) != -1);
			});
		}
		if (oSel.val() == "OrderedItems") {
			Catalog.aDisplayProducts = $.grep(Catalog.aDisplayProducts, function (oProduct, nIndex) {
				return (oProduct.QTY_ON_ORDER > 0);
			});
		}

		var aOrders = $.grep(Catalog.aMasterProducts, function (oProduct, nIndex) { return (oProduct.QTY_ON_ORDER > 0); });
		if (aOrders.length == 0) {
			$("label[for=btnOrders]").hide();
			oSel.find("option").last().text("No Orders").hide();
		}
		else {
			$("label[for=btnOrders]").show();
			$("#btnOrders").button({ label: aOrders.length });
			oSel.find("option").last().text("My Orders (" + aOrders.length + ")").show();
		}
	},
	createPageOptions: function () {
		var nPages = Math.ceil(Catalog.aDisplayProducts.length / Catalog.thumbsPerPage.current);
		var jSelPageFilter = $("#selPageFilter");
		jSelPageFilter.find("option").remove();
		for (var nPage = 0; nPage < nPages; nPage++) {
			if (!User.oData.TOKENRATE) {
				jSelPageFilter.append('<option value="' + String(nPage + 1) + '">Page ' + String(nPage + 1) + '</option>');
			} else {
				var nFirstProduct = nPage * Catalog.thumbsPerPage.current;
				var nLastProduct = (nPage == nPages - 1) ? Catalog.aDisplayProducts.length - 1 : ((nPage + 1) * Catalog.thumbsPerPage.current) - 1;
				var nHigh = (nPage == 0) ? "Up" : Catalog.aDisplayProducts[nFirstProduct].TOKENS_EACH;
				var nLow = Catalog.aDisplayProducts[nLastProduct].TOKENS_EACH;
				jSelPageFilter.append(
					'<option value="' + String(nPage + 1) + '">' + //Page ' + String(nPage + 1) + ': ' +
					nHigh + ' to ' + nLow + ' ' + User.oData.TOKENUNIT + 's' +
					'</option>');
			}
		}

		if (nPages <= 1) {
			//Disable Page Navigation
		} else {
			//Enabled
		}

	},
	initPageNavBtns: function () {
		var jSelPage = $("#selPageFilter").bgiframe().change(function () {
			LogEntry("Page " + $(this).val() + " selected.");
			Catalog.pageChanged();
		});
		var jSelCat = $("#selCategory").bgiframe().change(function () {
			LogEntry($(this).val() + " category selected.");
			Catalog.categoryChanged();
		});

		$("#Navigator .navButton")
		.click(function () {
			if ($(this).attr("disabled") == "true") return;
			LogEntry("Nav. button '" + $(this).attr("navorder") + "' clicked.");
			switch ($(this).attr("navorder")) {
				case "prevcat": jSelCat[0].selectedIndex--; Catalog.categoryChanged(); break;
				case "nextcat": jSelCat[0].selectedIndex++; Catalog.categoryChanged(); break;

				case "start": jSelPage.val(1); Catalog.pageChanged(); break;
				case "prev": jSelPage.val(Number(jSelPage.val()) - 1); Catalog.pageChanged(); break;
				case "next": jSelPage.val(Number(jSelPage.val()) + 1); Catalog.pageChanged(); break;
				case "end": jSelPage.val(jSelPage.find("option").length); Catalog.pageChanged(); break;
			}
		})
		.filter("[navorder='prevcat']").button({ text: false, icons: { primary: 'ui-icon-arrowthick-1-n', secondary: null} }).end()
		.filter("[navorder='nextcat']").button({ text: false, icons: { primary: 'ui-icon-arrowthick-1-s', secondary: null} }).end()
		.filter("[navorder='start']").button({ text: false, icons: { primary: 'ui-icon-seek-start', secondary: null} }).end()
		.filter("[navorder='prev']").button({ text: false, icons: { primary: 'ui-icon-seek-prev', secondary: null} }).end()
		.filter("[navorder='next']").button({ text: false, icons: { primary: 'ui-icon-seek-next', secondary: null} }).end()
		.filter("[navorder='end']").button({ text: false, icons: { primary: 'ui-icon-seek-end', secondary: null} }).end()
		;
		$("#Navigator .buttonSet").buttonset();
	},
	thumbClicked: function (oClicked) {
		Login.hideTip();

		var nProductId = $(oClicked).data("ID");
		for (var nX = 0; nX < Catalog.aPopups.length; nX++) {
			if (Catalog.aPopups[nX].nProductId == nProductId) {
				if (Catalog.aPopups[nX].tip.css("display") != "none") {  //is(":visible"))
					Catalog.aPopups[nX].hidePopup();
					return;
				}
				Catalog.aPopups[nX].trigger = $(oClicked);
				Catalog.aPopups[nX].showPopup();
				return;
			}
		}
		// Product's popup had not been created yet.  Go ahead and new it.
		Catalog.aPopups[Catalog.aPopups.length] = new ProductPopup($(oClicked));
	},
	categoryChanged: function (cAnimationOrder, callback) {
		var oSel = $("#selCategory");

		var nSelectedCat = oSel[0].selectedIndex;
		var nTotCats = oSel.find("option").length;

		$(".navCategoryButtonSet .navButton").mouseleave().button("enable");
		if (nSelectedCat == 0) {
			$(".navButton[navorder='prevcat']").button("disable");
		}

		if (nSelectedCat + 1 == nTotCats) {
			$(".navButton[navorder='nextcat']").button("disable");
		}

		Catalog.updateDisplayProducts();
		Catalog.createPageOptions();
		if (cAnimationOrder == undefined) {
			if (nSelectedCat > Catalog.nCurrentCatIndex) cAnimationOrder = "bottom,top";
			else if (nSelectedCat < Catalog.nCurrentCatIndex) cAnimationOrder = "top,bottom";
			else cAnimationOrder = "none";
		}
		Catalog.nCurrentCatIndex = nSelectedCat;
		Catalog.pageChanged(cAnimationOrder, callback);
	},
	pageChanged: function (cAnimationOrder, callback) {
		var jThumbs = $("#RewardObjects .ProductThumb");
		var my = this;
		this.moveIn = false;
		var jPageFilter = $("#selPageFilter");
		var nSelectedPage = Number(jPageFilter.val()) - 1;
		var nTotPages = jPageFilter.find("option").length;

		// Animtation[0] is move to positiob, Animation[1] = move from position, Animation[2] is final position (undefined==0px or "hide")
		var aAnimations = [];
		if (cAnimationOrder != undefined)
			var aAnimations = cAnimationOrder.split(',');

		if (aAnimations[1] == undefined) aAnimations[1] = aAnimations[0];

		if (aAnimations[0] == undefined) {
			if (nSelectedPage > Catalog.nCurrentPage) aAnimations = ["left", "right"];
			else if (nSelectedPage < Catalog.nCurrentPage) aAnimations = ["right", "left"];
			else aAnimations[0] = "none";
		}

		Catalog.nCurrentPage = nSelectedPage;

		this.fixNavigators = function () {
			//Enable-Disable Nav buttons as necessary

			$(".navPageButtonSet .navButton").mouseleave().button("enable")
			if (nSelectedPage == 0) {
				$(".navButton[navorder='start'],.navButton[navorder='prev']").button("disable");
			}

			if (nSelectedPage + 1 == nTotPages) {
				$(".navButton[navorder='next'],.navButton[navorder='end']").button("disable");
			}

		}

		var oDoc = { width: $(document).width() + 120, height: $(document).height() + 150 };

		this.oMove = {
			cOrder: function (cPosOrder, nIndex) {
				if (cPosOrder == "random") {
					var nInt = Math.floor(Math.random() * 4);
				}
				if (cPosOrder == "leftright") {
					var nInt = nIndex % 2;
				}
				if (cPosOrder == "updown") {
					var nInt = (nIndex % 2) + 2;
				}
				if (cPosOrder == "fourway") {
					var nInt = nIndex % 4;
				}
				switch (nInt) {
					case 0: return "left"; break;
					case 1: return "right"; break;
					case 2: return "top"; break;
					case 3: return "bottom"; break;
				}

				return cPosOrder;
			},
			left: function (cToFrom, nIndex) {
				var nToFrom = (cToFrom == "to") ? 0 : 1;
				var cOrder = my.oMove.cOrder(aAnimations[nToFrom], nIndex);
				switch (cOrder) {
					case "left": return "-" + oDoc.width + "px"; break;
					case "right": return "0" + oDoc.width + "px"; break;
					case "top": return "0px"; break;
					case "bottom": return "0px"; break;

				}
			},
			top: function (cToFrom, nIndex) {
				var nToFrom = (cToFrom == "to") ? 0 : 1;
				switch (my.oMove.cOrder(aAnimations[nToFrom], nIndex)) {
					case "left": return "0px"; break;
					case "right": return "0px"; break;
					case "top": return "-" + oDoc.height + "px"; break;
					case "bottom": return "" + oDoc.height + "px"; break;
				}

			}
		}

		this.moveOut = function () {
			var moveBack = function () {
				Catalog.drawPage();
				jThumbs.css({ "display": "" }).each(function (index, element) {
					$(element).animate({ "left": "0px", "top": "0px" }, 1500, "easeOutBack", function () {
						if (index == jThumbs.length - 1) {
							if (callback) callback();
						}
					});
				});
			}

			jThumbs.stop(true, false).each(function (index, element) {
				if (aAnimations[0] == "static") {
					$(element).css({ "left": my.oMove.left("from", index), "top": my.oMove.top("from", index) });
					return;
				}
				$(element).animate({ "left": my.oMove.left("to", index), "top": my.oMove.top("to", index) }, 750, 'easeInQuad',
					function () {
						$(this).css({ "left": my.oMove.left("from", index), "top": my.oMove.top("from", index) });
						if (index == jThumbs.length - 1) {
							if (aAnimations[1] != "hide") { moveBack(); }
							else if (callback) callback();
						}
					});
			});
			if (aAnimations[0] == "static") { moveBack(); }
		}
		this.fixNavigators();

		if (aAnimations[0] == "none") Catalog.drawPage();
		else this.moveOut();
	},
	drawPage: function () {
		var nSelectedPage = Number($("#selPageFilter").val()) - 1;
		var jThumbs = $("#RewardObjects .ProductThumb");
		if (Catalog.aDisplayProducts.length == 0) { jThumbs.addClass("hidden"); return; }

		for (var nX = 0; nX < Catalog.thumbsPerPage.current; nX++) {
			var nProductIndex = nSelectedPage * Catalog.thumbsPerPage.current + nX;

			var jProduct = jThumbs.eq(nX);
			if (nProductIndex >= Catalog.aDisplayProducts.length) {
				jProduct.addClass("hidden");
				continue;
			}
			var oProduct = Catalog.aDisplayProducts[nProductIndex];

			jProduct.find('.ProductThumb-Image')[0].src = "/Common/Images/Elapsors/SmallLoading.gif";
			if (oProduct.CUSTOM_REWARD == "1") {
				jProduct.find('.ProductThumb-Image')[0].src = "/Common/customer_images/" + oProduct.CODE + ".gif?" + Date.now().getTime();
				if (oProduct.HTML_USED == "1") {
					oProduct.NAME = oProduct.NAME.encodeHTML();
					oProduct.DESCRIPTION = oProduct.DESCRIPTION.encodeHTML();
				}
			}
			else
				jProduct.find('.ProductThumb-Image')[0].src = "http://tokenrewards.com/product_images/small/" + oProduct.CODE + ".gif";



			jProduct.removeClass("hidden")
			.data({
				"index": nProductIndex,
				"isCustomReward": oProduct.CUSTOM_REWARD == "1"
			})
			.data(oProduct)
			.find('.ProductThumb-Name').html(oProduct.NAME)
			.end();


			if (Number(oProduct.TOKENS_EACH) > 0) {
				jProduct.find(".ProductThumb-Price").removeClass("hidden")
				.find(".UserPrice").text(oProduct.TOKENS_EACH).end()
				.find(".TextRewardUnits").text(Application.oUser.TOKENUNIT.toPlural(oProduct.TOKENS_EACH));
			}
			jProduct.find(".shipLogo").hide();
			if (oProduct.QTY_ON_ORDER > 0 || oProduct.ARRIVAL_DATE) {
				var jOrderedThumb = jProduct.find(".ProductThumb-Ordered");

				jOrderedThumb
					.removeClass("hidden")
					.removeClass("shipped")
					.find(".orderDescript").text(oProduct.QTY_ON_ORDER + " " +
						((oProduct.QTY_ON_INVOICE > 0) ?
						((oProduct.QTY_SHIPPED > 0) ?
						'arriving ' + oProduct.ARRIVAL_DATE.toDateFormat("smallDate") + "!" : 'on the way!')
						: 'on order!')
					);

				if (oProduct.ARRIVAL_DATE && (oProduct.QTY_SHIPPED.toNumber() > 0)) {
					jProduct.find(".shipLogo").show();
					jOrderedThumb.addClass("shipped");
				}

			}
			else {
				jProduct.find(".ProductThumb-Ordered").addClass("hidden").find(".orderDescript").text('');
			}
		}

		if ($("#NewAccountPane").is(":visible")) { $(".ProductThumb").hide(); }
	}
};

var ProductPopup = function (jClicked) {
	var self = this;
	this.tip;
	this.triggertimer;
	this.tiptimer;
	this.shrinkTimeOut;
	this.trigger = jClicked;
	this.nProductId = jClicked.data('ID');
	this.isCustomReward = (jClicked.data('CUSTOM_REWARD') == "1");

	LogEntry("Product " + jClicked.data('CODE') + " - " + jClicked.data("NAME") + " - clicked.");

	this.shrinkImage = function (cSpeed) {
		var nSpeed = 2500;
		switch (cSpeed) {
			case false: nSpeed = 1500; break;
			case "fast": nSpeed = 500; break;
			case "slow": nSpeed = 2500; break;
		}

		var jImg = self.tip.find(".ProductPopUpImage");
		var jDetails = self.tip.find(".ProductPopUpDetails")

		jImg.stop(true, false).animate({ width: "95px", height: "95px" }, nSpeed, "easeOutBack", function () { });
		jDetails.fadeIn(nSpeed * .6, function () { });
	};
	this.growImage = function () {
		var jImg = self.tip.find(".ProductPopUpImage");
		var jDetails = self.tip.find(".ProductPopUpDetails")

		jImg.stop();
		if (jImg.width() < 288)
			jImg.animate({ width: "288px", height: "288px" }, 750, "easeOutBounce");
		jDetails.fadeOut(500, function () { });
	};

	this.createPopup = function () {
		var cDescription = self.trigger.data("DESCRIPTION") +
			(!self.trigger.data("isCustomReward") ? "<br/><br /><b>Warning:</b> CHOKING HAZARD - Not for Children Under 3 years." : '');

		self.tip = $('.ProductPopUp.prototype').clone().removeClass('prototype');
		if (ui.IE6) {
			self.tip.addClass("useBGImg");
			$(".imgPopupBG", self.tip).remove();
		}

		$(".categoryName", self.tip).text(self.trigger.data("CATEGORIES"));
		$(".productCode", self.tip).text(self.trigger.data("CODE"));
		$(".ProductPopUpName", self.tip).html(self.trigger.data("NAME"));
		$(".ProductPopUpDescript", self.tip).html(cDescription);
		$(".ProductPopUpImage", self.tip).attr("src", !self.trigger.data("isCustomReward") ?
			"http://tokenrewards.com/product_images/large/" + self.trigger.data("CODE") + ".gif" :
			"/Common/customer_images/" + self.trigger.data("CODE") + ".gif?" + Date.now().getTime());


		$(document.body).append(self.tip);
		self.tip.bgiframe()
		.hover(
			function () {
				clearTimeout(self.triggertimer);
				clearTimeout(self.tiptimer);
			},
			function () { self.tiptimer = setTimeout(function () { self.hidePopup(); }, 500) })
		.find(".ProductZoomTrigger").hover(
			function () { self.growImage(); },
			function () { self.shrinkImage("fast"); })
		.end().find(".ProductPopUpImage").mouseenter(
			function () {
				clearTimeout(self.shrinkTimeOut);
				$(this).stop(true, false);
				self.tip.find(".ProductPopUpDetails").stop(true, true);
				self.shrinkImage("fast");
			})
		.end().find(".ProductPopUpClose").click(function () { self.hidePopup(); })
		.end().find(".createOrder")
			.button({ text: true, label: "Order Now!", icons: { primary: "ui-icon-cart"} })
			.click(function () { self.createOrder_clicked(); })
		.end();


		if (self.trigger.data("isCustomReward")) {
			$(".cancelOrder", self.tip).addClass('noCancelNote').html(
				'Contact the ' + User.ProviderName + ' shop administrator ' +
				'to cancel this order.'
			);
		}
		else {
			$(".cancelOrder", self.tip)
			.button({ text: true, label: "Cancel Order", icons: { primary: "ui-icon-closethick"} })
			.click(function () { self.cancelOrder_clicked(); });
		}

	};
	this.showPopup = function () {
		var tip = self.tip;
		var trigger = self.trigger;
		var SetPosition = function () {
			var TestPosition = function (aPos, aOffset) {
				var bVSuccess = false, bHSuccess = false;
				var nTipTop = 0, nTipLeft = 0, nTipRight = 0, nTipBottom = 0;

				var nWithin = -25;
				switch (aPos[0]) {
					case "left":
						nTipLeft = aOffset[0] + nTriggerLeft - nTipWidth;
						bHSuccess = nTipLeft > nWithin && (nTipLeft + nTipWidth < nViewWidth - nWithin);
						break;
					case "center":
						nTipLeft = aOffset[0] + nTriggerLeft + nTriggerWidth / 2 - nTipWidth / 2;
						nTipRight = aOffset[0] + nTriggerLeft + nTriggerWidth / 2 + nTipWidth / 2;
						bHSuccess = (nTipLeft > nWithin && nTipRight < nViewWidth - nWithin);
						break;
					case "right":
						nTipLeft = aOffset[0] + nTriggerLeft + nTriggerWidth;
						bHSuccess = (nTipLeft + nTipWidth < nViewWidth - nWithin);
						break;
				}

				var nWithin = 50;
				switch (aPos[1]) {
					case "top":
						nTipTop = aOffset[1] + nTriggerTop - nTipHeight;
						bVSuccess = nTipTop > -nWithin;
						break;
					case "center":
						nTipTop = aOffset[1] + nTriggerTop + (nTriggerHeight / 2) - nTipHeight / 2;
						nTipBottom = nTipTop + nTipHeight;
						bVSuccess = (nTipTop > -nWithin && nTipBottom < nViewHeight + nWithin);
						break;
					case "bottom":
						nTipTop = aOffset[1] + nTriggerTop + nTriggerHeight;
						bVSuccess = (nTipTop + nTipHeight < nViewHeight + nWithin);
						break;
				}

				if (bVSuccess && bHSuccess) {
					tip.css({ top: String(nTipTop) + "px", left: String(nTipLeft) + "px" });
					return true;
				} else return false;
			}

			var viewport = $(window);
			var nViewHeight = Number(viewport.height());
			var nViewWidth = Number(viewport.width());


			var nTipHeight = 435; // Number(tip.height());
			var nTipWidth = 400; // Number(tip.width());

			var nTriggerHeight = Number(trigger.height());
			var nTriggerWidth = Number(trigger.width());

			var TriggerOffset = trigger.offset();

			var nTriggerTop = TriggerOffset.top
			var nTriggerLeft = TriggerOffset.left;

			var jPointer = tip.find(".Pointer");
			jPointer.removeClass("North South East West Left Right Top Bottom hidden");
			var aTestOffSet = [0, 0];

			if (TestPosition(["right", "center"], [-25, 75])) { jPointer.addClass("West Top"); return true; }
			if (TestPosition(["left", "center"], [25, 75])) { jPointer.addClass("East Top"); return true; }

			if (TestPosition(["right", "center"], [-25, -3])) { jPointer.addClass("West"); return true; }
			if (TestPosition(["left", "center"], [25, -3])) { jPointer.addClass("East"); return true; }

			if (TestPosition(["right", "center"], [-25, -100])) { jPointer.addClass("West Bottom"); return true; }
			if (TestPosition(["left", "center"], [25, -100])) { jPointer.addClass("East Bottom"); return true; }

			if (TestPosition(["center", "top"], [-3, 28])) { jPointer.addClass("South"); return true; }
			if (TestPosition(["center", "bottom"], [-3, -25])) { jPointer.addClass("North"); return true; }

			if (TestPosition(["center", "bottom"], [90, -25])) { jPointer.addClass("North Left"); return true; }
			if (TestPosition(["center", "bottom"], [-100, -25])) { jPointer.addClass("North Right"); return true; }

			if (TestPosition(["center", "top"], [90, 28])) { jPointer.addClass("South Left"); return true; }
			if (TestPosition(["center", "top"], [-100, 28])) { jPointer.addClass("South Right"); return true; }


			//			if (TestPosition(["bottom", "right"], [-nTriggerHeight - 20, -30])) { jPointer.addClass("East Top"); return true; }
			//			if (TestPosition(["top", "left"], [nTriggerHeight + 20, 30])) { jPointer.addClass("East Bottom"); return true; }
			//			if (TestPosition(["top", "right"], [nTriggerHeight + 20, -30])) { jPointer.addClass("West Bottom"); return true; }

			//If doesn't fit anywhere else, then middle of screen
			tip.css({ top: String((nViewHeight / 2) - (nTipHeight / 2) + 20) + "px",
				left: String((nViewWidth / 2) - (nTipWidth / 2)) + "px"
			})
			jPointer.addClass("hidden");

		}

		var oImg = tip.find(".ProductPopUpImage");
		oImg.css({ width: "288px", height: "288px" });
		tip.find(".ProductPopUpDetails").css("display", "none");

		SetPosition();

		self.trigger.mouseenter(function () {
			clearTimeout(self.triggertimer);
			clearTimeout(self.tiptimer);
		})
		.mouseleave(function () {
			self.triggertimer = setTimeout(function () { self.hidePopup(); }, 500);
		});


		if (User.bShowPrices) {
			tip.find(".ProductPopUpBottom")
			.find(".TokenPrice").text(trigger.data("TOKENS_EACH")).removeClass("hidden").end()
			.find(".TokenUnit").text(Application.oUser.TOKENUNIT.toPlural(self.trigger.data("TOKENS_EACH")))
			.removeClass("hidden").end()
			.removeClass("hidden");
		}

		if (User.key) {
			if (trigger.data("QTY_ON_ORDER") == 0) {
				tip.find(".cancelOrder,.orderDetails").hide().end()
					.find(".createOrder").show().end()
					.find(".orderDetails").hide();
			}
			else {
				tip.find(".createOrder").hide();
				if (trigger.data("QTY_ON_INVOICE") == 0) {
					tip.find(".cancelOrder").show().end()
						.find(".orderDetails").hide();
				}
				else {
					tip.find(".cancelOrder").hide();
					tip.find(".orderDetails").html(
						trigger.data("QTY_ON_ORDER") + " " +
						((trigger.data("QTY_SHIPPED") > 0) ?
							'arriving ' + trigger.data("ARRIVAL_DATE").toDateFormat("smallDate")
							: 'on the way')
						+ "!"
					);
				}
			}

		}

		//$.sound.play("claves.wav", { timeout: 1000 });
		tip.fadeIn(250);
		self.shrinkTimeOut = setTimeout(function () {
			self.shrinkImage("slow"); clearTimeout(self.shrinkTimeOut);
		}, 1000);
	}
	this.hidePopup = function () {
		clearTimeout(self.shrinkTimeOut);
		self.tip.children().stop(true, true);
		self.trigger.unbind('mouseenter').unbind('mouseleave');
		self.tip.fadeOut(500);
	}
	this.orderQty_changed = function () {
		var jSel = $("#selOrderQty");
		var nPrice = Number(self.trigger.data("TOKENS_EACH")) * Number(jSel.val());
		var cPriceStr = nPrice + " " + User.oData.TOKENUNIT.toLowerCase().toPlural(nPrice);
		$(".orderTotalPrice").text(cPriceStr);
		$(".newBalance").text(String(Number(User.oData.BALANCE) - nPrice));
	}
	this.createOrder_clicked = function () {
		LogEntry("Product# " + self.nProductId + " 'Order Now...' clicked.");
		self.hidePopup();
		var cTitle = "Confirm Order"
		var nBal = Number(User.oData.BALANCE);
		var nPrice = Number(self.trigger.data("TOKENS_EACH"));
		var cPriceStr = nPrice + " " + User.oData.TOKENUNIT.toPlural(nPrice);

		if (nPrice > nBal) {
			$("#wrapOrderQty").hide();
			$("#notEnoughFunds").show().find(".orderRequires")
				.text(String(nPrice - nBal) + " more " + User.oData.TOKENUNIT.toLowerCase().toPlural(nPrice));
			cTitle = "Not Enough " + User.oData.TOKENUNIT + "s";
		} else {
			$("#notEnoughFunds").hide();
			var nMaxQty = Math.floor(nBal / nPrice);
			if (nMaxQty > 100) nMaxQty = 50;
			var jSel = $("#selOrderQty").empty();
			for (var nX = 1; nX <= nMaxQty; nX++) {
				jSel.append('<option>' + nX + '</option>');
			}
			jSel.val("1").unbind().bind("change", self.orderQty_changed);
			jSel.change();
			$("#wrapOrderQty").show();
		}

		$("#warnCustomReward").hide();
		if (self.trigger.data().isCustomReward) $("#warnCustomReward").show();

		$("#diagConfirmOrder")
		.find(".orderItemImg").attr("src", $(".ProductThumb-Image", self.trigger).attr("src")).end()
		.find(".orderItemName").html(self.trigger.data("NAME")).end()
		.find(".orderItemPrice").text(cPriceStr + " each.").end()
		.dialog({
			bgiframe: true,
			width: 350,
			autoOpen: true,
			modal: true,
			title: cTitle,
			open: function () {
				var jBtns = $(this).siblings(".ui-dialog-buttonpane").find("button");
				jBtns.eq(0).button({ icons: { primary: "ui-icon-check"} });
				jBtns.eq(1).button({ icons: { primary: "ui-icon-closethick"} });

				if (nPrice > nBal)
					jBtns.eq(0).button("disable");
			},
			buttons: {
				"Place Order": function () { self.saveOrder(); },
				"Cancel": function () {
					LogEntry("Product# " + self.nProductId + " ordering canceled.");
					$(this).dialog('close');
				}
			},
			close: function (event, ui) { $(this).dialog('destroy'); }
		});

	};
	this.cancelOrder_clicked = function () {
		LogEntry("Product# " + self.nProductId + " 'Cancel Order' clicked.");
		self.hidePopup();
		ui.openWait("Canceling " + self.trigger.data("NAME") + " order...", true);
		var cSQL = DataHandler.closeWish(self.nProductId) + DataHandler.account + DataHandler.userProducts;
		DataHandler.execute(cSQL, function (aTables) {
			if (aTables[0][0].ERR$NAME > '') {
				ui.modalMessage({
					message: "Sory, we had a problem canceling the order:<br /><br />" + aTables[0][0].ERR$MESSAGE,
					title: "Problem Canceling Order"
				});
			}
			User.postOrderRefresh(aTables[1][0], aTables[2]); ;
		});
	};

	this.saveOrder = function () {
		LogEntry("Product# " + self.nProductId + " 'Place Order' (qty " + $("#selOrderQty").val() + ") clicked!.");
		self.hidePopup();
		$("#diagConfirmOrder").dialog('close');

		var nQty = $("#selOrderQty").val().toNumber();

		ui.openWait("Creating order for " + self.trigger.data("NAME") + "...", true);

		var cSQL = "select * from shop$create_order(" + User.key.prepSQL() + "," +
						self.nProductId.prepSQL() + "," +
						nQty.prepSQL() + "," +
						self.trigger.data("CUSTOM_REWARD").prepSQL(true) + ");";

		cSQL += DataHandler.account +
					DataHandler.userProducts +
					DataHandler.ledger;

		DataHandler.execute(cSQL, function (aTables) {
			User.postOrderRefresh(aTables[1][0], aTables[2], aTables[3]);
			if (aTables[0][0].ERR$NAME > '') {
				ui.modalMessage({
					message: "Sorry, we had a problem placing the order:<br /><br />" + aTables[0][0].ERR$MESSAGE,
					title: "Problem Creating Order"
				});
				return;
			}
			if (self.isCustomReward && User.oData.SHOP_ADMIN_EMAIL) {
				ui.openWait("Delivering e-mail to the shop administrator for " + User.ProviderName + "...", true);
				// send email to administrator
				var oPartyName = User.oData.NAME.parseName();
				var oPronouns = genderPronouns(User.oData.GENDER);
				var nPrice = nQty * self.trigger.data("TOKENS_EACH").toNumber();
				var sPrice = nPrice + " " + User.oData.TOKENUNIT.toLowerCase().toPlural(nPrice);
				Email.send({
					to_contact_id: User.oData.SHOP_ADMIN_ID,
					to_name: User.oData.SHOP_ADMIN_NAME,
					to_address: User.oData.SHOP_ADMIN_EMAIL,
					template: 'shop_custom_reward_ordered',
					contents: Email.contentTemplates.shop_custom_reward_ordered
						.replace(/__party_name__/g, oPartyName.short)
						.replace(/__admin_name__/g, User.oData.SHOP_ADMIN_NAME)
						.replace(/__party_first__/g, oPartyName.nick)
						.replace(/__reward_title__/g, self.trigger.data("TITLE_PLAIN"))

						.replace(/__party_code__/g, User.oData.CODE.toUpperCase())
						.replace(/__qty__/g, nQty)
						.replace(/__reward_price__/g, sPrice)
						.replace(/__has_have__/g, (nPrice == 1) ? 'has' : 'have')
						.replace(/__party_balance__/g, User.oData.BALANCE + " " + User.oData.TOKENUNIT.toLowerCase().toPlural(User.oData.BALANCE))

						.replace(/__adjective__/g, oPronouns.adjective)
						.replace(/__objective__/g, oPronouns.objective)
						,
					callback: function (bSuccess) {
						ui.closeWait();
					}
				});
			}
		});
	};
	this.createPopup();
	this.showPopup();
};

var User = {
	bLoggedIn: false,
	bShowPrices: false,
	key: '',
	nickName: '',
	oData: {},
	aAwards: [], aLedger: [], aContacts: [], aShipSchedule: [],
	ProviderAccountID: 0,
	ProviderName: '',
	updateDisplayCnt: 0,
	updateBalanceDisplay: function (callback) {
		$(".UserBalance").text(Number(User.oData.BALANCE));

		$(".orderedItemsCount").text(Number(User.oData.PENDING_ITEM_QTY));
		$(".orderedItemsTotal").text(Number(User.oData.PENDING_TOKENS));
		var jUserInfo = $("#UserInfo").removeClass("hidden");
		if (User.updateDisplayCnt == 0) {
			var cNote = NewsTicker.welcomeNote() +
			"&nbsp;&nbsp;You have " + User.oData.BALANCE + " " + User.oData.TOKENUNIT.toLowerCase().toPlural(User.oData.BALANCE) + ".";
			jUserInfo.html(cNote).css({ "right": "-" + (jUserInfo.width() + 10) + "px" })
			.animate({ right: "10px" }, 3000, "easeOutQuad");
		}
		else {
			var cNote = User.nickName + ", you now have " + User.oData.BALANCE + " " + User.oData.TOKENUNIT.toLowerCase().toPlural(User.oData.BALANCE) + ".";
			jUserInfo.animate({ "right": "-" + (jUserInfo.width() + 10) + "px" }, 1000, "easeInExpo", function () {
				jUserInfo.text(cNote).css({ "right": "-" + (jUserInfo.width() + 10) + "px" }).animate({ right: "10px" }, 2000, "easeOutExpo",
			function () { jUserInfo.effect("pulsate", { mode: "show", times: 3 }, 500, function () { if (callback) callback(); }); });
			});
		}
		User.updateDisplayCnt++;
		//if (bPulsateBalance) $("#MenuBar .UserBalance,#MenuBar .orderedItemsCount:visible").effect("pulsate", { mode: "show", times: 5 }, 750);
	},
	postOrderRefresh: function (oUser, aProducts, aLedger) {
		Catalog.aMasterProducts = $.extend(true, [], aProducts);
		if (aLedger) User.aLedger = $.extend(true, [], aLedger);

		User.refreshAccount(oUser, true);
		ui.closeWait();

		Catalog.updateDisplayProducts();
		if (window.location.hash == "#Rewards") {
			Catalog.drawPage("none");
		}
		User.updateBalanceDisplay();

	},
	refreshAccount: function (oUser) {
		if (oUser) { User.oData = $.extend(true, {}, oUser); }

		User.ProviderAccountID = User.oData.CUSTOMER_ID;
		$.cookie('tr_account_id', User.ProviderAccountID, { expires: 30, domain: 'tokenrewards.com' });

		User.ProviderName = User.oData.PROVIDER_NAME;
		var cFirst = User.oData.NAME.parseName(User.oData.NICK_NAME).nick;
		User.nickName = cFirst;

		Application.oUser.TOKENUNIT = User.oData.TOKENUNIT;
		Application.oUser.TOKENRATE = User.oData.TOKENRATE;
		Application.oUser.CODE = User.oData.CUSTOMER_CODE;
		Application.oUser.NAME = User.oData.NAME + " (" + User.oData.CODE.toUpperCase() + ")";

		Account.refresh.all();
	},

	initialized:false,
	init: function (aTables) {
		ui.closeWait();
		User.oData = $.extend(true, {}, aTables[0][0]);
		Application.oUser = $.extend(true, {}, aTables[0][0]);

		User.bLoggedIn = true;
		User.bShowPrices = true;

		$.cookie("session_account", Login.cCode);
		$.cookie("login_key", User.key);

		User.aLedger = $.extend(true, [], aTables[2]);
		User.aContacts = $.extend(true, [], aTables[3]);
		User.aAwards = $.extend(true, [], aTables[4]);
		User.aShipSchedule = $.extend(true, [], aTables[5]);

		Catalog.productsFetched(aTables[1], function () {
			User.refreshAccount(aTables[0][0]);
			User.updateBalanceDisplay();
			LogEntry("Participant logged in.");
		});


		Awards.refresh();

		SetRewardUnitElements();
		$("#CodeEntry, #tipCodeEntry").remove();

		//NewsTicker.aNewsItems[0] = { cNews: '', funAction: function () { } }

		$("#Navigator, #selPageFilter").addClass("showPrices");


		$("#btnAwards").button({ disabled: false });
		$("#btnAccount").button({ disabled: false });

		if (!User.initialized) {
			$("#btnsHashes input").change(function () {
				if ($(this).attr("id") == "btnOrders") $("#accountTabs").tabs("select", 2);
				window.location.hash = $(this).val();
			});
			$(window).unbind("hashchange").hashchange(function () { Application.hashChanged(); });
			User.initialized = true;
		}
		$("#btnDepoCert").button({ disabled: false })
		$("#btnLogOut").button({ disabled: false }).click(function () {
			$.cookie("session_account", null);
			$.cookie("login_key", null);
			$(window).unbind("hashchange");
			window.location.hash = '#Rewards';
			window.location.reload();
		});

		$(".providerName").text(User.ProviderName);
		if ($("#NewsTicker .providerInfo").length == 0) {
			$("#NewsTicker").append(
				'<div class="tickerItem providerInfo">' +
					'<span class="providerLabel">Your rewards are provided by:</span>' +
					'<span class="providerName">' + User.ProviderName + '</span>' +
				'</div>'
			);
			NewsTicker.begin();
		}
	}
};

var Awards = {
	initialized: false,
	init: function () {
		$("#btnsAwardOptions").buttonset();
		$("#btnsAwardOptions input").change(function () {
			LogEntry("Toggle Award View");
			if ($("#btnsAwardOptions input[value='got']").is(":checked")) {
				$("#Awards .awardObject:not(.awarded)").addClass("notAwarded");
				$("#Awards .awardObject").removeClass("completed partyCompleted expired");
			}
			else $("#Awards .awardObject").removeClass("notAwarded").each(function () {
				if ($(this).attr("group_qty_available").toNumber() <= 0) $(this).addClass("completed");
				if ($(this).attr("party_qty_available").toNumber() <= 0) $(this).addClass("partyCompleted");
				if ((new Date()).getTime() > $(this).attr("expires").toNumber()) $(this).addClass("expired");
			});
		});

		$("#btnsAwardDetails").buttonset();
		$("#btnsAwardDetails input").change(function () {
			if ($("#btnsAwardDetails input[value='hide']").is(":checked")) {
				$("#Awards .awardObject").addClass("hideDescription");
			}
			else $("#Awards .awardObject").removeClass("hideDescription");
		});


		Awards.resize();
		Awards.initialized = true;
	},
	show: function () {
		if (!Awards.initialized) Awards.init();

		$("#Awards").addClass("invisible").css({ "height": "auto", "bottom": "0" })
		.position({ my: "center bottom", at: "center top", of: $('body'), collision: "none" })
		.removeClass("invisible").show()
		.position({ my: "center top", at: "center bottom", of: $("#MenuBar"), offset: "0 -30", collision: "none",
			using: function (to) { $(this).animate(to, 1500, "", function () { Awards.resize(); }); }
		});

	},
	hide: function (callback) {
		$("#Awards").css({ "height": "auto", "bottom": "auto" })
		.position({ my: "center bottom", at: "center top", of: $('body'), offset: "0 0", collision: "none",
			using: function (to) {
				$(this).animate(to, 1000, "", function () { $("#Awards").hide(); if (callback) callback(); });
			}
		});
	},
	refresh: function () {
		var nAwardCnt = 0;
		for (var nX = 0; nX < User.aAwards.length; nX++) {
			var jAward = $(commonHTML.award);
			var oRec = User.aAwards[nX];

			if (oRec.AWARD_TYPE != "0" || oRec.HIDDEN_FROM_PARTIES) continue;
			nAwardCnt++;
			var cExpires = (oRec.EXPIRES) ? (new Date(oRec.EXPIRES)).getTime() : "Infinity".toNumber();
			var cAvailable = (oRec.GROUP_QTY_AVAILABLE) ? oRec.GROUP_QTY_AVAILABLE : "Infinity".toNumber();
			var cPartyAvailable = (oRec.PARTY_QTY_AVAILABLE) ? oRec.PARTY_QTY_AVAILABLE : "Infinity".toNumber();

			var cObjClasses = 'participantView';
			cObjClasses += ((new Date()).getTime() > cExpires) ? " expired" : "";
			cObjClasses += (cAvailable <= 0) ? " completed" : "";
			cObjClasses += (cPartyAvailable <= 0) ? " partyCompleted" : "";
			cObjClasses += (oRec.PARTY_QTY_AWARDED > 0) ? " awarded" : "";

			jAward.attr({
				"group_qty_available": cAvailable,
				"party_qty_available": cPartyAvailable,
				"award_id": oRec.ID,
				"expires": cExpires
			}).addClass(cObjClasses)
			.find(".title").html(oRec.TITLE).end()
			.find(".awardUnitName").html(Application.oUser.TOKENUNIT.toPlural(oRec.AMOUNT).toUpperCase()).end()
			.find(".description").html(oRec.DESCRIPTION).end()
			.find(".details .deadline .detailValue").html((oRec.EXPIRES) ? (new Date(oRec.EXPIRES)).format("smallDate") : "None").end()
			.find(".details .awarded .detailValue").html(oRec.PARTY_QTY_AWARDED + ((oRec.PARTY_QTY) ? '&nbsp;of&nbsp;' + oRec.PARTY_QTY : ''));

			commonHTML.drawCertAmount(jAward, oRec.AMOUNT);

			jAward.appendTo("#AwardObjects");
		}

		if (nAwardCnt > 0) $("#divNoAwards").remove();

	},
	resize: function () {
		return;
		$("#Awards").css({ height: $(window).height() - 121 + "px" });
	}
};

var Account = {
	initialized: false,
	init: function () {
		$("#accountTabs").tabs({ select: function (event, ui) { LogEntry(ui.tab.text + " tab selected."); } });

		$("#btnChangePassword").button({ icons: { primary: "ui-icon-pencil"} })
			.click(function () { Account.password.open(); });

		$("#btnEditInfo").button({ icons: { primary: "ui-icon-pencil"} })
			.click(function () { Account.edit.open(); });

		$("#btnEditEmail").button({ icons: { primary: "ui-icon-pencil"} })
			.click(function () { Account.email.open(); });
		$("#tabAccountInfo #btnSendEmail").button({ icons: { primary: "ui-icon-mail-closed"} })
			.click(function () {
				Account.sendPasswordReset();
			});

		$("#btnAddContact").button({ label: "Add Account Contact...", icons: { primary: "ui-icon-plusthick"} })
			.click(function () { AccountContact.openDialog(false, -1); });

		$("#txtDepositCode").keyup(function (event) {
			$(".badDepositCode").hide();
			var cCode = $("#txtDepositCode").val().trim().toLowerCase();
			var jBtn = $("#btnDepositCode");

			if (cCode.validDepositCode()) jBtn.button({ disabled: false });
			else { jBtn.button({ disabled: true }); }

			if (event.keyCode == 13 && cCode.length >= 6) jBtn.click();
		});
		$("#btnDepositCode").button({ label: "Okay", disabled: true, icons: { primary: "ui-icon-check"} })
			.click(function () { Account.depositCertificate.initDeposit(); });


		$("#btnCancelOrders").button().hide().click(function () { Account.cancelOrders(); });
		var cSoundText = function () {
			return;
			var cText;
			if (!$.sound.enabled) cText = "Play Sounds";
			else cText = "Quiet Please!";
			return cText;
		}
		$("#tabAccountInfo #chkSounds").button().change(function () {
			return;
			//$.sound.enabled = $(this).attr("checked");
			if ($.sound.enabled) {
				$.cookie("SoundsEnabled", "true");
				$(this).button("option", "label", "Turn Sounds Off");
				//$("#tabAccountInfo label[for='chkSounds']").text("Turn Sounds Off");
			}
			else {
				$.cookie("SoundsEnabled", "false");
				$(this).button("option", "label", "Turn Sounds On");
			}
		}).change();


		//		$("#btnBackFromAccount").button({ icons: { primary: "ui-icon-triangle-1-w"} })
		//		.click(function () {
		//			if (window.history.length > 1) window.history.back();
		//			else window.location.hash = "#Rewards";
		//		});

		Account.initialized = true;
	},
	show: function () {
		if (!Account.initialized) Account.init();
		Account.refresh.all();
		$("#Account").fadeIn();
		return;
		//$("#MenuBar").slideUp('slow');
		$("#Account").addClass("invisible").show()
		.position({ my: "center bottom", at: "center top", of: $('#MenuBar'), collision: "none" })
		.removeClass("invisible")
		.position({ my: "center top", at: "center top", of: $('#MenuBar'), offset: "0 45", collision: "none",
			using: function (to) {
				$(this).animate(to, 1000, "", function () {
					if ($("#accountTabs").tabs("option", "selected") == 1) $("#txtDepositCode").focus();
				});
			}
		});
	},
	hide: function (callback) {
		$("#Account").hide();
		if (callback) callback();
		return;
		$("#Account")
		.position({ my: "center bottom", at: "center top", of: $('#MenuBar'), collision: "none",
			using: function (to) {
				$(this).animate(to, 1000, "",
				function () {
					$("#Account").hide();
					if (callback) callback();
				});
			}
		});
	},
	refresh: {
		myInfo: function () {
			var jTab = $("#tabAccountInfo");

			$("#accountCode", jTab).text(User.oData.CODE.toUpperCase());
			$("#accountCreated", jTab).text(new Date(User.oData.CREATED_ON).format("shortDateTime"));

			if (User.oData.PASSWORD != User.oData.CODE) {
				$("#passwordProtected").text("Yes").css({ color: "#00BB00", "font-weight": "bold" });
				$("#btnChangePassword").button({ label: "Change Password..." });
			}
			else {
				$("#passwordProtected").text("No").css({ color: "#FF0000", "font-weight": "bold" });
				$("#btnChangePassword").button({ label: "Create Password..." });
			}

			jTab.find(".providerName").text(User.ProviderName);
			if (User.oData.CLASS_NAME)
				$("#className", jTab).text(User.oData.CLASS_NAME).show().prev().show();
			else $("#className", jTab).hide().prev().hide();


			$(".UserName").text(User.oData.NAME);
			$(".UserNick").text(User.nickName);
			$(".UserGender", jTab).text(Gender(User.oData.GENDER));
			$(".UserAge", jTab).text(Age(User.oData.BIRTHYEAR));

			$("#EmailVerified, #EmailNotVerified").hide();
			if (User.oData.EMAIL) {
				if (User.oData.EMAIL_VERIFIED) {
					$("#btnEditEmail").button({ label: "Change E-Mail Address..." });
					$("#EmailVerified").show();
				}
				else {
					$("#btnEditEmail").button({ label: "Confirm E-Mail Address..." });
					$("#EmailNotVerified").show();
				}

				$("#UserEmail", jTab).text(User.oData.EMAIL);
			}
			else {
				$("#btnEditEmail").button({ label: "Enter E-Mail Address..." });
				$("#UserEmail", jTab).text("(E-Mail Address Missing)");
			}

		},
		currentOrders: function () {
			var jOrders = $("#tabOrders tbody").empty();
			var aPending = $.grep(Catalog.aMasterProducts, function (oProduct, nIndex) {
				return (oProduct.QTY_ON_ORDER.toNumber() > 0 && oProduct.QTY_SHIPPED.toNumber() == 0)
			});

			for (var nX = 0; nX < aPending.length; nX++) {
				//	<th>Item Name</th><th>Each</th><th>Qty</th><th>Total</th><th>Cancel</th>
				jOrders.append(
					'<tr>' +
						'<td>' + aPending[nX].TITLE_PLAIN + '</td>' +
						'<td style="text-align:right">' + aPending[nX].TOKENS_EACH + '</td>' +
						'<td style="text-align:center">' + aPending[nX].QTY_ON_ORDER + '</td>' +
						'<td style="text-align:right">' + Number(aPending[nX].TOKENS_EACH) * Number(aPending[nX].QTY_ON_ORDER) + '</td>' +
						'<td style="text-align:center">' +
				// No canceling orders on invoices or custom_rewards
							((aPending[nX].QTY_ON_INVOICE.toNumber() > 0 || aPending[nX].CUSTOM_REWARD) ? 'On the way!' :
							'<input type="checkbox" productid="' + aPending[nX].ID + '" rowtotal="' +
							Number(aPending[nX].TOKENS_EACH) * Number(aPending[nX].QTY_ON_ORDER) + '"/>') +
						'</td>' +
					'</tr>');
			}
			jOrders.find("input:checkbox").change(function () {
				var jChecked = jOrders.find("input:checkbox:checked");
				if (jChecked.length > 0) {
					var nSum = 0;
					jChecked.each(function () {
						nSum += Number($(this).attr("rowtotal"));
					});

					$("#postCancelBalance").text("Available after: " + String(Number(User.oData.BALANCE) + nSum));
					$("#btnCancelOrders").fadeIn();

				}
				else $("#btnCancelOrders").fadeOut();
			});
		},
		history: function () {
			var nDeposits = 0, nDepositCnt = 0, nWithdraws = 0, nWithdrawCnt = 0, nAmount = 0;
			var jHistory = $("#tblHistory tbody").empty();
			for (var nX = 0; nX < User.aLedger.length; nX++) {
				nAmount = Number(User.aLedger[nX].AMOUNT);
				nDeposits += (nAmount > 0) ? nAmount : 0;
				nWithdraws += (nAmount < 0) ? nAmount : 0;
				nDepositCnt += (nAmount > 0) ? 1 : 0;
				nWithdrawCnt += (nAmount < 0) ? 1 : 0;
				//				<th>Date</th><th>Description</th><th>Amount</th>
				var cDate = new Date(User.aLedger[nX].ADDED).format("shortDateTime");
				jHistory.append('<tr><td>' + cDate + '</td>' +
												'<td style="width:50%;">' +
													'<div style="width:100%; height:1.3em; overflow:hidden" title="' + User.aLedger[nX].DESCRIPTION + '">' +
														User.aLedger[nX].DESCRIPTION +
													'</div>' +
												'</td>' +
												'<td style="text-align:right">' + nAmount + '</td>' +
										'</tr>');
			}
			$("#tabHistory .historySummary")
				.find(".depositsLabel").text("Total Deposits (" + nDepositCnt + "):").end()
				.find(".deposits").text(nDeposits).end()
				.find(".withdrawsLabel").text("Minus Withdrawals (" + nWithdrawCnt + "):").end()
				.find(".withdrawals").text(Math.abs(nWithdraws)).end()
				.find(".pendingsLabel").text("Minus Current Orders (" + User.oData.PENDING_ORDERS + "):").end()
				.find(".pendings").text(User.oData.PENDING_TOKENS).end()
				.find(".historyBalance").text(User.oData.BALANCE + " " + User.oData.TOKENUNIT.toPlural(User.oData.BALANCE));
		},
		contacts: function () {
			var jBtn = $("#btnAddContact");
			var jTbody = $("#tblContacts tbody").empty();
			for (var nX = 0; nX < User.aContacts.length; nX++) {
				if (User.aContacts[nX].DEACTIVATED) continue;
				jTbody.append(
					'<tr contact_id="' + User.aContacts[nX].CONTACT_ID + '" email_verified="' + User.aContacts[nX].EMAIL_VERIFIED + '">' +
						'<td>' + User.aContacts[nX].NAME + '</td>' +
						'<td>' + User.aContacts[nX].RELATIONSHIP + '</td>' +
						'<td>' + User.aContacts[nX].EMAIL + '</td>' +
						'<td style="height:22px; text-align:center;">' +
							'<span class="btnEditContact" title="Edit this contact..."></span>' +
							'<span class="btnClearContact" title="Remove this contact..." ></span>' +
						'</td>' +
					'</tr>'
					);
			}
			jTbody.find("span.btnEditContact").css("height", "22px").button({ text: false, icons: { primary: 'ui-icon-pencil'} })
				.removeClass("ui-state-hover")
				.click(function () {
					AccountContact.openDialog(false, $(this).parent().parent().attr("contact_id"));
				});

			jTbody.find("span.btnClearContact").css("height", "22px").button({ text: false, icons: { primary: 'ui-icon-trash'} })
				.click(function () { Account.deactivateContact(this); });

			switch (jTbody.find("tr").length) {
				case 0: jBtn.css("top", "65px"); break;
				case 1: jBtn.css("top", "92px"); break;
				default: jBtn.css("top", "-4px"); break;
			}



		},
		shipSchedule: function () {
			var data = User.aShipSchedule;

			$("#divNextShipment").hide();
			$("#divOrderShipmentDeadline").hide();
			if (data.length == 0) {
				$("#divOrderShipment .shipdate").text("Ask Administrator");
				return;
			}

			var dX = new Date(data[0].ADJ_LANDING_DATE);

			if (data[0].ORDER_DEADLINE_AGE.toNumber() > 0) {
				$("#divNextShipment .shipdate").text(dX.format("dddd, mmm d, yyyy") + ", " + data[0].ADJ_LANDING_DATE_AGE.toDaysLeft());
				$("#divNextShipment").show();
			}

			for (var nX = 0; nX < data.length; nX++) {
				if (data[nX].ORDER_DEADLINE_AGE.toNumber() <= 0) {
					var dX = new Date(data[nX].ADJ_LANDING_DATE);
					$("#divOrderShipment .shipdate").text(dX.format("dddd, mmm d, yyyy") + ", " + data[nX].ADJ_LANDING_DATE_AGE.toDaysLeft());
					$("#divOrderShipmentDeadline .shipdate").text(dX.format("m/d"));

					var dX = new Date(data[nX].ORDER_DEADLINE);
					$("#divOrderShipmentDeadline .orderdate").text(dX.format("dddd, mmm d") + ", " + data[nX].ORDER_DEADLINE_AGE.toDaysLeft());
					$("#divOrderShipmentDeadline").show();

					$("#NewsTicker").append(
						'<div class="tickerItem orderDeadline">' +
							'<span>Order by ' + dX.format("m/d") + ", that's " + data[nX].ORDER_DEADLINE_AGE.toDaysLeft() + '!</span>' +
						'</div>'
					);
					break;
				}
			}

		},
		all: function () {
			if (!Account.initialized) Account.init();
			Account.refresh.history();
			Account.refresh.currentOrders();
			Account.refresh.contacts();
			Account.refresh.shipSchedule();
			Account.refresh.myInfo();
		}
	},
	cancelOrders: function () {
		ui.openWait("Canceling orders...");
		var cSQL = "";
		var jCanceled = $("#tabOrders tbody input:checkbox:checked");
		jCanceled.each(function () {
			cSQL += DataHandler.closeWish($(this).attr("productid"));
			LogEntry("Order canceled for Product #" + $(this).attr("productid"));
		});

		cSQL += DataHandler.account + DataHandler.userProducts;
		DataHandler.execute(cSQL, function (aTables) {
			ui.closeWait();
			var bError = false;
			for (var nX = 0; nX < jCanceled.length; nX++) {
				if (aTables[nX][0].ERR$NAME > '') {
					bError = true;
				}
			}

			if (bError) {
				ui.modalMessage({
					message: "Sory, we had a problem canceling the order:<br /><br />" + aTables[0][0].ERR$MESSAGE,
					title: "Problem Canceling Order"
				});
			}

			User.postOrderRefresh(aTables[jCanceled.length][0], aTables[jCanceled.length + 1]);
			$("#btnCancelOrders").hide();
		});
	},
	deactivateContact: function (btn) {
		var jRow = $(btn).parent().parent();
		var oConfirm = {
			title: "Remove Account Contact?",
			message: "Are sure you want to remove " + jRow.find("td").eq(0).text() + " from your list of account contacts?",
			action: function () {
				LogEntry("Account contact deactivated.");
				$("#elapContactsTable").show();
				$("#btnAddContact").hide();
				var jRow = $(btn).parent().parent();
				jRow.addClass("hidden");
				var oContact = {
					contact_id: jRow.attr("contact_id"),
					name: jRow.find("td").eq(0).text(),
					relation: jRow.find("td").eq(1).text(),
					email: jRow.find("td").eq(2).text()
				}
				LogEntry("Account contact (" + oContact.name + ") deactivated.");

				var cSQL = "select * from shop$contact_update(" +
						User.key.prepSQL() + "," +
						oContact.contact_id.prepSQL() + "," +
						oContact.name.prepSQL() + "," +
						oContact.relation.prepSQL() + "," +
						oContact.email.prepSQL() + "," +
						"'Participant');";
				cSQL += DataHandler.contacts;
				var query = execQuery(cSQL, function (data) {
					User.aContacts = data[1];
					Account.refresh.contacts();
					$("#elapContactsTable").hide();
					$("#btnAddContact").show();
				});
			}
		}
		ui.modalConfirm(oConfirm);
	},
	depositCertificate: {
		oCertificate: {},
		cInputCode: '',
		initDeposit: function () {
			$("#btnDepositCode").addClass("invisible");
			$("#elapCodeFetch span").text(" Fetching Code...")
			$("#elapCodeFetch").show();
			var cCode = $("#txtDepositCode").val().replace(" ", "").trim().toLowerCase();
			this.oCertificate = {};
			this.cInputCode = cCode;
			var query = new execQuery("SELECT * FROM shop$certificate(" + cCode.prepSQL() + "," + User.oData.CODE.prepSQL() + ");",
				function (data) {
					Account.depositCertificate.oCertificate = $.extend({}, data[0]);
					if (Account.depositCertificate.valid()) Account.depositCertificate.certificateDeposited();
					else {
						$("#btnDepositCode").removeClass("invisible").button({ disabled: true });
						$("#elapCodeFetch").hide();
						$("#txtDepositCode").focus();
					}
				});
		},
		valid: function () {
			var cert = Account.depositCertificate.oCertificate;
			if (cert.AMOUNT_DEPOSITED) { return true; }

			var cCode = Account.depositCertificate.cInputCode;
			if (!cert.CERT_CODE) {
				$("#badCode").slideDown(400);
				LogEntry("Certificate Deposit Failed - code not found. " + cCode);
				return false;
			}
			if (cert.USED.toNumber() > 0) {
				$("#usedCode").slideDown(400);
				LogEntry("Certificate Deposit Failed - code used. " + cCode);
				return false;
			}
			if (cert.AWARD_DELETED || (cert.GROUP_QTY_AVAILABLE && cert.GROUP_QTY_AVAILABLE.toNumber() <= 0)) {
				$("#awardExhausted").slideDown(400);
				LogEntry("Certificate Deposit Failed - group qty exhuasted or award deleted. " + cCode);
				return false;
			}
			if (cert.PARTY_QTY_AVAILABLE && cert.PARTY_QTY_AVAILABLE.toNumber() <= 0) {
				$("#awardPartyExhausted").slideDown(400);
				LogEntry("Certificate Deposit Failed - party qty exhuasted or deleted. " + cCode);
				return false;
			}
			if (cert.PARTY_NOT_ELIGIBLE) {
				$("#awardPartyNotEligible").slideDown(400);
				LogEntry("Certificate Deposit Failed - party not eligible. " + cCode);
				return false;
			}
			return false;
		},
		certificateDeposited: function (aTables) {
			$("#elapCodeFetch span").text(" Making Deposit...");
			if (User.aContacts.length > 0)
				LogEntry("Certificate deposited, notifications delivered. " + Account.depositCertificate.oCertificate.CERT_CODE);
			else
				LogEntry("Certificate deposited, no notifications. " + Account.depositCertificate.oCertificate.CERT_CODE);

			var sendContactNotifications = function () {
				var cert = Account.depositCertificate.oCertificate;

				//if (!cert.AWARD_TITLE) cert.AWARD_TITLE = "Certificate Award";
				var cAwardTitle = cert.AWARD_TITLE;
				var cAwardTitle_Plain = cert.AWARD_TITLE;
				var cAwardAmount = cert.AMOUNT;
				var cAwardTokens = cAwardAmount + " " + User.oData.TOKENUNIT.toPlural(cAwardAmount);

				var oPartyName = User.oData.NAME.parseName(User.oData.NICK_NAME);
				var pronoun = genderPronouns(User.oData.GENDER);


				for (var nX = 0; nX < User.aContacts.length; nX++) {
					var oContact = User.aContacts[nX];
					if (oContact.DEACTIVATED || !oContact.EMAIL_VERIFIED) continue;
					var oContactName = oContact.NAME.parseName();

					var cContents = Email.contentTemplates.admin_contact_award
						.replace(/__contact_first_name__/g, oContactName.first)
						.replace(/__provider_name__/g, User.ProviderName)
						.replace(/__party_full_name__/g, oPartyName.asEntered)
						.replace(/__party_nick_name__/g, oPartyName.nick)

						.replace(/__award_amount_tokens__/g, cAwardTokens)
						.replace(/__award_title__/g, cAwardTitle)

						.replace(/__Nominative__/g, pronoun.nominative.toProperCase(true))
						.replace(/__nominative__/g, pronoun.nominative)
						.replace(/__objective__/g, pronoun.objective)
						.replace(/__Objective__/g, pronoun.objective.toProperCase(true))
						.replace(/__adjective__/g, pronoun.adjective)
						.replace(/__Adjective__/g, pronoun.adjective.toProperCase(true))
						;
					Email.send({
						to_contact_id: oContact.CONTACT_ID,
						to_name: oContactName.asEntered,
						to_address: oContact.EMAIL,
						subject: User.ProviderName + " awarded " + oPartyName.asEntered + "! " + cAwardTitle_Plain,
						template: 'admin_contact_award',
						contents: cContents,
						callback: function (bSuccess, cSentTo, oSendData) { }
					});
				}
			} ();


			DataHandler.execute(DataHandler.account + DataHandler.ledger + DataHandler.awards,
				function (aTables) {
					$("#elapCodeFetch").hide();
					$("#btnDepositCode").removeClass("invisible").button({ disabled: true });
					var oCertificate = Account.depositCertificate.oCertificate;
					var cAwarded = oCertificate.AMOUNT + " " + oCertificate.TOKENUNIT.toLowerCase().toPlural(oCertificate.AMOUNT);
					var nNewBalance = Number(User.oData.BALANCE) + Number(oCertificate.AMOUNT)
					var cBalance = nNewBalance + " " + oCertificate.TOKENUNIT.toLowerCase().toPlural(nNewBalance);
					$("#divDepositMade")
					.find(".UserName").text(User.nickName).end()
					.find(".RewardCodeValue").text(oCertificate.AMOUNT).end()
					.find(".awarded.awardUnits").text(cAwarded).end()
					.find(".userBalance.awardUnits").text(cBalance).end()
					.show();

					User.aLedger = $.extend(true, [], aTables[1]);
					User.aAwards = $.extend(true, [], aTables[2]);
					User.refreshAccount(aTables[0][0]);
					Awards.refresh();
					$("#txtDepositCode").val('').focus();
					User.updateBalanceDisplay(function () { $("#divDepositMade").fadeOut(); });
				});
		}
	},

	edit: {
		initialized: false,

		init: function () {
			if (Account.edit.initialized) return;

			$("#wrapExtraNames input").focusout(function () {
				Account.edit.setExtraNames(this, true);
			});
			$('select', "#diagEditParticipant").change(function () { Account.edit.validate(); });
			$('input[type="text"], textarea, select', "#diagEditParticipant").keyup(function () {
				var sId = $(this).attr("id");
				if (/Name/.test(sId)) { Account.edit.setExtraNames(this, false); }

				Account.edit.validate();
			});

			var jSel = $("#selPartyBirthYear");
			var nCurYear = Number(new Date().getFullYear()) - 3;
			for (var nX = nCurYear; nX >= 1950; nX--) {
				jSel.append('<option>' + nX + '</option>');
			}
			Account.edit.initialized = true;

		},
		refresh: function () {

			var oData = User.oData;
			$("#diagEditParticipant #txtPartyName").val(oData.NAME);
			var oNames = oData.NAME.parseName();

			var jNickName = $("#diagEditParticipant #txtNickName");
			jNickName.val(oData.NICK_NAME).addClass((oData.NICK_NAME != oNames.nick) ? "edited" : "");


			$("#diagEditParticipant #selPartyGender").val(oData.GENDER);
			$("#diagEditParticipant #selPartyBirthYear").val(oData.BIRTHYEAR);

		},
		updatedValues: function () {
			this.NAME = $("#diagEditParticipant #txtPartyName").val().trim();
			this.NICK_NAME = $("#diagEditParticipant #txtNickName").val().trim();

			this.GENDER = $("#diagEditParticipant #selPartyGender").val();
			this.BIRTHYEAR = $("#diagEditParticipant #selPartyBirthYear").val();
		},
		validate: function () {
			var oUpdated = new Account.edit.updatedValues();
			var oCurrent = User.oData;
			var bEdited = false;

			if ($("#selPartyBirthYear").val())
				$("#noteAgeYears").text("(" + Age($("#selPartyBirthYear").val()) + " years old)").show();
			else $("#noteAgeYears").hide();

			for (var sField in oUpdated) {
				if (oUpdated[sField] != oCurrent[sField]) {
					bEdited = true;
				}
			}

			$("#NoteRequiredField, .requiredAsterix", $("#diagEditParticipant").parent()).hide();
			var bReqsMet = true;

			if (!oUpdated.NAME) {
				$("#wrapPartyName .requiredAsterix").show();
				bReqsMet = false;
			}
			if (!bReqsMet) $("#NoteRequiredField, #NoteRequiredField .requiredAsterix").show();

			$("#btnSavePartyEdits").button({ disabled: !bEdited || !bReqsMet });

		},

		setExtraNames: function (elementEdited, bOnBlur) {
			var oNames = $("#diagEditParticipant #txtPartyName").val().parseName();
			var jEle = $(elementEdited);

			switch (elementEdited.id) {
				case "txtPartyName":
					if (!$("#txtSortName").hasClass("edited")) {
						$("#txtSortName").val(oNames.sort);
					}
					else if ($("#txtSortName").hasClass("edited") && $("#txtSortName").val().trim() == oNames.sort) {
						$("#txtSortName").removeClass("edited");
					}

					if (!$("#txtNickName").hasClass("edited")) {
						$("#txtNickName").val(oNames.nick);
					}
					else if ($("#txtNickName").hasClass("edited") && $("#txtNickName").val().trim() == oNames.nick) {
						$("#txtNickName").removeClass("edited");
					}

					break;
				case "txtSortName":
					if (bOnBlur && !jEle.val().trim()) jEle.val(oNames.sort);
					if (oNames.sort == jEle.val().trim()) jEle.removeClass("edited");
					else jEle.addClass("edited");
					break;
				case "txtNickName":
					if (bOnBlur && !jEle.val().trim()) jEle.val(oNames.nick);
					if (oNames.nick == jEle.val().trim()) jEle.removeClass("edited");
					else jEle.addClass("edited");
					break;
			}

		},

		open: function () {
			Account.edit.init();
			Account.edit.refresh();

			$("#diagEditParticipant").dialog({
				autoOpen: true,
				modal: true,
				width: 400,
				open: function (event, ui) {
					var jBtns = $(this).siblings(".ui-dialog-buttonpane").find("button");
					jBtns.eq(0).button({ disabled: true, icons: { primary: "ui-icon-check"} }).attr("id", "btnSavePartyEdits");
					jBtns.eq(1).button({ icons: { primary: "ui-icon-closethick"} });

					$(this).siblings(".ui-dialog-buttonpane").append(
						'<div id="NoteRequiredField">' +
							'<span class="requiredAsterix">*</span> You must enter your name to save your changes.' +
						'</div>'
					);
					Account.edit.validate();
				},
				close: function (event, ui) { $(this).dialog('destroy'); },
				buttons: {
					'Save': function () {
						LogEntry("Edits saved.");
						Account.edit.save();
						$(this).dialog('close');
					},
					'Cancel': function () {
						LogEntry("Edits canceled.");
						$(this).dialog('close');
					}
				}
			});

			LogEntry("Edit My Info clicked.");
		},
		save: function () {
			ui.elap.on("Saving");
			var updated = new Account.edit.updatedValues();

			var SQL = "execute procedure SHOP$PARTICIPANT_UPDATE(";
			SQL += User.key.prepSQL() + ", " +
				updated.NAME.prepSQL() + ", " +
				updated.NICK_NAME.prepSQL() + ", " +
				User.oData.EMAIL.prepSQL(true) + ", " +
				updated.GENDER.prepSQL(true) + ", " +
				updated.BIRTHYEAR.prepSQL(true) + ", " +
				User.oData.PASSWORD.prepSQL() + ");";

			SQL += DataHandler.account;
			DataHandler.execute(SQL, function (aTables) {
				User.refreshAccount(aTables[1][0]);
				ui.elap.off();
			});
		}

	},

	email: {
		initialized: false,
		init: function () {
			if (Account.email.initialized) return;
			$("#btnSendConfirm").button({ icons: { primary: "ui-icon-mail-closed" }, disabled: true })
				.click(function () { Account.email.sendConfirm(); });
			$("#txtPartyEmail").keyup(function () { Account.email.validate() });
			$("#txtConfirmCode").keyup(function () { Account.email.validate() });

			$("#btnCheckConfirmCode").button({ icons: { primary: "ui-icon-triangle-1-w" }, disabled: true })
			.click(function () { Account.email.checkConfirmCode(); });

			Account.email.initialized = true;
		},
		refresh: function () {
			if (User.oData.EMAIL_VERIFIED) {
				// changing email address 
				$("#txtPartyEmail").val("");
			}
			else if (User.oData.EMAIL) {
				$("#txtPartyEmail").val(User.oData.EMAIL);
			}
			else $("#txtPartyEmail").val("");

			$("#SendConfirmSuccess").hide();
			$("#btnSendConfirm").show();
			$("#txtConfirmCode").val('');

		},

		open: function () {
			Account.email.init();
			Account.email.refresh();

			$("#diagChangeEmail").dialog({
				autoOpen: true,
				modal: true,
				width: 550,
				open: function (event, ui) {
					var jBtns = $(this).siblings(".ui-dialog-buttonpane").find("button");
					jBtns.eq(0).button({ disabled: true, icons: { primary: "ui-icon-check"} }).attr("id", "btnSaveEmail");
					jBtns.eq(1).button({ icons: { primary: "ui-icon-closethick"} });
					$(".ui-button").bind("focusout", function () { $(this).removeClass("ui-state-focus"); });
				},
				close: function (event, ui) {
					$(this).dialog('destroy');
				},
				buttons: {
					'Save': function () { $(this).dialog('close'); Account.email.save(); },
					'Cancel': function () { $(this).dialog('close'); }
				}
			});

			Account.email.validate();

		},

		sendConfirm: function () {
			var sEmail = $("#txtPartyEmail").val();

			$("#btnSendConfirm, #wrapEmailValidation").hide();
			$("#elapSendConfirm").show();

			Email.send({
				to_name: User.oData.NAME,
				to_address: sEmail,
				to_contact_id: User.oData.CONTACT_ID,
				template: 'shop_email_confirm',
				contents: Email.contentTemplates.shop_email_confirm
					.replace(/__first_name__/g, User.nickName)
					.replace(/__token_name__/g, User.oData.TOKENUNIT.toLowerCase())
					.replace(/__provider_name__/g, User.oData.PROVIDER_NAME)
				,
				callback: function (bSuccess, sSentTo, oSend) {
					$("#elapSendConfirm").hide();
					$("#SendConfirmSuccess").show();
				}
			});

		},
		validate: function () {
			var sEmail = $("#txtPartyEmail").val();

			var bValidEmail = sEmail.isValidEmail();
			var bValidCode = $("#txtConfirmCode").val().length == 4;

			if (bValidCode) $("#btnCheckConfirmCode").button({ disabled: false });
			else $("#btnCheckConfirmCode").button({ disabled: true });

			if (bValidEmail) {
				$("#btnSendConfirm").button({ disabled: false });
				if (User.oData.EMAIL != sEmail)
					$("#btnSaveEmail").button({ disabled: false });
				else $("#btnSaveEmail").button({ disabled: true });
			}
			else {
				$("#btnCheckConfirmCode").button({ disabled: true });
				$("#btnSaveEmail").button({ disabled: true });
			}

			if (sEmail == '') {
				$("#wrapEmailValidation .valid").hide();
				$("#wrapEmailValidation .invalid").hide();
				$("#wrapEmailValidation .empty").show();
			}
			else if (!bValidEmail) {
				$("#wrapEmailValidation .empty").hide();
				$("#wrapEmailValidation .valid").hide();
				$("#wrapEmailValidation .invalid").show();
			}
			else {
				$("#wrapEmailValidation .empty").hide();
				$("#wrapEmailValidation .invalid").hide();
				$("#wrapEmailValidation .valid").show();
			}
		},
		saveEmailSQL: function () {
			var SQL = "select * from SHOP$PARTICIPANT_UPDATE(" +
				User.key.prepSQL() + ", " +
				User.oData.NAME.prepSQL() + ", " +
				User.oData.NICK_NAME.prepSQL() + ", " +
				$("#txtPartyEmail").val().prepSQL() + ", " +
				User.oData.GENDER.prepSQL(true) + ", " +
				User.oData.BIRTHYEAR.prepSQL(true) + ", " +
				User.oData.PASSWORD.prepSQL() + ");";

			return SQL;
		},
		checkConfirmCode: function () {
			ui.elap.on("Saving");
			var SQL = Account.email.saveEmailSQL() + "\n" +
					"select * from com$email_verify(" +
					$("#txtConfirmCode").val().prepSQL() + "," +
					$("#txtPartyEmail").val().prepSQL() + ");" +
					DataHandler.account;

			new execQuery(SQL, function (data) {
				ui.elap.off();

				if (data[1].length) {
					$("#diagChangeEmail").dialog("close");
					ui.modalMessage({
						title: "E-mail Address Confirmed",
						message: "Your new e-mail address is now saved and confirmed."
					});
				}
				else {
					ui.modalMessage({
						title: "Wrong Confirmation Code",
						message: "The confirmation code you entered does not appear to be correct. <br/><br/>" +
								"Please try again.",
						action: function () { $("#txtConfirmCode").val('').focus(); }
					});
					return;
				}
				User.refreshAccount(data[2][0]);

			});
		},
		save: function () {
			ui.elap.on("Saving");
			var SQL = Account.email.saveEmailSQL() + DataHandler.account;
			DataHandler.execute(SQL, function (aTables) {
				User.refreshAccount(aTables[1][0]);
				ui.elap.off();
			});
		}
	},

	password: {
		initialized: false,
		init: function () {
			if (Account.password.initialized) return;

			$("#diagChangePassword input").keyup(function () { Account.password.validate(); });
			$("#chkShowCurrentPassword").change(function () { $("#spanCurrentPassword").toggle(); });

			Account.password.initialized = true;
		},
		refresh: function () {
			$("#spanCurrentPassword").text(User.oData.PASSWORD)
			$("#Reset_Password1, #Reset_Password2").val('');

			$("#wrapCurrentPassword").toggle(User.oData.PASSWORD != User.oData.CODE);
		},
		validate: function () {
			var sPass1 = $("#Reset_Password1").val();
			var sPass2 = $("#Reset_Password2").val();

			$("#noEmpty").toggle(sPass1.length < 4);
			$("#noMatch").toggle(sPass1.length >= 4 && sPass1 != sPass2);

			$("#btnSavePassword").button({ disabled: (!sPass1 || sPass1 != sPass2) });
		},
		open: function () {
			if (!User.oData.EMAIL_VERIFIED) {
				ui.modalMessage({
					title: "Cannot Create Password",
					message: "Sorry, but you cannot password protect protect your account until you have a confirmed e-mail address."
				});
				return;
			}

			Account.password.init();
			Account.password.refresh();

			$("#diagChangePassword").dialog({
				autoOpen: true,
				modal: true,
				width: 350,
				open: function (event, ui) {
					var jBtns = $(this).siblings(".ui-dialog-buttonpane").find("button");
					jBtns.eq(0).button({ disabled: true, icons: { primary: "ui-icon-check"} }).attr("id", "btnSavePassword");
					jBtns.eq(1).button({ icons: { primary: "ui-icon-closethick"} });
					$("#Reset_Password1").focus();
				},
				close: function (event, ui) { $(this).dialog('destroy') },
				buttons: {
					'Save Password': function () { Account.password.save(); },
					'Cancel': function () { $(this).dialog('close'); }
				}

			});

		},
		save: function () {
			ui.elap.on("Saving");
			var SQL = "select * from SHOP$PARTICIPANT_UPDATE(" +
				User.key.prepSQL() + ", " +
				User.oData.NAME.prepSQL() + ", " +
				User.oData.NICK_NAME.prepSQL() + ", " +
				User.oData.EMAIL.prepSQL() + ", " +
				User.oData.GENDER.prepSQL(true) + ", " +
				User.oData.BIRTHYEAR.prepSQL(true) + ", " +
				$("#Reset_Password1").val().prepSQL() + ");";

			SQL += DataHandler.account;
			DataHandler.execute(SQL, function (aTables) {
				ui.elap.off();
				if (aTables[0][0].BAD_PASSWORD == "1") {
					ui.modalMessage({
						title: "Password Problem",
						message: "Please use a different password.  The one you have entered cannot be used for technical reasons."
					});
					$("#Reset_Password2").val('');
					$("#Reset_Password1").val('').focus();
					return;
				}

				User.refreshAccount(aTables[1][0]);
				$("#diagChangePassword").dialog('close');
				ui.modalMessage({ title: "Password Changed", message: "Your new password was saved successfully." });
				$("#diagChangePassword").dialog('close');
			});

		}
	}
	// yt487ad vkrnswg

};

var AccountContact = {
	bFromNewAccount: false,
	current: {
		contact_id: '',
		name: '',
		relation: '',
		email: '',
		email_verified: ''
	},
	initialized: false,
	aRelations: [
					"Mother", "Father (Dad)",
					"Grandmother", "Grandfather",
					"Sister", "Brother", "Cousin",
					"Aunt", "Uncle",
					"Tutor", "Teacher", "Doctor",
					"Mentor", "Friend", "Other"
					],
	init: function () {
		$("#ContactRelation").autocomplete({ minLength: 0, source: AccountContact.aRelations });
		$("#diagContact input").keyup(function () {
			AccountContact.validateInputs();
		});

		$("#labelContactName").dblclick(function (event) {
			var nX = $("#ContactName").val().toNumber();
			if (nX > 0 && nX < 4) {
				$("#ContactName").val("Test" + nX + " Contact" + nX);
				$("#ContactRelation").val("Contact" + nX + " Releationship");
				$("#ContactEmail").val("test" + nX + "@tokenrewards.com").keyup();
			}
		});
	},
	validateInputs: function () {
		var bAllValid = true;
		var updated = {
			name: $("#ContactName").val().trim(),
			relation: $("#ContactRelation").val().trim(),
			email: $("#ContactEmail").val().trim()
		};

		if (updated.name.length < 1) { bAllValid = false; $("#ContactName").next().find("span").show(); }
		else $("#ContactName").next().find("span").fadeOut();

		if (updated.relation.length < 1) { bAllValid = false; $("#ContactRelation").next().find("span").show(); }
		else $("#ContactRelation").next().find("span").fadeOut();

		if (!updated.email.validEmail()) { bAllValid = false; $("#ContactEmail").next().find("span").show(); }
		else $("#ContactEmail").next().find("span").fadeOut();

		$("#noticeDeactivated").hide();
		//Verify updated.email does not exist in deactivated contacts
		for (var nX = 0; nX < User.aContacts.length; nX++) {
			if (User.aContacts[nX].EMAIL == updated.email && User.aContacts[nX].DEACTIVATED && User.aContacts[nX].DEACTIVATED_BY != "Participant") {
				bAllValid = false;
				$("#noticeDeactivated").show();
				$("#noticeDeactivated span").text(User.aContacts[nX].NAME);
			}
		}
		var current = AccountContact.current;
		if (updated.name == current.name && updated.relation == current.relation && updated.email == current.email) bAllValid = false;

		var jBtn = $("#diagContact").siblings('.ui-dialog-buttonpane').find('button').eq(0).button({ disabled: !bAllValid });
	},
	save: function () {
		var saveForNewAccount = function () {
			var jTbody = $("#divContacts table tbody");

			if (AccountContact.current.contact_id == -1) {
				var nNewId = 0;
				var jRows = jTbody.find("tr");
				for (var nX = 0; nX < jRows.length; nX++) {
					var nTempId = Number(jRows.eq(nX).attr("contact_id"));
					if (nTempId > nNewId) { nNewId = nTempId; }
				}
				nNewId++;

				jTbody.append(
				'<tr contact_id="' + nNewId + '">' +
					'<td>' + $("#ContactName").val().trim() + '</td>' +
					'<td>' + $("#ContactRelation").val().trim() + '</td>' +
					'<td>' + $("#ContactEmail").val().trim() + '</td>' +
					'<td style="height:22px; text-align:center;">' +
						'<span class="btnEditContact" title="Edit this person..."></span>' +
						'<span class="btnClearContact" title="Remove this person..." ></span>' +
					'</td>' +
				'</tr>'
			);
			}
			else {
				var jCells = jTbody.find("tr[contact_id=" + AccountContact.current.contact_id + "]").find("td");
				jCells.eq(0).text($("#ContactName").val().trim());
				jCells.eq(1).text($("#ContactRelation").val().trim());
				jCells.eq(2).text($("#ContactEmail").val().trim());
			}

			jTbody.find("span.btnEditContact").css("height", "22px").button({ text: false, icons: { primary: 'ui-icon-pencil'} })
			.removeClass("ui-state-hover")
			.click(function () {
				AccountContact.openDialog(true, $(this).parent().parent().attr("contact_id"));
			});

			jTbody.find("span.btnClearContact").css("height", "22px").button({ text: false, icons: { primary: 'ui-icon-trash'} })
			.removeClass("ui-state-hover")
			.click(function () {
				$(this).parent().parent().remove();
				if ($("#divContacts table tbody tr").length == 0) {
					$("#divContacts table").hide();
					$("#divMoreContacts").hide();
					$("#divAnyContacts").show();
					$("#chkNoContacts,#chkNoMoreContacts").attr("checked", false);
					$("label[for=chkNoContacts],label[for=chkNoMoreContacts]").removeClass("ui-state-active");
					$("#divContacts").next().slideDown();
					NewAccount.valid.all();
				}
			});

			jTbody.parent().show();

			$("#divAnyContacts").hide();
			$("#divMoreContacts").show();

			$("#divContacts").next().hide();
			$("#btnNewContact2").button({ disabled: false }).removeClass("ui-state-hover");
		};
		if (AccountContact.bFromNewAccount) { saveForNewAccount(); return; }

		$("#elapContactsTable").show();
		$("#btnAddContact").hide();
		var updated = {
			name: $("#ContactName").val().trim(),
			relation: $("#ContactRelation").val().trim(),
			email: $("#ContactEmail").val().trim()
		};

		if (AccountContact.current.contact_id == -1) {
			cSQL = "select * from shop$contact_insert(" +
				User.key.prepSQL() + "," +
				updated.name.prepSQL() + "," +
				updated.relation.prepSQL() + "," +
				updated.email.prepSQL() + ");";
		}
		else {
			cSQL = "select * from shop$contact_update(" +
				User.key.prepSQL() + "," +
				AccountContact.current.contact_id.prepSQL() + "," +
				updated.name.prepSQL() + "," +
				updated.relation.prepSQL() + "," +
				updated.email.prepSQL() + "," +
				"null);";
		}
		cSQL += DataHandler.contacts;
		var query = new execQuery(cSQL, function (data) {
			oContact = {
				contact_id: data[0][0].CONTACT_ID,
				name: updated.name,
				relationship: updated.relation,
				email: updated.email
			};

			if (AccountContact.current.contact_id == -1 || AccountContact.current.email != updated.email)
				AccountContact.sendConfirmation(oContact);

			User.aContacts = data[1];
			Account.refresh.contacts();
			$("#elapContactsTable").hide();
			$("#btnAddContact").show();
		});
	},
	openDialog: function (bFromNewAccount, contact_id) {
		if (!this.initialized) this.init();
		this.bFromNewAccount = bFromNewAccount;
		AccountContact.current.contact_id = Number(contact_id);

		var jVals, cTitle;

		// contact_id of -1 means new contact
		if (contact_id == -1) {
			cTitle = "New Shop Account Contact";
			AccountContact.current.name = '';
			AccountContact.current.relation = '';
			AccountContact.current.email = '';
		}
		else {
			cTitle = "Edit Shop Account Contact";
			if (bFromNewAccount) jVals = $("#divContacts table tbody tr[contact_id=" + contact_id + "]").find("td");
			else jVals = $("#tblContacts tbody tr[contact_id=" + contact_id + "]").find("td");

			AccountContact.current.name = jVals.eq(0).text();
			AccountContact.current.relation = jVals.eq(1).text();
			AccountContact.current.email = jVals.eq(2).text();
			AccountContact.current.email_verified = jVals.parent().attr("email_verified");
		}

		$("#diagContact").dialog({ autoOpen: true, modal: true, width: 400, title: cTitle,
			open: function () {
				LogEntry(cTitle + " window dialog opened.")
				var jButtons = $("#diagContact").siblings('.ui-dialog-buttonpane').find('button');
				jButtons.eq(0).button({ disabled: true, icons: { primary: 'ui-icon-check'} });
				jButtons.eq(1).button({ icons: { primary: 'ui-icon-closethick'} });

				$("#diagContact #ContactName").val(AccountContact.current.name);
				$("#diagContact #ContactRelation").val(AccountContact.current.relation);
				$("#diagContact #ContactEmail").val(AccountContact.current.email);

				$("#ContactEmailConfirmed").hide();
				if (AccountContact.current.email_verified) {
					$("#diagContact #ContactEmail").attr("disabled", "disabled");
					$("#ContactEmailConfirmed").show();
				}
				AccountContact.validateInputs();
			},
			close: function () { $(this).dialog('destroy'); },
			buttons: {
				"Save": function () {
					LogEntry("Account Contact dialog changes saved.");
					$(this).dialog('close'); AccountContact.save();
				},
				"Cancel": function () {
					LogEntry("Account Contact dialog canceled.");
					$(this).dialog('close'); 
				}
			}
		});

	},
	sendConfirmation: function (oContact) {
		var oPartyName, cGender, cHisHer, cProvider;
		if (AccountContact.bFromNewAccount) {
			oPartyName = $("#txtFullName").val().parseName();
			cGender = $("#selGender").val();
			cProvider = NewAccount.oCertificate.CUSTOMER_NAME;
		}
		else {
			oPartyName = User.oData.NAME.parseName(User.oData.NICK_NAME);
			cGender = User.oData.GENDER;
			cProvider = User.ProviderName;
		}
		cHisHer = (cGender == 'M') ? "his" : ((cGender == 'F') ? "her" : "his/her");
		var pronouns = new genderPronouns(cGender);
		var oName = oContact.name.parseName();

		Email.send({
			to_contact_id: oContact.contact_id,
			to_name: oName.asEntered,
			to_address: oContact.email,
			subject: oPartyName.asEntered + ' has added you as a contact.',
			template: 'shop_contact_confirm',
			contents: Email.contentTemplates.shop_contact_confirm
				.replace(/__first_name__/g, oName.nick)
				.replace(/__party_first_name__/g, oPartyName.nick)
				.replace(/__adjective_pronoun__/g, pronouns.adjective)
				.replace(/__provider_name__/, cProvider),
			callback: function (bSuccess) { return; }
		});
	}
};

var NewAccount = {
	oCertificate: {},
	initialized: false,
	valid: {
		name: function () {
			return ($("#txtFullName").val().trim().length >= 2)
		},
		email: function () {
			var cVal = $("#txtEmail").val();
			return (cVal.validEmail() || cVal.toLowerCase().trim() == "no email");
		},
		demographics: function () {
			return !($("#selGender").val() == "0" || $("#selBirthYear").val() == "0");
		},
		anyContacts: function () {
			return $("#chkNoContacts").attr("checked") || $("#chkNoMoreContacts").attr("checked");
		},
		all: function () {
			var bAllValid = (this.name() && this.email() && this.demographics() && this.anyContacts());
			$("#btnCompleted").button({ disabled: !bAllValid });
			if (bAllValid) $("#btnCompleted").parent().fadeIn();
			else $("#btnCompleted").parent().fadeOut();
		}
	},
	certificateValidated: function (oCertificate) {
		var oCertificate = NewAccount.oCertificate;
		$("#spnCertificateInfo").text(oCertificate.CUSTOMER_NAME + " has awarded you " + oCertificate.AMOUNT + " " + oCertificate.TOKENUNIT.toLowerCase().toPlural(oCertificate.AMOUNT));
		$(".tokenName").text(oCertificate.TOKENUNIT.toLowerCase());

		var jSel = $("#selBirthYear");
		var nYear = Number(new Date().getFullYear()) - 4;
		for (var nX = 15; nX > 0; nX--) {
			jSel.append('<option>' + String(nYear - nX) + '</option>');
		}
		jSel.append('<option value="">Prefer not to say</option>');

		$("#btnCompleted").button({ disabled: true }).show();

		$("#divUserName").show();
		$("#divUserName").next().show();
		$("#NewAccountPane #CodeValidated").slideDown(500, function () {
			$("#NewAccountPane #txtFullName").focusin().focus();
		});

		var txtFullName = function () {
			$("#CodeValidated #txtFullName")
			.focusin(function () {
				$("#divUserName").next().slideDown();
				$("#divEmail").next().slideUp();
				$("#divDemographics").next().slideUp();
				$("#divContacts").next().slideUp();
			})
			.keyup(function (event) {
				jThat = $("#btnNameValid");
				if (NewAccount.valid.name()) jThat.button({ disabled: false }).show();
				else jThat.button({ disabled: true }).show();
				NewAccount.valid.all();
				if (event.keyCode == 13) jThat.click();
			});

			$("#CodeValidated #btnNameValid").show()
			.click(function () {
				$("#CodeValidated #btnEmailValid").button({ label: "Email Invalid", icons: { secondary: ''} }).show();
				var cName = $("#txtFullName").val().parseName().first.toLowerCase().prepSQL();
				var query = new execQuery("select * from ref$name_gender where lower(name)=" + cName + ";", function (data) {
					if (data.length > 0)
						switch (data[0].GENDER) {
						case "M": $("#divDemographics #selGender").val("M"); break;
						case "F": $("#divDemographics #selGender").val("F"); break;
					}
				});
				$("#divUserName").next().slideUp("normal", function () {
					$("#divEmail").slideDown(500);
					$("#CodeValidated #txtEmail").focusin().focus();
				});
				$(this).hide();
			});
		} ();

		var txtEmail = function () {
			$("#CodeValidated #txtEmail")
			.focusin(function () {
				$("#divEmail").next().slideDown();
				$("#divUserName").next().slideUp();
				$("#divDemographics").next().slideUp();
				$("#divContacts").next().slideUp();
			})
			.keyup(function (event) {
				var cVal = $(this).val();
				var jBtn = $("#CodeValidated #btnEmailValid");
				NewAccount.valid.all();
				if (NewAccount.valid.email()) {
					jBtn.button({ label: "Next Question", disabled: false, icons: { secondary: 'ui-icon-triangle-1-e'} }).show();
					if (event.keyCode == 13) jBtn.click();
				}
				else jBtn.button({ label: "Email Invalid", disabled: true, icons: { secondary: ''} }).show();
			});
			$("#CodeValidated #btnEmailValid").click(function () {
				$("#divEmail").next().slideUp("normal", function () {
					$("#divDemographics").slideDown(500);
					var jGender = $("#divDemographics #selGender");
					if (jGender.val() == "0") jGender.focus();
					else $("#selBirthYear").focus();
					$("#divDemographics").focusin();
				});
				$(this).hide();
			});
		} ();

		var divDemographics = function () {
			$("#divDemographics")
			.focusin(function () {
				$("#divEmail").next().slideUp();
				$("#divUserName").next().slideUp();
				$("#divDemographics").next().slideDown();
				$("#divContacts").next().slideUp();
			});
			$("#selBirthYear, #selGender").keyup(function (event) {
				NewAccount.valid.all();
				var jBtn = $("#CodeValidated #btnDemoValid");
				jBtn.button({ label: "Next Question", disabled: true, icons: { secondary: 'ui-icon-triangle-1-e'} }).show();
				if (NewAccount.valid.demographics()) {
					jBtn.button({ disabled: false });
					if (event.keyCode == 13) jBtn.click();
				}
			}).change(function () { $(this).keyup(); });
			$("#CodeValidated #btnDemoValid").click(function () {
				$("#divDemographics").next().slideUp("normal", function () {
					$("#divContacts").slideDown("normal", function () { $("#divContacts").focusin(); $("#btnNewContact1").focus(); })
				});
				$(this).hide();
			});
		} ();

		var divContacts = function () {
			$("#divContacts").focusin(function () {
				$("#divEmail").next().slideUp();
				$("#divUserName").next().slideUp();
				$("#divDemographics").next().slideUp();
				if (!NewAccount.valid.anyContacts() && !$("#divContacts table").is(":visible")) $("#divContacts").next().slideDown();
				$("#btnNewContact1,#btnNewContact2").button({ disabled: false });
			});
			$("#btnNewContact1,#btnNewContact2").button({ disabled: false, icons: { primary: "ui-icon-check"} })
			.click(function () {
				if ($("#chkNoContacts").attr("checked") || $("#chkNoMoreContacts").attr("checked")) {
					$("#chkNoContacts,#chkNoMoreContacts").attr("checked", false);
					$("label[for=chkNoContacts],label[for=chkNoMoreContacts]").removeClass("ui-state-active");
				}
				NewAccount.valid.all();
				AccountContact.openDialog(true, -1);
				$(this).removeClass("ui-state-hover").removeClass("ui-state-active");
			});

			$("#chkNoContacts,#chkNoMoreContacts").attr("checked", false)
			.button({ icons: { primary: "ui-icon-closethick"} })
			.click(function () {
				if ($(this).attr("id") == "chkNoContacts") {
					if ($(this).attr("checked")) {
						$("#divContacts").next().slideUp();
					}
					else {
						$("#divContacts").next().slideDown();
					}
				}
				NewAccount.valid.all();
			});
		} ();

		$("#btnCompleted").click(function () {
			$("#CodeValidated").slideUp(1000, function () {
				$("#divFinished").slideDown(1000, function () {
					NewAccount.finished();
				});
			});
		});
	},
	validateCertificate: function () {
		$("#btnValidateCode").hide();
		$("#CodeSearchElapsor").show();
		var cCode = $("#txtNewAccount_DepositCode").val().replace(" ", "").toLowerCase();
		var query = new execQuery("select * from shop$certificate(" + cCode.prepSQL() + ",null);", function (data) {
			cCode = "(" + cCode.toUpperCase() + ")";
			$("#CodeSearchElapsor").hide();
			var oCertificate = data[0];
			if (oCertificate.CERT_CODE == undefined || oCertificate.CERT_CODE == '') {
				$("#divCodeNotFound").slideDown(500);
				$("#btnValidateCode").button({ label: "Invalid Code", disabled: true, icons: { secondary: ''} }).show();
				$("#txtNewAccount_DepositCode").focus();
				LogEntry("New Shop Account - " + cCode + " - cert code fail, not found.");
				return;
			}
			if (oCertificate.USED == oCertificate.AMOUNT) {
				$("#divCodeUsed").slideDown(500);
				$("#btnValidateCode").button({ label: "Invalid Code", disabled: true, icons: { secondary: ''} }).show();
				$("#txtNewAccount_DepositCode").focus();
				LogEntry("New Shop Account - " + cCode + " - cert code fail, code used.");
				return;
			}
			if (oCertificate.PARTY_NOT_ELIGIBLE) {
				$("#divWrongParty .codeProviderName").text(oCertificate.CUSTOMER_NAME);
				$("#divWrongParty").slideDown(500);
				$("#btnValidateCode").button({ label: "Invalid Code", disabled: true, icons: { secondary: ''} }).show();
				$("#txtNewAccount_DepositCode").focus();
				LogEntry("New Shop Account - " + cCode + " - cert code fail, code for different party.");
				return;
			}
			if (oCertificate.AWARD_DELETED || (oCertificate.GROUP_QTY_AVAILABLE && oCertificate.GROUP_QTY_AVAILABLE.toNumber() <= 0)) {
				$("#divAwardBad .codeProviderName").text(oCertificate.CUSTOMER_NAME);
				$("#divAwardBad").slideDown(500);
				$("#btnValidateCode").button({ label: "Invalid Code", disabled: true, icons: { secondary: ''} }).show();
				$("#txtNewAccount_DepositCode").focus();
				LogEntry("New Shop Account - " + cCode + " - cert code fail, award deleted or exhausted qty.");
				return;
			}

			// Code must be valid
			LogEntry("New Shop Account - " + cCode + " - cert code good for new account.");
			NewAccount.oCertificate = oCertificate;
			$("#NewAccountPane #EnterCode").slideUp(500, function () {
				NewAccount.certificateValidated();
			})
		});
	},
	show: function () {
		if (!NewAccount.initialized) NewAccount.init();
		if (ui.IE6) $(".paneBorder,.copyright").hide();

		$("#CodeValidated").hide()
		$("#NewAccountPane #EnterCode").show();
		$("#NewAccountPane").position({ my: "center bottom", at: "center top", of: $('body'), collision: "none" })
		.show()
		.position({ my: "center top", at: "center top", of: $('body'), collision: "none", using:
			function (to) {
				$(this).animate(to, 1500, "", function () {
					$(".ProductThumb").hide();
					$('#txtNewAccount_DepositCode').focus();
				});
			}
		});
		$("#Copyright").fadeOut(1000);
		$("#MenuBar, #PageHeader").animate({ top: "-80px" }, 1000);
	},
	hide: function (callback) {
		$("#PageHeader").animate({ top: "0px" }, 1000);
		$("#MenuBar").animate({ top: "36px" }, 1000);
		$("#Copyright").fadeIn(1000);
		$("#NewAccountPane")
		.position({ my: "center bottom", at: "center top", of: $('body'), collision: "none", using:
			function (to) {
				$(this).animate(to, 1000, "",
				function () {
					$("#NewAccountPane").hide();
					callback();
				});
			}
		});
	},
	init: function () {
		Login.hideTip();

		$(".btnNextQuestion").button({ label: "Next Question", disabled: true, icons: { secondary: 'ui-icon-triangle-1-e'} });

		$("#NewAccountPane #NoteToParents").accordion({
			collapsible: true,
			active: false,
			autoHeight: false,
			change: function (event, ui) { LogEntry("Note To Parents panel toggled."); }
		});

		$("#NewAccountPane #btnBack").button({ icons: { primary: 'ui-icon-triangle-1-w'} }).click(function () { window.location.hash = "#Rewards"; });
		$("#NewAccountPane .paneNavsLogo").click(function () { window.location.hash = ""; });
		$("#btnValidateCode").button({ label: "Invalid Code", disabled: true, icons: { secondary: ''} }).show().click(function () {
			$(this).hide();
			NewAccount.validateCertificate();
		});

		$('#txtNewAccount_DepositCode')
		.keyup(function (event) {
			var bValid = $(this).val().validDepositCode();

			if (!bValid) {
				$("#btnValidateCode").button({ label: "Invalid Code", disabled: true, icons: { secondary: ''} });
			}
			else {
				$("#btnValidateCode").button({ label: "Validate Code", disabled: false, icons: { secondary: 'ui-icon-triangle-1-e'} });
			}
			$("#NewAccountPane .badCode").slideUp(500);
			if (event.keyCode == 13 && bValid) NewAccount.validateCertificate();
		});

		if ($('#txtNewAccount_DepositCode').val().validDepositCode()) $('#txtNewAccount_DepositCode').keyup();

		NewAccount.initialized = true;

	},
	finished: function () {
		var oCertificate = NewAccount.oCertificate;
		var cEmail = $("#CodeValidated #txtEmail").val();
		cEmail = (cEmail.toLowerCase() == "no email") ? "" : cEmail;

		var cName = $("#NewAccountPane #txtFullName").val();
		var oNames = cName.parseName();

		var cSQL = "select * from COM$PARTICIPANT_INSERT(" +
				oCertificate.CUSTOMER_ID.prepSQL() + ", " +
				cName.prepSQL() + ", " +
				oNames.sort.prepSQL() + ", " +
				oNames.nick.prepSQL() + ", " +
				cEmail.prepSQL(true) + ", " + //email
				$("#selGender").val().prepSQL(true) + "," +
				$("#selBirthYear").val().prepSQL(true) + "," +
				"null," + // Class_ID
				"null," + // Initial Deposit
				oCertificate.CERT_CODE.prepSQL() + ");";
		var query = new execQuery(cSQL, function (data) {
			$("#txtLogin").val(data[0].CODE.toUpperCase()).keyup();
			$("#divFinished #setupComplete")
				.find("#depositAmount").text(data[0].AMOUNT_DEPOSITED).end()
				.find(".newAccountCode").text(data[0].CODE.toUpperCase()).end()
				.find("#btnBeginShopping").button().click(function () {
					$("#divFinished #setupComplete").hide();
					window.location.hash = "#Rewards";
				});

			LogEntry("New Shop Account Created - (" + data[0].CODE + ")");
			NewAccount.partyContacts(data[0]);

			if (cEmail > "") {
				NewAccount.sendWelcomeMail(data[0]);
			}
			else {
				$("#divFinished #setupComplete #noEmail").show();
				$("#divFinished #elapCreateAccount").slideUp(500, function () { $("#divFinished #setupComplete").slideDown(); });
			}

		});
	},
	partyContacts: function (oAccount) {
		var jTbody = $("#divContacts table tbody");
		var jRows = jTbody.find("tr");
		var nContacts = jRows.length;
		if (nContacts == 0) return;

		var jCells = [];
		var aContacts = [];

		var cSQL = "select * from shop$login(" + oAccount.CODE.prepSQL() + ",'');";
		var query = new execQuery(cSQL, function (data) {
			var cKey = data[0].LOGIN_KEY;

			cSQL = '';
			for (var nX = 0; nX < nContacts; nX++) {
				jCells = jRows.eq(nX).find("td");
				aContacts[nX] = {
					contact_id: '',
					name: jCells.eq(0).text(),
					relationship: jCells.eq(1).text(),
					email: jCells.eq(2).text()
				};
				cSQL += "select * from shop$contact_insert(" +
					cKey.prepSQL() + "," +
					aContacts[nX].name.prepSQL() + "," +
					aContacts[nX].relationship.prepSQL() + "," +
					aContacts[nX].email.prepSQL() + ");";
			}

			var query2 = new execQuery(cSQL, function (aContactIDs) {
				if (nContacts == 1) {
					aContacts[0].contact_id = aContactIDs[0].CONTACT_ID;
					AccountContact.sendConfirmation(aContacts[0]);
				}
				else {
					for (var nX = 0; nX < nContacts; nX++) {
						aContacts[nX].contact_id = aContactIDs[nX][0].CONTACT_ID;
						AccountContact.sendConfirmation(aContacts[nX]);
					}
				}
			});
		});

	},
	sendWelcomeMail: function (oAccount) {
		var oName = $("#txtFullName").val().parseName();

		Email.send({
			to_contact_id: oAccount.CONTACT_ID,
			to_name: oName.asEntered,
			to_address: $("#CodeValidated #txtEmail").val().trim(),
			subject: 'Welcome to the Shop at Token Rewards.',
			template: 'shop_welcome',
			contents: Email.contentTemplates.shop_welcome
				.replace(/__first_name__/, oName.nick)
				.replace(/__account_code__/g, oAccount.CODE.toUpperCase()),
			callback: function (bSuccess, cSentTo, oMailData) {
				//if (!bSuccess) { alert('Sorry, there was an error when delivering the email.'); return; }
				$("#emailDeliveredTo").text(cSentTo);
				$("#divFinished #setupComplete #emailDelivered").show();
				$("#divFinished #elapCreateAccount").slideUp(500, function () { $("#divFinished #setupComplete").slideDown(); });
			}
		});
	}
};

var Login = {
	cCode: '',
	sessionUser: null,
	sessionKey: null,
	timer: false,
	oAccount: false,
	hideTip: function () { $("#tipCodeEntry").animate({ top: "-435px" }, 500, "easeInQuad"); },
	showTip: function () {
		$("#tipCodeEntry").show().stop(true, false).animate({ top: "-30px" }, 750, function () {
			$("#txtLogin").focus();
		});
	},
	prevVal: '',
	XHR: false,
	keyup: function (event) {
		var cLogin = $("#txtLogin").val().replace(" ", "").toLowerCase();
		clearTimeout(Login.timer);
		if (Login.XHR) Login.XHR.abort();

		if (cLogin.validAccountCode() || cLogin.validEmail()) {

			if ($("#passwordInputs").is(":visible") && (event.keyCode == 13 || event.keyCode == 9)) { $("#txtPassword").focus(); }

			if (Login.prevVal != cLogin) {
				Login.timer = setTimeout(function () {
					$("#tipCodeEntry .hidden").hide();
					$("#loginTip").hide();
					$("#tipLoginElapsor span").text("Looking for Account " + cLogin + "");
					$("#tipLoginElapsor").show();
					Login.XHR = new execQuery("select * from shop$login(" + cLogin.prepSQL() + ",null);", function (data) {
						Login.prevVal = cLogin;
						if (cLogin.validAccountCode()) Login.codeEntered(data);
						else Login.emailEntered(data);

						if ($("#passwordInputs").is(":visible")) $("#txtPassword").focus();
					});
				}, 250);
			}
			return;
		}
		$("#tipCodeEntry .hidden").hide();
		$("#loginTip").show();
	},

	init: function (callback) {
		var sHash = window.location.hash;
		var bOpenPassword = false;
		if ((/AutoLogin/i).test(sHash) || (/SetPassword/i).test(sHash)) {
			ui.elap.on("Auto Login");
			var sEmailCode = sHash.substring(sHash.indexOf("_") + 1, sHash.length).toLowerCase();
			var SQL = "select * from shop$login_email_code(" + sEmailCode.prepSQL() + ");";


			if ((/SetPassword/i).test(sHash)) {
				bOpenPassword = true;
			}
			else window.location.replace = "#Rewards";


			new execQuery(SQL, function (data) {
				if ($.type(data[0]) != "object" || !data[0].LOGIN_KEY) {
					ui.modalMessage({
						title: "Unable to Auto-Login",
						message: "Sorry, but there was a problem logging you in automatically.  The auto-login code or your account not be located."
					});
					LogEntry("Auto-login failed, unabled to find account/email code.");
					Login.init(callback);
					return;
				}

				var oLogin = data[0];
				if (oLogin.ACTIVATED != "1") {
					ui.modalMessage({
						title: "Unable to Auto-Login",
						message: "Sorry, but your account has been inactivated.  Please contact your reward provider to reactivate your account."
					});
					LogEntry("Auto-login failed, account inactivated.");
					Login.init(callback);
					return;
				}

				LogEntry("Auto-login from email code successful.");
				Login.cCode = Login.sessionUser = oLogin.PARTY_CODE;
				Login.sessionKey = User.key = oLogin.LOGIN_KEY;
				DataHandler.init(Login.cCode);
				Login.fetchAccount(function () {
					if (bOpenPassword) {
						window.location.replace("#Account");
						Account.password.open();
					}

					if (callback) callback();
				});

			});
			return;
		}

		this.sessionUser = $.cookie("session_account");
		this.sessionKey = $.cookie("login_key");

		if (Login.sessionUser && Login.sessionKey) {
			Login.cCode = Login.sessionUser;
			User.key = Login.sessionKey;
			DataHandler.init(Login.cCode);
			Login.fetchAccount(callback);
			return;
		}


		$("#CodeEntry").mouseenter(function () { Login.showTip(); });
		$("#tipCodeEntry").bgiframe();

		$('body').click(function (event) { if (!$("#passwordInputs").is(":visible")) Login.hideTip(); });

		$("#btnLogin").button({ disabled: true, label: "Ok!", icons: { primary: "ui-icon-check"} })
		.click(function () {
			Login.attempt(false);
		});
		$("#btnLoginNoPassword").click(function () {
			Login.attempt(false);
		});

		$("#txtPassword").keyup(function (event) {
			$("#badPassword").hide();
			if ($(this).val().length >= 4) {
				$("#btnLogin").button({ disabled: false });
				if (event.keyCode == 13) { $("#btnLogin").click(); return; }
			}
			else $("#btnLogin").button({ disabled: true });
		});

		$("#txtLogin")
		.click(function (event) { event.stopPropagation(); Login.showTip(); })
		.keyup(function (event) { Login.keyup(event); });

		$("#btnNewAccount").button().click(function (event) {
			var cLogin = $("#txtLogin").val().replace(" ", "");
			if (cLogin.validDepositCode()) {
				$("#txtNewAccount_DepositCode").val(cLogin);
			}
			$(window).hashchange(function () { Application.hashChanged(); });
			window.location.hash = "#NewAccount";
		});
		$("#btnSetPassword").button({ label: "Mail Password Help", icons: { primary: "ui-icon-mail-closed"} })
		.click(function () { Login.resetPassword(); });

		if (callback) callback();
	},
	attempt: function (SQL) {

		// standard login
		var cLogin = $("#txtLogin").val().toLowerCase().replace(" ", "");
		SQL = "select * from shop$login(" + cLogin.prepSQL() + "," + $("#txtPassword").val().prepSQL() + ");";
		new execQuery(SQL,
		function (aAccount) {
			if (aAccount.length == 0 || aAccount[0].LOGIN_KEY == '') {
				if ($("#passwordInputs").is(":visible")) {
					$("#badPassword").show();
					$("#txtPassword").val("").focus();
				}
				else $("#noAccountCode").show();
				User.key = '';
				return false;
			}
			if (aAccount[0].ACTIVATED != "1") {
				$("#loginProviderName").text(aAccount[0].PROVIDER);
				$("#inactiveAccountCode").text(aAccount[0].PARTY_CODE.toUpperCase());
				$("#inactiveAccount").show();
				User.key = '';
				return false;
			}

			if (aAccount[0].LOGIN_KEY == '') {
				//some other error/problem, shouldn't happen.
				alert("An unforeseen problem has occured, please contact Token Rewards if this continues.");
				User.key = '';
				return false;
			}
			//Good for login
			User.key = aAccount[0].LOGIN_KEY;
			Login.cCode = aAccount[0].PARTY_CODE;
			DataHandler.init(Login.cCode);
			Login.fetchAccount();
			return true;
		});
	},
	fetchAccount: function (callback) {
		ui.openWait("Retrieving your account now...");
		var query = DataHandler;
		query.execute(query.userData, function (aTables) {
			ui.elap.off();
			if (Login.accountValid(aTables[0][0])) {
				User.init(aTables);
			}
			else ui.closeWait();

			if (callback) callback();
			else Catalog.show();
		});
	},
	accountValid: function (oUser) {
		if (!oUser || oUser.CODE != Login.cCode || oUser.ACTIVATED != "1") {
			$.cookie("session_account", null);
			$.cookie("login_key", null);
			Login.sessionUser = null;
			Login.sessionKey = null;
			Login.init();
			return false;
		}

		return true;
	},
	emailEntered: function (aAccounts) {
		$("#tipCodeEntry .hidden").hide();
		if (aAccounts.length == 0) {
			$("#noAccountsEmail").show();
			Login.oAccount = false;
			return;
		}

		$("#passwordInputs").show();
		if (aAccounts.length > 1) {
			$("#tipWelcome").hide();
			$("#singleEmailAccount").hide();
			$("#multiEmailAccount").show();
			Login.oAccount = false;
		}
		else {
			User.nickName = aAccounts[0].NAME.parseName(aAccounts[0].NICK_NAME).nick;
			$("#tipWelcome").text(NewsTicker.welcomeNote()).show();
			$("#multiEmailAccount").hide();
			$("#singleEmailAccount").show();
			Login.oAccount = aAccounts[0];
		}
	},
	codeEntered: function (aAccount) {
		$("#tipCodeEntry .hidden").hide();
		if (aAccount.length == 0) {
			$("#noAccountCode").show();
			Login.oAccount = false;
			return;
		}

		Login.oAccount = aAccount[0];
		User.oData.NAME = aAccount[0].NAME;
		User.oData.NICK_NAME = aAccount[0].NICK_NAME;
		User.nickName = aAccount[0].NAME.parseName(aAccount[0].NICK_NAME).nick;
		if (aAccount[0].ACTIVATED == "0") {
			$("#loginProviderName").text(aAccount[0].PROVIDER);
			$("#inactiveAccountCode").text(aAccount[0].PARTY_CODE.toUpperCase());
			$("#inactiveAccount").show();
			return;
		}

		$("#tipWelcome").text(NewsTicker.welcomeNote()).show();
		if (aAccount[0].PASSWORD_EXISTS == "1") {
			$("#passwordInputs").show();
			if (aAccount[0].EMAIL_VERIFIED) {
				$("#singleEmailAccount").show();
			}
		}
		else {
			$("#LoginName").text(aAccount[0].NAME);
			$("#btnLoginNoPassword").button({
				label: "Hey " + aAccount[0].NAME.parseName(aAccount[0].NICK_NAME).nick + "!<br/>" +
					"Click here to log in!",
				icons: { primary: "" }
			});
			$("#noPasswordCode").show();
		}
	},
	resetPassword: function () {
		var cToAddress = Login.oAccount.EMAIL;

		$("#singleEmailAccount").hide();
		$("#setPasswordDelivery .emailTo").text(cToAddress);
		$("#setPasswordDelivery").show();
		$("#setPasswordDelivery #elapsor").show();
		$("#setPasswordDelivery #delivered").hide();

		var oName = Login.oAccount.NAME.parseName(Login.oAccount.NICK_NAME);

		Email.send({
			to_contact_id: Login.oAccount.CONTACT_ID,
			to_name: oName.asEntered,
			to_address: cToAddress,
			contents: Email.contentTemplates.shop_lost_password
			.replace(/__first_name__/, oName.nick)
			.replace(/__account_code__/g, Login.oAccount.PARTY_CODE.toUpperCase()),

			callback: function (bSuccess) {
				//if (!bSuccess) { alert('Sorry, there was an error when delivering the email.'); return; }
				$("#setPasswordDelivery #setup_email_elapsor").hide();
				$("#setPasswordDelivery #delivered").show();

			}
		});
	}
};

var NewsTicker = {
	nCurrentItem: 0,
	interval: false,
	welcomeNote: function () {
		var cUserName = User.nickName;
		var aSals = ["Hey there, " + cUserName + "!",
						"What's happening, " + cUserName + "?",
						"Welcome back, " + cUserName + "!",
						"How's it going " + cUserName + "?",
						"Hello there, " + cUserName + "!",
						"What's new, " + cUserName + "?",
						"Howdy, " + cUserName + "!",
						"Nice to see you, " + cUserName + "!"];
		var cText = aSals[Math.floor(Math.random() * aSals.length)];
		return cText;
	},
	begin: function () {
		NewsTicker.update();
		NewsTicker.interval = setInterval(function () {
			NewsTicker.update();
		}, 20000);
	},
	update: function () {
		var jItems = $("#NewsTicker .tickerItem");
		var cWidth = "-" + jItems.eq(NewsTicker.nCurrentItem).width() + "px";
		jItems.eq(NewsTicker.nCurrentItem).animate({ left: cWidth }, 1000, false, function () {
			if (jItems.length == NewsTicker.nCurrentItem + 1) NewsTicker.nCurrentItem = 0;
			else NewsTicker.nCurrentItem++;
			jItems.eq(NewsTicker.nCurrentItem).animate({ left: "0px" }, 2500, "easeOutQuad");
		});
	}
};

var DataHandler = {
	userData: "", 
	account: "\n", userProducts: "\n", pendingOrders: "\n",
	ledger: "\n", awards: "\n", contacts: "\n", shipSchedule: "\n",
	closeWish: function (nWishedProduct) {
		return String.fromCharCode(13) + "SELECT * FROM SHOP$cancel_order(" + User.key.prepSQL() + "," + nWishedProduct.prepSQL() + ");";
	},
	init: function () {
		this.contacts += "select * from shop$contacts(" + User.key.prepSQL() + ");";
		this.account += "select * FROM shop$account(" + User.key.prepSQL() + ");";
		this.userProducts += "select * from shop$products(" + User.key.prepSQL() + ",null) order by tokens_each, name;";
		this.ledger += "select * from shop$ledger(" + User.key.prepSQL() + ") order by added descending;";
		this.awards += "select * from shop$awards(" + User.key.prepSQL() + ") order by amount ascending;";
		this.shipSchedule += "select * from shop$shipping_schedule(" + User.key.prepSQL() + ");";
		this.pendingOrders += "select * from shop$pending(" + User.key.prepSQL() + ",null);";

		this.userData = 
			this.account +
			this.userProducts +
			this.ledger +
			this.contacts +
			this.awards +
			this.shipSchedule;
	},
	execute: function (queryString, callback) { new execQuery(queryString, callback); }
};


String.prototype.validCode = function () {
	var rX = new RegExp("[^a-z0-9]|i|o","g");
	return !rX.test(this.toLowerCase());
}
String.prototype.validDepositCode = function () {
	var cX = this.replace(" ", "").toLowerCase();
	return (cX.length > 5 && cX.validCode());
}
String.prototype.validAccountCode = function () {
	var cX = this.replace(" ", "").toLowerCase();
	return (cX.length == 7 && cX.validCode());
}

$(document).ready(function () { Application.docReady(); });



// bgIframe {
/* Copyright (c) 2006 Brandon Aaron (http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) 
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 * 
 * $LastChangedDate: 2007-07-21 18:45:56 -0500 (Sat, 21 Jul 2007) $
 * $Rev: 2447 $
 *
 * Version 2.1.1
 */
(function ($) { $.fn.bgIframe = $.fn.bgiframe = function (s) { if ($.browser.msie && /6.0/.test(navigator.userAgent)) { s = $.extend({ top: 'auto', left: 'auto', width: 'auto', height: 'auto', opacity: true, src: 'javascript:false;' }, s || {}); var prop = function (n) { return n && n.constructor == Number ? n + 'px' : n; }, html = '<iframe class="bgiframe"frameborder="0"tabindex="-1"src="' + s.src + '"' + 'style="display:block;position:absolute;z-index:-1;' + (s.opacity !== false ? 'filter:Alpha(Opacity=\'0\');' : '') + 'top:' + (s.top == 'auto' ? 'expression(((parseInt(this.parentNode.currentStyle.borderTopWidth)||0)*-1)+\'px\')' : prop(s.top)) + ';' + 'left:' + (s.left == 'auto' ? 'expression(((parseInt(this.parentNode.currentStyle.borderLeftWidth)||0)*-1)+\'px\')' : prop(s.left)) + ';' + 'width:' + (s.width == 'auto' ? 'expression(this.parentNode.offsetWidth+\'px\')' : prop(s.width)) + ';' + 'height:' + (s.height == 'auto' ? 'expression(this.parentNode.offsetHeight+\'px\')' : prop(s.height)) + ';' + '"/>'; return this.each(function () { if ($('> iframe.bgiframe', this).length == 0) this.insertBefore(document.createElement(html), this.firstChild); }); } return this; }; })(jQuery);




