/************************************************************************************/
/* $Revision: 106264 $
 * $Id: cmtaggingservices.js.txt 106264 2008-12-19 16:33:37Z abrink $
 *
 * Author: Coremetrics/PSD 
 * Coremetrics  v1.2, 12/18/2008
 * COPYRIGHT 1999-2008 COREMETRICS, INC. 
 * ALL RIGHTS RESERVED. U.S.PATENT PENDING
 * Disclaimer: Coremetrics is not responsible for hosting or maintenance or this file
 *
 */
/************************************************************************************/
//Production data warehouse flag
cmSetProduction();
/*===========================GLOBAL VARIABLES ===============================*/
// options for debug mode when sending tag:
// 1: only alert
// 2: only send tag
// 3: alert & send tag
var G_PS_DEBUG_MODE = 2;

// current page url
var G_PS_URL_PATH = "" + document.location.href.toLowerCase();
var G_PS_PATHNAME = document.location.pathname.toLowerCase();
var G_PS_QUERYSTRING = document.location.search.toLowerCase();
var G_PS_COOKIE_LIFETIME = 604800; // 7*24*60*60 = 7 days
// cookie name
var G_PS_COOKIE_CATID = "PS_CATID";
var G_PS_COOKIE_PROD_CATID = "PS_PROD_CATID";
var G_PS_COOKIE_PROFILE = "PS_PROFILE";
var G_PS_COOKIE_SHOP9 = "PS_SHOP9";
var G_PS_COOKIE_ORDER = "PS_ORDER";
var G_PS_COOKIE_FLAG = "PS_FLAG";		// used as a "session" variable to handle events between pages
// current category ID while browsing/searching/refining, etc
var G_PS_CUR_CATID = null;
/*========================= END GLOBAL VARIABLES =============================*/

if (G_PS_PATHNAME == "/shop/catalog.html")
{
	cmCreateConversionEventTag("CATALOG REQUEST", "1", "REQUEST A CATALOG", "10");
}
if (G_PS_PATHNAME == "/shop/catalogdownload.html")
{
	cmCreateConversionEventTag("CATALOG REQUEST", "2", "REQUEST A CATALOG", "90");
}

/*=========================== BEGIN NAVIGATION ===============================*/
// Navigation logic should go here!
if (document.location.hostname.search(/smartfixtures.com/gi)>=0)
{
	if (G_PS_PATHNAME == "/shop/processorder.asp")
	{
		psCreateErrorTag("ERROR", "ERROR");
	}
	else if (psIsSearchView())
	{
		psPostSearchView();
	}
	else if (psIsProductView())
	{
		psPostProductView();
		// Hijack AddToCart button
		psHijackAddToCart();
	}
	else if (psIsCartView())
	{
		psPostCartView();
		// Hijack the Proceed to Checkout button to resend shop5 tags
		psHijackProceedToCheckOut();
	}
	else if (psIsOrderView())
	{
		psPostOrderView();
	}
	else 
	{
		psPostPageView();
	}
	// Clear search flag 
	if ((psIsProductView() == false) && (psIsSearchView() == false) && (psGetCookie(G_PS_COOKIE_FLAG) == "search"))
	{
		psSetCookie(G_PS_COOKIE_FLAG, "");
	}
	// Post registration tag if any
	if (psIsLoginPage() == false)
		psPostRegistrationTag();
}

/*
 * Determine if the page is the search result page
 */
function psIsSearchView()
{
	var result = (G_PS_PATHNAME.search(/\/landing_template_search.asp/gi)>=0) 
		|| (G_PS_PATHNAME.search(/\/search_results.asp/gi)>=0);

	return result;
}

/*
 * Determine if the page is the product detail page
 */
function psIsProductView()
{
	return G_PS_PATHNAME.search(/catalog.product.asp/gi)>=0;
}

/*
 * Determine if the page is the shopping cart page
 */
function psIsCartView()
{
	return (G_PS_PATHNAME.search(/\/shop\/cart.html/gi)>=0);
}

/*
 * Determine if the page is the thank you page
 */
function psIsOrderView()
{
	return (G_PS_PATHNAME.search(/\/shop\/shopping_template.asp/gi)>=0);
}
/*============================ END NAVIGATION ================================*/


/*===================== BEGIN TAGGING BUSSINESS LOGIC ========================*/
function psPostSearchView()
{
	// Your logic of throwing pageview tag for search functionalities goes here
	G_PS_CUR_CATID = "SEARCH";
	var pageId = psGetSearchPageId();
	var sResult = psGetSearchResult();
	var sTerm = psGetValueFromUrl(G_PS_QUERYSTRING, "searchtext");
	sTerm = (sTerm == null ? psGetValueFromUrl(G_PS_QUERYSTRING, "q") : sTerm);
	if (pageId != null)
		psCreatePageviewTag(pageId, G_PS_CUR_CATID, sTerm, sResult);
	// Flag search status
	psSetCookie(G_PS_COOKIE_FLAG, "search");
}

/*
 * Get search page id from source code
 */
function psGetSearchPageId()
{
	if (G_PS_PATHNAME.search(/search_results.asp/gi)>=0)
		return "SEARCH";
	else
	{
		var tables = document.getElementsByTagName("table");
		for (var i = 0; i < tables.length; i++)
		{
			if (tables[i].className == "subnav")
			{
				for (var r = 0; r < tables[i].rows.length; r++)
				{
					if (tables[i].rows[r].innerHTML.search(/previous/gi)>=0 
						&& tables[i].rows[r].innerHTML.search(/Your search:/gi)<0)
					{
						for (var c = 0; c < tables[i].rows[r].cells.length; c++)
						{
							if (tables[i].rows[r].cells[c].innerHTML.search(/previous/gi)<0)
							{
								var classes = psGetElementsByClass("activenav", tables[i].rows[r].cells[c]);
								if (classes.length > 0)
								{
									for (var j = 0; j < classes.length; j++)
									{
										var temp = psGetInnerText(classes[j]);
										if (temp.search(/previous/i)<0)
											return "SEARCH SUCCESSFUL PAGE " + temp;
									}
									return "SEARCH SUCCESSFUL";
								}
								else
									return "SEARCH UNSUCCESSFUL";
							}
						}
					}
				}
			}
		}
		return "SEARCH UNSUCCESSFUL";
	}
}

/*
 * Get search result from source code
 */
function psGetSearchResult()
{
	if (G_PS_PATHNAME.search(/search_results.asp/gi)>=0)
		return "0";
	else
	{
		var tables = document.getElementsByTagName("table");
		for (var i = 0; i < tables.length; i++)
		{
			if (tables[i].className == "subnav")
			{
				for (var r = 0; r < tables[i].rows.length; r++)
				{
					if (tables[i].rows[r].innerHTML.search(/previous/gi)>=0 
						&& tables[i].rows[r].innerHTML.search(/Your search:/gi)<0)
					{
						for (var c = 0; c < tables[i].rows[r].cells.length; c++)
						{
							if (tables[i].rows[r].cells[c].innerHTML.search(/previous/gi)<0)
							{
								var classes = psGetElementsByClass("activenav", tables[i].rows[r].cells[c])
								var result = (classes.length > 0 ? psGetInnerText(classes[0]) : "0");
								var aTags = tables[i].rows[r].cells[c].getElementsByTagName("a");
								if (aTags.length > 0)
								{
									var pageNo = psGetInnerText(aTags[aTags.length - 1]); // get the last page number
									pageNo = (result > pageNo ? result : pageNo); // ensure the largest number
									result = (pageNo > 5 ? 5 : pageNo); // Search result is no more than 5 
								}
								return result;
							}
						}
					}
				}
			}
		}
		return "0";
	}
}

/*
 * Process to post productview tag for the item in product detail
 */
function psPostProductView()
{
	var prd = new psProduct();
	if (prd.getProduct()) // Get product info successfully?
		psCreateProductviewTag(prd.id, prd.name, prd.catId);
}

/*
 * Hijack AddToCart button to capture prdId and catId to persist to cookie
 */
function psHijackAddToCart()
{
	for (var i = 0; i < document.images.length; i++)
	{
		if (document.images[i].src.search(/addtocart.jpg/gi)>=0)
		{
			document.images[i].oldCMFunc = document.images[i].onclick;
			document.images[i].onclick = function()
			{
				var prdId = psGetValueFromUrl(G_PS_QUERYSTRING, "product_ID");
				var catId = psGetCatId();
				// Persist prdId along with catId to cookie
				psSetValueToCookie(G_PS_COOKIE_PROD_CATID, prdId, catId);
				// Invoke the original function
				if (this.oldCMFunc != null)
					return this.oldCMFunc();
			}
			break;
		}
	}
}

/*
 * Process to post shop5tags for items in shopping cart
 */
function psPostCartView()
{
	// Throw page view tag
	G_PS_CUR_CATID = "SHOPPING CART";
	psCreatePageviewTag("VIEW CART", G_PS_CUR_CATID, null);

	var cartTbl = document.getElementById("itemTable");
	if (cartTbl == null)
		return;

	var rows = cartTbl.rows; // use rows variable for optimization
	var prd = new psProduct();
	var prdId_catId = "";
	psSetCookie(G_PS_COOKIE_SHOP9, "", "delete"); // Initialize buffer
	for (var r = 1; r < rows.length; r++) // item for each row
	{
		if (rows[r].innerHTML.search(/item #/gi)<0) // Skip rows not containing item (identified by the term "Item #")
			continue;
		if (prd.getItem5(rows[r])) // Get shop5 item successfully?
		{
			psCreateShopAction5Tag(prd.id, prd.name, prd.quantity, prd.price, prd.catId);
			prdId_catId = "#" + prd.id + "~" + prd.catId + prdId_catId;
		}
	}
	psSetCookie(G_PS_COOKIE_PROD_CATID, prdId_catId, G_PS_COOKIE_LIFETIME); // Update the prod_catId cookie
	// Make sure to have actual postings
	psDisplayShop5s();
}

/*
 * Hijack the Proceed to Checkout button to resend shop5 tags with updated quantities
 */
function psHijackProceedToCheckOut()
{
	for (var i = 0; i < document.images.length; i++)
	{
		if (document.images[i].src.search(/\/shoppingcart\/proceedtocheckout.jpg/gi)>=0)
		{
			document.images[i].oldCMFunc = document.images[i].onclick;
			document.images[i].onclick = function()
			{
				psPostCartView(); // Resend shop5 tags
				if (this.oldCMFunc != null)
					return this.oldCMFunc();
			}
			break;
		}
	}
}

/*
 * Process to post shop9tags for items purchased
 */
function psPostOrderView()
{
	// Throw page view tag
	G_PS_CUR_CATID = "SHOPPING CART";
	psCreatePageviewTag("RECEIPT", G_PS_CUR_CATID, null);

	var ord = new psOrder();
	if (ord.getOrder()) // Get order info from cookie
	{
		var uP = new psProfile();
		if (uP.readProfile()) // Read profile
		{
			var prd = new psProduct();
			// Get shop9 items from cookie to throw shop9 tags
			var item9 = psGetCookie(G_PS_COOKIE_SHOP9);
			item9 = (item9 != null ? item9 : "");
			item9 = item9.split("#");
			for (var r = 1; r < item9.length; r++) // item for each row
			{
				if (prd.getItem9(item9[r]))
					psCreateShopAction9Tag(prd.id, prd.name, prd.quantity, prd.price, uP.email, ord.id, ord.subtotal, prd.catId);
			}
			// Make sure to have actual postings
			psDisplayShop9s();
			// Post order tag finally
			psCreateOrderTag(ord.id, ord.subtotal, ord.shipping, uP.email, uP.city, uP.state, uP.zipcode);
			// Post registration tag finally
			psCreateRegistrationTag(uP.email, uP.email, uP.city, uP.state, uP.zipcode, uP.newsletter, uP.subscribe);
			// Delete cookies after checking out successfully
			psSetCookie(G_PS_COOKIE_PROD_CATID, "", "delete");
			psSetCookie(G_PS_COOKIE_PROFILE, "", "delete");
			psSetCookie(G_PS_COOKIE_SHOP9, "", "delete");
			psSetCookie(G_PS_COOKIE_ORDER, "", "delete");
			psSetCookie(G_PS_COOKIE_FLAG, "", "delete");			
		}
	}
}

/*
 * All page view tags go here
 */
function psPostPageView()
{
	var pageId = psGetPageId();
	G_PS_CUR_CATID = psGetCatId();
	
	if (G_PS_PATHNAME == "/")
		pageId = G_PS_CUR_CATID = "HOME";
	else if (G_PS_PATHNAME == "/shop/contact.html")
		pageId = G_PS_CUR_CATID = "Contact Us";	
	else if (G_PS_PATHNAME == "/shop/storefixtures.html")
		pageId = G_PS_CUR_CATID = "Store Fixtures";
	else if (G_PS_PATHNAME == "/shop/storebasics.html")
		pageId = G_PS_CUR_CATID = "Store Basics";
	else if (G_PS_PATHNAME == "/shop/storeplanning.html")
		pageId = G_PS_CUR_CATID = "Store Planning";
	else if (G_PS_PATHNAME == "/shop/officebasics.html")
		pageId = G_PS_CUR_CATID = "Office Basics";
	else if (G_PS_PATHNAME == "/shop/catalog.designer.asp")
		pageId = G_PS_CUR_CATID = "Design Your Own";
	else if (G_PS_PATHNAME == "/shop/designassistanceretail.html")
		pageId = G_PS_CUR_CATID = "Store Planning Assistance";
	else if (G_PS_PATHNAME == "/shop/catalog.html")
		pageId = G_PS_CUR_CATID = "Request A Catalog";
		//cmCreateConversionEventTag("CATALOG REQUEST", "1", "REQUEST A CATALOG", "10");
	else if (G_PS_PATHNAME == "/shop/sale.html")
		pageId = G_PS_CUR_CATID = "Sale";
	else if (G_PS_PATHNAME == "/retailbestsellers.html")
		pageId = G_PS_CUR_CATID = "Retail Bestsellers";
	else if (G_PS_PATHNAME.search(/\/whatsnew.html/gi)>=0)
		pageId = G_PS_CUR_CATID = "Whats New";
	else if (G_PS_PATHNAME == "/shop/accessories.html")
		pageId = G_PS_CUR_CATID = "Accessories";
	else if (G_PS_PATHNAME == "/store/galleries/retail.html")
		pageId = G_PS_CUR_CATID = "Design Gallery";
	else if (G_PS_PATHNAME == "/shop/passwordrecovery.html")
		pageId = G_PS_CUR_CATID = "Password Recovery";
	else if (G_PS_PATHNAME == "/shop/tradeshow.html")
		pageId = G_PS_CUR_CATID = "Tradeshow";
	else if (G_PS_PATHNAME == "/shop/retail.html")
		pageId = G_PS_CUR_CATID = "Retail";
	else if (G_PS_PATHNAME == "/shop/catalogdownload.html")
		pageId = G_PS_CUR_CATID = "Catalog Download";
		//cmCreateConversionEventTag("CATALOG REQUEST COMPLETE", "2", "REQUEST A CATALOG", "90");
	else if (G_PS_PATHNAME == "/storeplanningthankyou.html")
		pageId = G_PS_CUR_CATID = "Store Planning Thank You";
	else if (G_PS_PATHNAME == "/store/about.html" || G_PS_PATHNAME == "/store/awards.html"
		 || G_PS_PATHNAME == "/store/corporate.html" || G_PS_PATHNAME == "/store/companyhistory.html"
		 || G_PS_PATHNAME == "/store/news.html" || G_PS_PATHNAME.search(/\/faq/gi)>=0
		 || G_PS_PATHNAME == "/store/siteindex.html" || G_PS_PATHNAME == "/shop/designassist.html")
	{
		var end = G_PS_PATHNAME.lastIndexOf(".");
		end = (end < 0 ? G_PS_PATHNAME.length : end);
		pageId = G_PS_PATHNAME.substring(G_PS_PATHNAME.lastIndexOf("/")+1, end);
		G_PS_CUR_CATID = "CONTENT";
	}
	else if (G_PS_PATHNAME == "/shop/login.html")
	{
		pageId = "LOGIN";
		G_PS_CUR_CATID = "MY ACCOUNT";
		// Hijack logging in
		psHijackRegSubmission();
	}
	else if (G_PS_PATHNAME == "/shop/billing.html")
	{
		pageId = "BILLING";
		G_PS_CUR_CATID = "SHOPPING CART";
		// Hijack udpating profile
		psHijackRegSubmission();
	}
	else if (G_PS_PATHNAME == "/shop/shipping.html" || G_PS_PATHNAME == "/shop/delivery.html"
		|| G_PS_PATHNAME == "/shop/addshipping.html" || G_PS_PATHNAME == "/shop/payment.html")
	{
		pageId = G_PS_PATHNAME.substring(G_PS_PATHNAME.lastIndexOf("/")+1, G_PS_PATHNAME.lastIndexOf("."));
		G_PS_CUR_CATID = "SHOPPING CART";
		// Persist order info to cookie
		if (G_PS_PATHNAME == "/shop/payment.html")
		{
			var ord = new psOrder();
			ord.writeOrder();
		}
	}
	else if (pageId == null) // catch-all exception case
	{
		pageId = G_PS_PATHNAME;
		G_PS_CUR_CATID = "ADD PAGE TO CM TAG LIB";
	}
	//
	// Persist current catId (to be used in product page for items navigated from exceptional page)
	if (G_PS_PATHNAME == "/shop/sale.html" || G_PS_PATHNAME == "/retailbestsellers.html" 
		|| (G_PS_PATHNAME.search(/\/whatsnew.html/gi)>=0))
	{
		psSetCookie(G_PS_COOKIE_CATID, G_PS_CUR_CATID);
	}

	//
	// Throw pageview at last
	psCreatePageviewTag(pageId, G_PS_CUR_CATID, null, null); // Other pages go to "ADD URL" category
	if (G_PS_PATHNAME == "/shop/catalog.html")
	{
		cmCreateConversionEventTag("CATALOG REQUEST", "1", "REQUEST A CATALOG", "10");
	}
	if (G_PS_PATHNAME == "/shop/catalogdownload.html")
	{
		cmCreateConversionEventTag("CATALOG REQUEST", "2", "REQUEST A CATALOG", "90");
	}
}

/*
 * Extract general pageId from source code with the rule:
 *  - In case the source code contains only one "highlight" span element, that's the top menu. 
 * PageId then is the inner text of the span
 *	- In case the source code contains 2 "highlight" span elements, that's the sub menu. PageId
 * then is first element + ":" + second element
 */
function psGetPageId()
{
	var pageId = null;
	var classes = psGetElementsByClass("highlight", null);
	if (classes.length == 1) // top menu highlighted
		pageId = psGetInnerText(classes[0]);
	else if (classes.length == 2) // sub menu highlighted
		pageId = psGetInnerText(classes[0]) + ":" + psGetInnerText(classes[1]);

	return pageId;
}

/*
 * Get catId for general page view
 */
function psGetCatId()
{
	var catId = null;
	if (psGetCookie(G_PS_COOKIE_FLAG) == "search")
		catId = "search";				
	else
	{
		var classes = psGetElementsByClass("highlight", null);
		if (classes.length > 0)
			catId = psGetInnerText(classes[0]); // always get the first 
		else
		{
			catId = psGetCookie(G_PS_COOKIE_CATID);
			catId = (catId == null ? "BOOKMARK" : catId);
		}
	}
	return catId;
}

/*
 * Sign-in, account registration page?
 */
function psIsLoginPage()
{
	var result = (G_PS_PATHNAME == "/shop/login.html");

	return result;
}

/*
 * Hijack login page
 */
function psHijackRegSubmission()
{
	// Clear flag before flagging
	var flag = psGetCookie(G_PS_COOKIE_FLAG);
	if (flag == "sign-in" || flag == "update")
		psSetCookie(G_PS_COOKIE_FLAG, "");
	// Login page
	if (document.signIn != null)
	{
		document.signIn.oldCMFunc = document.signIn.onsubmit;
		document.signIn.onsubmit = function()
		{
			var uP = new psProfile();
			if (uP.writeLogin())
			{
				// Flag sign-in
				psSetCookie(G_PS_COOKIE_FLAG, "sign-in");
			}
			if (document.signIn.oldCMFunc != null)
				return document.signIn.oldCMFunc();
		}
	}
	// Account update page (billing page)
	var count = 0;
	for (var i = 0; i < document.images.length; i++)
	{
		if (document.images[i].src.search(/\/shoppingcart\/billingaddress.jpg/gi)>=0
			|| document.images[i].src.search(/\/shoppingcart\/diffaddress.jpg/gi)>=0)
		{
			count = count + 1;
			document.images[i].oldCMFunc = document.images[i].onclick;
			document.images[i].onclick = function()
			{
				var uP = new psProfile();
				if (uP.writeUpdate())
				{
					// Flag sign-in
					psSetCookie(G_PS_COOKIE_FLAG, "update");
				}
				if (this.oldCMFunc != null)
					return this.oldCMFunc();
			}
		}
		if (count >= 2)
			break;
	}
}

/*
 * Process to post registration tag
 */
function psPostRegistrationTag()
{
	var uP = new psProfile();
	if (uP.readProfile())
	{
		var flag = psGetCookie(G_PS_COOKIE_FLAG);
		if (flag == "sign-in")
		{
			psCreateRegistrationTag(uP.email, uP.email); // Post reg tag for sign-in
			// Clear flag
			psSetCookie(G_PS_COOKIE_FLAG, "");
		}
		else if (flag == "update")
		{
			// Post reg tag for udpate profile
			psCreateRegistrationTag(uP.email, uP.email, uP.city, uP.state, uP.zipcode, uP.newsletter, uP.subscribe);
			// Clear flag
			psSetCookie(G_PS_COOKIE_FLAG, "");
		}
	}
}


/*====================== END TAGGING BUSSINESS LOGIC =========================*/


/*======================= GENERAL UTILITY FUNCTION ===========================*/
/* PURPOSE: constructor for product
 * Note: you can add more methods to psProduct in its prototype
 * RETURN: none
 */
function psProduct()
{
    this.id = null;
    this.name = null;
    this.catId = null;
    this.price = null;
    this.quantity = null;

	/*
	 * Reset all member variables
	 */
	this.reset = function()
	{
		this.id = null;
		this.name = null;
		this.catId = null;
		this.price = null;
		this.quantity = null;
	}
	/*
	 * Extracting product info from source code for posting productview tag
	 */
	this.getProduct = function()
	{
		try
		{
			this.reset();
			this.id = psGetValueFromUrl(G_PS_QUERYSTRING, "product_ID").toUpperCase();
			if (document.frmAddProductSelect != null)
			{
				var tbls = document.frmAddProductSelect.getElementsByTagName("table");
				for (var i = 0; i < tbls.length; i++)
				{
					for (var r = 0; r < tbls[i].rows.length; r++)
					{
						for (var c = 0; c < tbls[i].rows[r].cells.length; c++)
						{
							if (tbls[i].rows[r].cells[c].innerHTML.toUpperCase().search(this.id)>=0)
							{
								this.name = tbls[i].rows[r].cells[c].innerHTML;
								this.name = this.name.substring(0, this.name.toUpperCase().indexOf("<BR"));
								break;
							}
						}
						if (this.name != null)
							break;
					}
					if (this.name != null)
						break;
				}
			}
			this.catId = psGetValueFromCookie(G_PS_COOKIE_PROD_CATID, this.id); // get catId from cookie for carted item
			this.catId = (this.catId == null || this.catId == "null" ? psGetCatId() : this.catId);

			return true;
		}
		catch (ex) { return false; }
	}
	/*
	 * Extracting product info from source code specified by the "current" row
	 * of items table in the shopping cart
	 */
	this.getItem5 = function(itemRow)
	{
		try
		{
			this.reset();
			var buff = itemRow.cells[1].innerHTML.split("item #");
			this.id = psTrim(buff[1].substring(0, buff[1].indexOf("-")));
			this.name = buff[0].substring(0, buff[0].toUpperCase().lastIndexOf("</TR>"));
			this.name = this.name.substring(this.name.lastIndexOf("<TD>")+4, this.name.lastIndexOf("</TD>"));
			// quantity
			this.quantity = itemRow.cells[3].getElementsByTagName("input");
			this.quantity = (this.quantity.length > 0 ? this.quantity[0].value : null);
			// price
			this.price = itemRow.cells[4].getElementsByTagName("input");
			this.price = (this.price.length > 0 ? this.price[0].value : null);
			// catId
			this.catId = psGetValueFromCookie(G_PS_COOKIE_PROD_CATID, this.id);
			// Hardcode to categorize exceptional items
			if (this.catId == null)
			{
				if (this.id == 67656)
					this.catId = "glass cube displays";
			}
			//
			// Persist shop9 items in pair (id, "quantity|price")
			psSetValueToCookie(G_PS_COOKIE_SHOP9, this.id, this.quantity + "|" + this.price);

			return true;
		}
		catch (ex) { return false; }
	}
	/*
	 * Extract product info from item (get back from cookie)
	 */
	this.getItem9 = function(item)
	{
		try
		{
			this.reset();
			var data = item.split("~");
			if (data.length >= 2)
			{
				this.id = data[0];
				data = data[1].split("|");
				this.name = null;
				this.quantity = data[0];
				this.price = data[1];			
				this.catId = psGetValueFromCookie(G_PS_COOKIE_PROD_CATID, this.id); // get catId from cookie G_PS_COOKIE_PROD_CATID
				// Hardcode to categorize exception items
				if (this.catId == null)
				{
					if (this.id == 67656)
						this.catId = "glass cube displays";
				}
			}
			return true;
		}
		catch (ex) {return false;}
	}
}

/* PURPOSE: constructor for profile
 * Note: you can add more methods to psProfile in its prototype
 * RETURN: none
 */
function psProfile()
{
    this.email = null;
    this.city = null;
    this.state = null;
    this.zipcode = null;
	this.newsletter = null;
	this.subscribe = null;
	/*
	 * Get user profile from cookie
	 */
	this.readProfile = function()
	{
		try
		{
			this.email = psGetCookie(G_PS_COOKIE_PROFILE);
			if (this.email != null)
			{
				var buf = this.email.split('|');
				for (var i=0; i<buf.length; i++)
				{
					var tempVal = buf[i];
					// when NULL is written to cookie, it becomes string, not literal constant
					buf[i] = (tempVal=="null" ? null : tempVal); 
				}
				this.email = buf[0];
				this.city = buf[1];
				this.state = buf[2];
				this.zipcode = buf[3];
				this.newsletter = buf[4];
				this.subscribe = buf[5];
			}
			return true;
		}
		catch (ex) { return false; }
	}
	/*
	 * Capture user account email as user logs in
	 */
	this.writeLogin = function()
	{
		try
		{
			this.email = document.getElementsByName("email");
			this.email = (this.email.length > 0 ? this.email[0].value : null);
			// persist profile
			return this.writeProfile();
		}
		catch (ex) { return false; }
	}
	/*
	 * Capture user account profile as user udpate the billing info
	 */
	this.writeUpdate = function()
	{
		try
		{
			this.email = document.getElementById("emailAddress");
			this.email = (this.email != null ? this.email.value : null);
			// city
			this.city = document.getElementById("city");
			this.city = (this.city != null ? this.city.value : null);
			// state
			this.state = document.getElementById("state");
			this.state = (this.state != null ? psTrim(this.state.options[this.state.selectedIndex].value) : null);
			// zipcode
			this.zipcode = document.getElementById("zipcode");
			this.zipcode = (this.zipcode != null ? this.zipcode.value : null);
			// persist profile
			return this.writeProfile();
		}
		catch (ex) { return false; }
	}
	/*
	 * Set user profile to cookie
	 */
	this.writeProfile = function()
	{
		try
		{
			if (this.email == null)
				return false;
			// make sure that the data contains 4 parts separated by 3 '|'
			var data = this.email + '|' + this.city + '|' + this.state + '|' + this.zipcode
				 + '|' + this.newsletter + '|' + this.subscribe;
			// store on cookie
			psSetCookie(G_PS_COOKIE_PROFILE, data);

			return true;
		}
		catch (ex) { return false; }
	}
}

/*
 * Order object encapsulates order Id, subtotal, shipping and customer Id
 * This design is aimed at code resuse and easy readability
 */
function psOrder()
{
	this.id = null;
	this.subtotal = "";
	this.shipping = "";
	/*
	 * get order info from source code
	 */
	this.getOrder = function()
	{
		try
		{
			this.id = document.body.innerHTML.toUpperCase().split("YOUR ORDER NUMBER IS")[1];
			this.id = psTrim(this.id.substring(0, this.id.indexOf("<")));
			var order = psGetCookie(G_PS_COOKIE_ORDER);
			order = (order != null ? order.split("~") : null);
			if (order != null)
			{
				this.subtotal = order[0];
				this.shipping = order[1];
			}
			return true;
		}
		catch (ex) {return false;}
	}
	/*
	 * Capture order info to persist to cookie
	 */
	this.writeOrder = function()
	{
		this.subtotal = document.getElementById("subTotal");
		this.subtotal = (this.subtotal != null ? psGetInnerText(this.subtotal).replace("$", "") : null);
		// shipping
		this.shipping = document.body.innerHTML.toUpperCase().split("SHIPPING AND HANDLING")[1];
		this.shipping = this.shipping.split("$")[1];
		this.shipping = this.shipping.substring(0, this.shipping.indexOf("<"));
		// Persist order info to cookie
		psSetCookie(G_PS_COOKIE_ORDER, this.subtotal + "~" + this.shipping, G_PS_COOKIE_LIFETIME);
	}
}

/* PURPOSE: Compare case-insensitive strings
 * RETURN: true: strings are not null and the same
 *         false: any of the string is null or not the same
 */

function psIsEqual()
{
	for (var i=0; i<arguments.length; i++)
	{
		if(arguments[0] == null || arguments[i] == null)
		{
			return false;
		}
		else if(arguments[0].toUpperCase() != arguments[i].toUpperCase())
		{
			return false;
		}
	}
	return true;
}

/* PURPOSE: Get inner text of an object or remove html tags of a particular string
 *          work properly even when the designated tag/text has script tag inside
 * RETURN: resultant string or null object
 */
function psGetInnerText(pTagOjb){
	var pattern = /<script[\s\S]*?<\/script>/gi; // question mark means non-greedy
	if (pTagOjb != null)
	{
		var sT = (typeof(pTagOjb) == "object") ? pTagOjb.innerHTML : pTagOjb;
		// remove all script tags and its content
		while (sT.search(pattern) > -1)
		{
			sT = sT.replace(pattern, "");
		}
		return sT.replace(/\<+.+?\>+/g, "");
	}
	return null;
}

/* PURPOSE: Remove all unaccepted characters in categoryid, including
 * [, ', ", :, comma,]
 * RETURN: string
 */
function psCleanCatId(pCatId)
{
    return (pCatId != null) ? pCatId.replace(/[\'\":,]\™\®/g, "") : null;
}

function psCleanPageId(pPageId)
{
	return (pPageId != null) ? pPageId.replace(/[\n\t\v\r’\'\"]\™\®/gi, "") : null; 
}

function psCleanProductName(pProductName)
{
	return (pProductName != null) ? pProductName.replace(/[\n\t\v\r’\'\"]\™\®/gi, "") : null; 
}

/* PURPOSE: Remove all leading & trailing spaces of a string
 * Note: [&nbsp;] is also considered as a space
 * RETURN: string
 */
function psTrim(pStr)
{
	if (pStr == null || typeof(pStr) != "string")
		return pStr;
	return (pStr != null) ? pStr.replace(/&nbsp;|\u00A0/gi, ' ').replace(/^\s+|\s+$/g, '') : null;
}
/* PURPOSE: extract value from the URL
 * in format of http://xxx.com/page.ext?key1=value1&key2=value2
 * or key1=value1&key2=value2
 * RETURN: string value of the parameter
 */
function psGetValueFromUrl(pUrl, pKey)
{
	pUrl = (pUrl != null) ? "?" + psTrim(pUrl.toLowerCase()) : null;
	pKey = (pKey != null) ? psTrim(pKey.toLowerCase()) : null;

	if (pUrl == null || pKey == null || pUrl.indexOf(pKey) == -1) 
		return null;
	
	var start = pUrl.indexOf('&' + pKey + '=');
	start = (start == -1) ? pUrl.indexOf('?' + pKey + '=') : start;
	if (start >= 0)
	{
		start = start + pKey.length;
		var end = pUrl.indexOf("&", start);
		if(end == -1) 
			end = pUrl.length;
		var middle = pUrl.indexOf("=", start);
		return pUrl.substring(middle + 1, end);
	}
	return null;
}

/*
 * Return the first element encountered by the class name
 */
function psGetElementsByClass(pClassName, node)
{
	if (node == null)
		node = document;
	var allPageTags = node.getElementsByTagName("*");
	var elements = new Array();
	for (var k = 0; k < allPageTags.length; k++)
	{
		if (allPageTags[k].className.toLowerCase() == pClassName.toLowerCase())
			elements.push(allPageTags[k]);
	}
	return elements;
}

/* PURPOSE: convert special HTML characters to normal character
 * Note: for each project, this function needs to be updated
 * RETURN: decoded string
 */
function psHtmlDecode(pValue)
{
    if (pValue)
    {
        pValue = pValue.replace(/&nbsp;/gi, " ");
        pValue = pValue.replace(/&quot;/gi, '"');
        pValue = pValue.replace(/&amp;/gi, "&");
        pValue = pValue.replace(/&lt;/gi, "<");
        pValue = pValue.replace(/&gt;/gi, ">");
    }

    return pValue;
}

/* PURPOSE: extract domain part in the URL
 * RETURN: domain
 */
function psGetDomain(pUrl){
    var se = /^https*\:\/\/([^\/]+)/gi;
    return (pUrl.search(se) > -1) ? RegExp.$1 : null;
}

/* PURPOSE: remove unnecessary characters (dollar sign, comma, quote, minus, etc) 
 * from price to make it work properly with parseFloat/parseInt
 * RETURN: well-formed price
 */
function psCleanPrice(pPrice)
{
	var pattern = /[^0-9\.]/gi;
    return (pPrice != null ? pPrice.toString().replace(pattern, "") : null);
}

/* PURPOSE: retrieve cookie value
 * RETURN: string
 */
function psGetCookie(pCookieName)
{
	var cookies = document.cookie;
	if (!pCookieName || !cookies)
		return null;

	cookies = "; " + cookies.toLowerCase();
	var key = "; " + pCookieName.toLowerCase() + "=";
	var start = cookies.lastIndexOf(key);
	if (start >= 0)
	{
		start = start + key.length;
		var end = cookies.indexOf(";", start);
		if (end == -1)
			end = cookies.length;

		return unescape(cookies.substring(start, end));
	}

    return null;
}

/* PURPOSE: set cookie value
 * Note: if the designated cookie is too big, the old items will be removed
 * because cookie size is limited to 4K
 * @pLifeTime in seconds
 * pDomain: don't specify if using current domain
 * RETURN: boolean
 */
function psSetCookie(pCookieName, pCookieValue, pLifeTime, pDomain)
{
    if (!pCookieName)
		return false;

	if(pLifeTime == "delete") 
    {         
        CC(pCookieName, pDomain);//delete cookie by calling coremetrics's cookie function
        return true;
    }
    // set cookie by calling coremetrics's cookie function
    var expire = (pLifeTime) ? (new Date((new Date()).getTime() + (1000 * pLifeTime))).toGMTString() : null;
    
    return CB(pCookieName, escape(pCookieValue), expire, pDomain);
}

/* PURPOSE: set value in cookie in format of:
 * #key1~value1#key2~value2
 * RETURN: string
 * NOTE: Use null or '' for pValue to remove the pair specified by pKey
 */
function psSetValueToCookie(pCookieName, pKey, pValue)
{
	// "normalize" input parameters
	pCookieName = psTrim(pCookieName);
	pKey = (pKey != null) ? "#" + psTrim(pKey).toLowerCase() + "~" : pKey;
	// 
	var catCookie = psGetCookie(pCookieName);
	catCookie = (catCookie == null) ? "" : catCookie;

	var start = catCookie.indexOf(pKey);
	if (start >= 0) // Store before -> remove the old value
	{
		var end = catCookie.indexOf("#", start + pKey.length);
		if (end == -1)
			end = catCookie.length;
		catCookie = catCookie.replace(catCookie.substring(start, end), "");
	}
	
	// remove the last items (eldest items) until cookie size < 3500	
	if (pValue != null && pValue != '')
	{
		catCookie = pKey + pValue + catCookie;

		var cookieArray = null;
		while (catCookie.length > 3500)
		{
			cookieArray = catCookie.split("#");
			cookieArray.pop();
			catCookie = cookieArray.join("#");
		}
	}
	// Save to cookie
	psSetCookie(pCookieName, catCookie, G_PS_COOKIE_LIFETIME);
}

/* PURPOSE: get value stored in cookie in format of:
 * #key1~value1#key2~value2
 * RETURN: string
 */
function psGetValueFromCookie(pCookieName, pKey)
{
	// "normalize" input parameters
	pCookieName = psTrim(pCookieName);
	pKey = (pKey != null) ? "#" + psTrim(pKey).toLowerCase() + "~" : pKey;
	// extract catId associated with the specified key (pKey)
    var catCookie = psGetCookie(pCookieName);
    if (catCookie != null)
    {
        var start = catCookie.indexOf(pKey);
		if (start >=0 )
		{
			start = start + pKey.length;
			var end = catCookie.indexOf("#", start);
			if (end == -1)
				end = catCookie.length;
			return catCookie.substring(start, end);
		}
		return null;
    }
    return null;
}

/********************************************************/
/* WRAPPER FOR COREMETRICS' TAG FUNCTIONS               */
/********************************************************/
function psCreatePageviewTag(pId, pCatId, pSrchTerm, pSrchResult) 
{
	pId = psCleanPageId(pId);
	pCatId = psCleanCatId(pCatId);
    if (pSrchResult != null)
        pSrchResult += "";
    if (G_PS_DEBUG_MODE == 1 || G_PS_DEBUG_MODE == 3)
        alert("cmCreatePageviewTag(" + pId + ", " + pCatId + ", " + pSrchTerm + ", " + pSrchResult + ")");
    if (G_PS_DEBUG_MODE == 2 || G_PS_DEBUG_MODE == 3)
        cmCreatePageviewTag(pId, pCatId, pSrchTerm, pSrchResult);
}

function psCreateProductviewTag(pId, pName, pCatId) 
{
	pName = psCleanProductName(pName);
	pCatId = psCleanCatId(pCatId);
    if (G_PS_DEBUG_MODE == 1 || G_PS_DEBUG_MODE == 3)
        alert("cmCreateProductviewTag(" + pId + ", " + pName + ", " + pCatId + ")");
    if (G_PS_DEBUG_MODE == 2 || G_PS_DEBUG_MODE == 3)
        cmCreateProductviewTag(pId, pName, pCatId);
}

function psCreateShopAction5Tag(pId, pName, pQuantity, pPrice, pCatId) 
{
	pName = psCleanProductName(pName);
	pCatId = psCleanCatId(pCatId);
	pQuantity = psCleanPrice(pQuantity);
	pPrice = psCleanPrice(pPrice);
    if (G_PS_DEBUG_MODE == 1 || G_PS_DEBUG_MODE == 3)
        alert("cmCreateShopAction5Tag(" + pId + ", " + pName + ", " + pQuantity + ", " + pPrice + ", " + pCatId + ")");
    if (G_PS_DEBUG_MODE == 2 || G_PS_DEBUG_MODE == 3)
        cmCreateShopAction5Tag(pId, pName, pQuantity, pPrice, pCatId);    
}

function psCreateShopAction9Tag(pId, pName, pQuantity, pPrice, pCusID, pOrderID, pOrderTotal, pCatId) 
{
	pName = psCleanProductName(pName);
	pCatId = psCleanCatId(pCatId);
	pQuantity = psCleanPrice(pQuantity);
	pPrice = psCleanPrice(pPrice);
	pOrderTotal = psCleanPrice(pOrderTotal);
    if (G_PS_DEBUG_MODE == 1 || G_PS_DEBUG_MODE == 3)
        alert("cmCreateShopAction9Tag(" + pId + ", " + pName + ", " + pQuantity + ", " + pPrice + ", " + pCusID + ", " + pOrderID + ", " + pOrderTotal + ", " + pCatId + ")");
    if (G_PS_DEBUG_MODE == 2 || G_PS_DEBUG_MODE == 3)
        cmCreateShopAction9Tag(pId, pName, pQuantity, pPrice, pCusID, pOrderID, pOrderTotal, pCatId);
}

function psCreateOrderTag(pId, pOrderTotal, pOrderShipping, pCusID, pCusCity, pCusState, pCusZip) 
{
	pOrderTotal = psCleanPrice(pOrderTotal);
	pOrderShipping = psCleanPrice(pOrderShipping);
    if (G_PS_DEBUG_MODE == 1 || G_PS_DEBUG_MODE == 3)
        alert("cmCreateOrderTag(" + pId + ", " + pOrderTotal + ", " + pOrderShipping + ", " + pCusID + ", " + pCusCity + ", " + pCusState + ", " + pCusZip + ")");
    if (G_PS_DEBUG_MODE == 2 || G_PS_DEBUG_MODE == 3)
        cmCreateOrderTag(pId, pOrderTotal, pOrderShipping, pCusID, pCusCity, pCusState, pCusZip);
}

function psCreateConversionEventTag(pId, pActionType, pCatID, pPoints) 
{
	pCatID = psCleanCatId(pCatID);
    if (G_PS_DEBUG_MODE == 1 || G_PS_DEBUG_MODE == 3)
        alert("cmCreateConversionEventTag(" + pId + ", " + pActionType + ", " + pCatID + ", " + pPoints + ")");
    if (G_PS_DEBUG_MODE == 2 || G_PS_DEBUG_MODE == 3)
        cmCreateConversionEventTag(pId, pActionType, pCatID, pPoints);
}

function psCreateRegistrationTag(pCusID, pCustEmail, pCusCity, pCusState, pCusZip, pNewsletter, pSubscribe) 
{
    if (G_PS_DEBUG_MODE == 1 || G_PS_DEBUG_MODE == 3)
        alert("cmCreateRegistrationTag(" + pCusID + ", " + pCustEmail + ", " + pCusCity + ", " + pCusState + ", " + pCusZip + ", " + pNewsletter + ", " + pSubscribe + ")");
    if (G_PS_DEBUG_MODE == 2 || G_PS_DEBUG_MODE == 3)
        cmCreateRegistrationTag(pCusID, pCustEmail, pCusCity, pCusState, pCusZip, pNewsletter, pSubscribe);
}

function psCreateErrorTag(pPageID, pCatId) 
{
	pPageID = psCleanPageId(pPageID);
	pCatId = psCleanCatId(pCatId);
    if (G_PS_DEBUG_MODE == 1 || G_PS_DEBUG_MODE == 3)
        alert("cmCreateErrorTag(" + pPageID + ", " + pCatId + ")");
    if (G_PS_DEBUG_MODE == 2 || G_PS_DEBUG_MODE == 3)
        cmCreateErrorTag(pPageID, pCatId);
}

function psDisplayShop5s()
{
    if (G_PS_DEBUG_MODE == 1 || G_PS_DEBUG_MODE == 3)
        alert("cmDisplayShop5s()");
    if (G_PS_DEBUG_MODE == 2 || G_PS_DEBUG_MODE == 3)
        cmDisplayShop5s();
}

function psDisplayShop9s()
{
    if (G_PS_DEBUG_MODE == 1 || G_PS_DEBUG_MODE == 3)
        alert("cmDisplayShop9s()");
    if (G_PS_DEBUG_MODE == 2 || G_PS_DEBUG_MODE == 3)
        cmDisplayShop9s();
}
/*===========================END GENERAL UTILITY FUNCTION ==================*/