/************************************************************************************/
/* $Revision: $
 * $Id: $
 *
 * Author: Coremetrics/PSD 
 * Coremetrics  v3.0, 01/16/2009
 * 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_URL_REFERRER = document.referrer.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_PROD_NAME = "PS_PROD_NAME";
var G_PS_COOKIE_PROFILE = "PS_PROFILE";
var G_PS_COOKIE_FLAG = "PS_FLAG";		// used as a "session" variable to handle events between pages
var G_PS_COOKIE_PREFIX = "PS_PREFIX";
// current category ID while browsing/searching/refining, etc
var G_PS_CUR_CATID = null;
var G_PS_ARR_DOMAIN = ["shopfujifilm.com"];//value must be one array of domains or null
/*========================= END GLOBAL VARIABLES =============================*/

/*=========================== BEGIN NAVIGATION ===============================*/
// Navigation logic should go here!
psHijackSearch();
psHijackLeftMenu();
if(G_PS_PATHNAME == "/" || G_PS_PATHNAME == "/index.asp")
{
	psCreatePageviewTag("Home","Home",null,null);
	psSetCookie(G_PS_COOKIE_CATID,"Home");
	psHijackAddToCart("Home");
}
else if(G_PS_PATHNAME == "/customer_care.asp")
{
	psCreatePageviewTag("customer_care","customer_care",null,null);
	psSetCookie(G_PS_COOKIE_PREFIX,"customer_care_");
}
else if(G_PS_PATHNAME == "/cat_digcam.asp")
{
	var prefix = "";
	var flag = psGetCookie(G_PS_COOKIE_FLAG);
	if(psIsEqual(flag,"true"))
	{
		prefix = psGetCookie(G_PS_COOKIE_PREFIX);
		prefix = (psIsEqual(prefix,"site_map_"))? prefix:"";
	}
	psCreatePageviewTag("cat_digcam",prefix + "digcam",null,null);
	psSetCookie(G_PS_COOKIE_PREFIX,"","delete");
	psHijackDigCam();
}
else if(G_PS_PATHNAME == "/3d-tech.asp")   // added 9/25/09 WBIRD
{
 var prefix = "";
 var flag = psGetCookie(G_PS_COOKIE_FLAG);
 if(psIsEqual(flag,"true"))
 {
  prefix = psGetCookie(G_PS_COOKIE_PREFIX);
  prefix = (psIsEqual(prefix,"site_map_"))? prefix:"";
 }
 psCreatePageviewTag("3d-tech",prefix + "3d-tech",null,null);
 psSetCookie(G_PS_COOKIE_PREFIX,"","delete");
 psHijackDigCam(); // same page DOM as DigCam
}

else if(G_PS_PATHNAME == "/cc_privacy.asp")
{
	var prefix = psGetCookie(G_PS_COOKIE_PREFIX);
	prefix = (prefix==null)? "customer_care_":prefix;
	psCreatePageviewTag("cc_privacy",prefix + "SAFETY PRIVACY & EMAIL",null,null);
}
else if(G_PS_PATHNAME == "/cc_promotions.asp")
{
	var prefix = psGetCookie(G_PS_COOKIE_PREFIX);
	prefix = (prefix==null)? "customer_care_":prefix;
	psCreatePageviewTag("cc_promotions",prefix + "ORDERING & PAYMENT",null,null);
}
else if(G_PS_PATHNAME == "/ordertrack.asp")
{
	psCreatePageviewTag("ordertrack","Order Tracking",null,null);
}
else if(G_PS_PATHNAME == "/cc_trackship.asp")
{
	psCreatePageviewTag("cc_trackship","cc_trackship",null,null);
	psSetCookie(G_PS_COOKIE_PREFIX,"order_tracking_");
}
else if(G_PS_PATHNAME == "/site_map.asp")
{
	psCreatePageviewTag("site_map","site_map",null,null);
	psSetCookie(G_PS_COOKIE_CATID,"site map");
	psSetCookie(G_PS_COOKIE_PREFIX,"site_map_");
}
else if(G_PS_PATHNAME == "/shoppingcart.asp")
{
	psPostCartView();
	psHijackAlsoConsider();
	psHijackShoppingCart();
}
else if(G_PS_PATHNAME == "/v30/checkout.asp")
{
	if(psIsEqual(psGetDomain(G_PS_URL_REFERRER), psGetDomain(G_PS_URL_PATH))
		&& G_PS_URL_REFERRER.indexOf("/v30/login.asp")>-1 && psCheckLogin())
	{
		var profile = new psProfile();
		profile.readProfile();
		psCreateRegistrationTag(profile.email,profile.email,profile.city,profile.state,profile.zipcode,profile.newsletter,profile.subscribe);
	}
	psCreatePageviewTag("checkout","checkout",null,null);
	psHijackCheckout();
}
else if(G_PS_PATHNAME == "/v30/login.asp")
{
	psCreatePageviewTag("login","login",null,null);
	psHijackLogin();
}
else if(G_PS_PATHNAME == "/v30/qas_search.asp")
{
	psCreatePageviewTag("qas_search","checkout",null,null);
}
else if(G_PS_PATHNAME == "/v30/preview.asp")
{
	var profile = new psProfile();
	profile.readProfile();
	psCreateRegistrationTag(profile.email,profile.email,profile.city,profile.state,profile.zipcode,profile.newsletter,profile.subscribe);
	psCreatePageviewTag("preview","checkout",null,null);
}
else if(G_PS_PATHNAME == "/v30/final.asp")
{
	psPostOrderView();
}
else if(G_PS_PATHNAME == "/v30/error.asp")
{
	psCreatePageviewTag("error","checkout",null,null);
}
else if(G_PS_PATHNAME == "/tech.asp")
{
	var prefix = "";
	var flag = psGetCookie(G_PS_COOKIE_FLAG);
	if(psIsEqual(flag,"true"))
	{
		prefix = psGetCookie(G_PS_COOKIE_PREFIX);
		prefix = (psIsEqual(prefix,"site_map_"))? prefix:"";
	}
	psCreatePageviewTag("tech",prefix + "tech",null,null);
	psSetCookie(G_PS_COOKIE_PREFIX,"","delete");
}
else if(G_PS_PATHNAME.indexOf("/cc_")>-1)
{
	psPostCusCareView();
}
else if(G_PS_PATHNAME.toUpperCase().indexOf("PRODUCT_LIST.ASP")>-1)
{
	psPostSearchView();
}
else if(G_PS_URL_PATH.indexOf("/detail/")>-1)
{
	if(psIsNoProduct())
	{
		psCreatePageviewTag("No Product","Product View",null,null);
	}
	else
	{
		var prd = new psProduct();
		if (prd.getProduct()) // Get product info successfully?
			psCreateProductviewTag(prd.id, prd.name, prd.catId);
		psHijackRelatedAcc();
	}
}
else 
{
	psPostPageView();
}

function psIsNoProduct()
{
	var strList = document.getElementsByTagName("strong");
	for(var i = 0; i < strList.length; i++ )
	{
		if(psIsEqual(psGetInnerText(strList[i]),"Sorry, the item you are looking for is not available."))
		{
			return true;
		}
	}
	return false;
}

/*============================ END NAVIGATION ================================*/


/*===================== BEGIN TAGGING BUSSINESS LOGIC ========================*/
function psHijackLeftMenu()
{
	var divItem = document.getElementById("side_nav");
	if(divItem != null)
	{
		var aList = divItem.getElementsByTagName("a");
		for(var i=0;i<aList.length;i++)
		{
			aList[i].oldCMF = aList[i].onclick;
			aList[i].onclick = function()
			{
				psSetCookie(G_PS_COOKIE_FLAG,"true");
				if(this.oldCMF != null)
				{
					return this.oldCMF();
				}
			}
		}
	}
}

function psCheckLogin()
{
	var inputItem = document.getElementsByName("Ecom_BillTo_Online_Email")[0];
	var email = psGetElementValue(inputItem,false);
	if(email==null || email == "")
	{
		return false;
	}
	return true;
}

function psHijackDigCam()
{
	var divList = document.getElementsByTagName("div");
	var divSeries = new Array();
	for(var i=0;i<divList.length;i++)
	{
		if(psIsEqual(divList[i].className,"series"))
		{
			divSeries.push(divList[i]);
		}
	}
	for(var i=0;i<divSeries.length;i++)
	{
		var aList = divSeries[i].getElementsByTagName("a");
		for(var j=0;j<aList.length;j++)
		{
			aList[j].oldCMF = aList[j].onclick;
			aList[j].onclick = function()
			{
				var parent = this.parentNode;
				while(!(psIsEqual(parent.tagName,"div") && psIsEqual(parent.className,"series")))
				{
					parent = parent.parentNode;
				}
				divList = parent.getElementsByTagName("div");
				var catId = null;
				for(var k=0;k<divList.length;k++)
				{
					if(psIsEqual(divList[k].className,"series_title"))
					{
						catId = psGetInnerText(divList[k]);
						break;
					}
				}
				psSetCookie(G_PS_COOKIE_CATID,catId);
				if(this.oldCMF != null)
				{
					this.oldCMF();
				}
			}
		}
	}
}

function psHijackSearch()
{
	var divItem = document.getElementById("go");
	if(divItem != null)
	{
		var inputList = divItem.getElementsByTagName("input");
		for(var i = 0; i < inputList.length; i++ )
		{
			if(psIsEqual(inputList[i].alt,"go"))
			{
				inputList[i].oldCMFunc = inputList[i].onclick;
				inputList[i].onclick = function()
				{
					psSetCookie(G_PS_COOKIE_CATID,"Search");
					if(this.oldCMFunc != null)
					{
						this.oldCMFunc();
					}
				}
				break;
			}
		}
	}
}

function psHijackShoppingCart()
{
	var tbl = document.getElementById("cart");
	if(tbl != null)
	{
		var aList = tbl.getElementsByTagName("a");
		for(var i = 0; i < aList.length; i++ )
		{
			if(aList[i].href.toLowerCase().indexOf("/detail/")>-1)
			{
				aList[i].oldCMFunc = aList[i].onclick;
				aList[i].onclick = function()
				{
					psSetCookie(G_PS_COOKIE_CATID,"Shopping cart");
					if(this.oldCMFunc != null)
					{
						this.oldCMFunc();
					}
				}
			}
		}
	}
}

function psHijackAddToCart(catId)
{
	var aList = document.getElementsByTagName("a");
	for(var i = 0; i < aList.length; i ++ )
	{
		if(aList[i].href.toLowerCase().indexOf("addtocart.asp")>-1)
		{
			aList[i].oldCMFunc = aList[i].onclick;
			aList[i].onclick = function()
			{
				var prodId = this.href;
				var se = /http\:\/\/(www\.)?shopfujifilm\.com\/addtocart\.asp\?T1\=FUJ\s*\+\s*([\w*\d*-]*[\w*\d*])/gi;
				prodId = (prodId.search(se)>-1)? RegExp.$2:prodId;
				psSetValueToCookie(G_PS_COOKIE_PROD_CATID,prodId,catId);
				if(this.oldCMFunc != null)
				{
					this.oldCMFunc();
				}
			}
		}
	}
}

function psHijackAlsoConsider()
{
	var divItem = document.getElementById("upsell");
	if(divItem != null)
	{
		var aList = divItem.getElementsByTagName("a");
		for(var i = 0; i < aList.length; i ++ )
		{
			aList[i].oldCMFunc = aList[i].onclick;
			if(psIsEqual(aList[i].className,"upsell_img"))
			{
				aList[i].onclick = function()
				{
					psSetCookie(G_PS_COOKIE_CATID,"Also Consider");
					if(this.oldCMFunc != null)
					{
						this.oldCMFunc();
					}
				}
			}
			else
			{
				aList[i].onclick = function()
				{
					var prodId = this.href;
					var se = /http\:\/\/(www\.)?shopfujifilm\.com\/addtocart\.asp\?T1\=FUJ\s*\+\s*([\w*\d*-]*[\w*\d*])/gi;
					prodId = (prodId.search(se)>-1)? RegExp.$2:prodId;
					psSetValueToCookie(G_PS_COOKIE_PROD_CATID,prodId,"Also Consider");
					if(this.oldCMFunc != null)
					{
						this.oldCMFunc();
					}
				}
			}
		}
	}
}

function psHijackRelatedAcc()
{
	var divItem = document.getElementById("upsell");
	if(divItem != null)
	{
		var aList = divItem.getElementsByTagName("a");
		for(var i = 0; i < aList.length; i ++ )
		{
			aList[i].oldCMFunc = aList[i].onclick;
			aList[i].onclick = function()
			{
				psSetCookie(G_PS_COOKIE_CATID,"Related Accessories");
				if(this.oldCMFunc != null)
				{
					this.oldCMFunc();
				}
			}
		}
	}
}

function psPostPageView()
{
	var pageId = psGetPageName();
	var catId = psGetLastFolder();
	if(psIsEqual(catId,"category") || psIsEqual(catId,"products"))
	{
		var se = /\w*_(\w*)/gi;
		catId = (pageId.search(se)>-1)? RegExp.$1:catId;
		var prefix = "";
		var flag = psGetCookie(G_PS_COOKIE_FLAG);
		if(psIsEqual(flag,"true"))
		{
			prefix = psGetCookie(G_PS_COOKIE_PREFIX);
			prefix = (psIsEqual(prefix,"site_map_"))? prefix:"";
		}
		psCreatePageviewTag(pageId,prefix + catId,null,null);
		psSetCookie(G_PS_COOKIE_PREFIX,"","delete");
	}
	else
	{
		psCreatePageviewTag(pageId,catId,null,null);
	}
	psSetCookie(G_PS_COOKIE_CATID,pageId);
}

function psGetPageName()
{
	var se = /(\/\w*)*\/(\w*\.?\w*)/gi;
	var pageName = (G_PS_PATHNAME.search(se)>-1)? RegExp.$2:null;
	return pageName;
}


function psGetLastFolder()
{
	var se = /(\/\w*)*\/(\w*)\/\w*\.?\w*/gi;
	var lastFolder = (G_PS_PATHNAME.search(se)>-1)? RegExp.$2:null;
	return lastFolder;
}

function psHijackCheckout()
{
	var imgList = document.getElementsByTagName("img");
	var imgItem = null;
	for(var i = 0; i < imgList.length; i ++ )
	{
		if(psIsEqual(imgList[i].alt,"submit order"))
		{
			imgItem = imgList[i];
			break;
		}
	}
	if(imgItem != null)
	{
		imgItem.oldCMFunc = imgItem.onclick;
		imgItem.onclick = function()
		{
			var profile = new psProfile();
			profile.email = psGetElementValue(document.getElementsByName("Ecom_BillTo_Online_Email")[0],false);
			profile.city = psGetElementValue(document.getElementsByName("Ecom_BillTo_Postal_City")[0],false);
			profile.state = psGetElementValue(document.getElementsByName("Ecom_BillTo_Postal_StateProv")[0],true);
			profile.zipcode = psGetElementValue(document.getElementsByName("Ecom_BillTo_Postal_PostalCode")[0],false);
			profile.newsletter = "special offers and promotions from ShopFujiFilm.com";
			profile.subscribe = (document.getElementsByName("emailbox")[0]).checked ? "Y":"N";
			profile.writeProfile();
			if(this.oldCMFunc != null)
			{
				this.oldCMFunc();
			}
		}
	}
}

function psHijackLogin()
{
	var inputList = document.getElementsByTagName("input");
	var inputItem = null;
	for(var i = 0; i < inputList.length; i ++ )
	{
		if(psIsEqual(inputList[i].type,"image"))
		{
			inputItem = inputList[i];
			break;
		}
	}
	if(inputItem != null)
	{
		inputItem.oldCMFunc = inputItem.onclick;
		inputItem.onclick = function ()
		{
			var inputTemp = document.getElementsByName("email")[0];
			if(inputTemp != null)
			{
				var profile = new psProfile();
				profile.email = psGetElementValue(inputTemp,false);
				profile.writeProfile();
			}
			if(this.oldCMFunc != null)
			{
				this.oldCMFunc();
			}
		}
	}
}

function psPostCusCareView()
{
	var pageId = G_PS_PATHNAME.replace(/\/|.asp/gi,"");
	var catId = null;
	var h2List = document.getElementsByTagName("h2");
	var pTitle = psGetInnerText(h2List[0]);
	if(pTitle != null)
	{
		var divList = document.getElementsByTagName("div");
		var divItem = null;
		for(var i = 0; i < divList.length; i ++ )
		{
			if(psIsEqual(divList[i].className,"left-link-bar"))
			{
				divItem = divList[i];
				break;
			}
		}
		if(divItem != null)
		{
			var spanList = divItem.getElementsByTagName("span");
			var ulList = divItem.getElementsByTagName("ul");
			var cont = true;
			for(var i = 0; i < ulList.length; i ++ )
			{	
				var aList = ulList[i].getElementsByTagName("a");
				for(var j = 0; j < aList.length; j ++ )
				{
					if(psIsEqual(psTrim(psHtmlDecode(psGetInnerText(aList[j]))),psTrim(psHtmlDecode(pTitle))))
					{
						catId = (spanList.length>i)? psHtmlDecode(psGetInnerText(spanList[i])).toUpperCase():null;
						cont = false;
						break;
					}
				}
				if(!cont)
				{
					break;
				}
			}
			var prefix = psGetCookie(G_PS_COOKIE_PREFIX);
			prefix = (prefix==null)? "customer_care_":prefix;
			psCreatePageviewTag(pageId,prefix + catId,null,null);
		}
	}
}

function psPostSearchView()
{
	// Your logic of throwing pageview tag for search functionalities goes here
	G_PS_CUR_CATID = "SEARCH";
	var pageId = null;
	var sTerm = psGetValueFromUrl(G_PS_URL_PATH,"SEARCH");
	var sResult = 0;
	
	var h1List = document.getElementsByTagName("h1");
	if(psIsEqual(psGetInnerText(h1List[0]),"NO PRODUCTS FOUND"))
	{
		pageId = "SEARCH UNSUCCESSFUL";
	}
	else
	{
		pageId = "SEARCH SUCCESSFUL PAGE";
		var pageNo = psGetValueFromUrl(G_PS_URL_PATH,"PGN");
		pageNo = (pageNo == null)? 1:pageNo;
		pageId = pageId + " [" + pageNo + "]";
		
		var divList = document.getElementsByTagName("div");
		var divItem = null;
		for(var i = 0; i < divList.length; i ++ )
		{
			if(psIsEqual(divList[i].className,"PAGECOUNT_RANGE"))
			{
				divItem = divList[i];
				break;
			}
		}
		if(divItem != null)
		{
			sResult = psGetInnerText(divItem);
			var se = /showing\s*items\s*\d*\s*-\s*\d*\s*of\s*(\d*)/gi;
			sResult = (sResult.search(se)>-1)? RegExp.$1:sResult;
		}
	}
	
	if (pageId != null)
		psCreatePageviewTag(pageId, G_PS_CUR_CATID, sTerm, sResult);
	psSetCookie(G_PS_COOKIE_CATID,"Search");
}

/*
 * Process to post shop5tags for items in shopping cart
 */
function psPostCartView()
{
	// Throw page view tag
	psCreatePageviewTag("shoppingcart","shoppingcart",null,null);

	var cartTbl = document.getElementById("cart");
	if (cartTbl == null)
		return;

	var rows = cartTbl.rows; // use rows variable for optimization
	var prd = new psProduct();
	var indexProd = 0;
	for (var r = 0; r < rows.length; r++) // item for each row
	{
		var isProduct = false;
		for(var i=0; i<rows[r].cells.length; i++)
		{
			if(psIsEqual(rows[r].cells[i].className,"cart_prod"))
			{
				isProduct = true;
				break;
			}
		}
		if(isProduct)
		{
			indexProd++;
			if (prd.getItem5(rows[r],indexProd)) // Get shop5 item successfully?
				psCreateShopAction5Tag(prd.id, prd.name, prd.quantity, prd.price, prd.catId);
		}
	}
	// Make sure to have actual postings
	psDisplayShop5s();
}

/*
 * Process to post shop9tags for items purchased
 */
function psPostOrderView()
{
	// Throw page view tag
	psCreatePageviewTag("final","checkout",null,null);

	var cartTbl = null;
	var cellList = document.getElementsByTagName("td");
	var cellItem = null;
	for(var i=0; i<cellList.length; i++)
	{
		if(psIsEqual(psGetInnerText(cellList[i]),"Order Detail"))
		{
			cellItem = cellList[i];
			break;
		}
	}
	if(cellItem != null)
	{
		cartTbl = (cellItem.parentNode).parentNode;
	}
	
	if (cartTbl == null)
		return;

	var rows = cartTbl.rows; // use rows variable for optimization
	var ord = new psOrder();
	
	var profile = new psProfile();
	profile.readProfile();
	cellItem = null;
	for (var i=0; i<cellList.length; i++)
	{
		if(psIsEqual(psGetInnerText(cellList[i]),"Email Address:"))
		{
			cellItem = cellList[i];
			break;
		}
	}
	if(cellItem != null)
	{
		var rowItem = cellItem.parentNode;
		profile.email = psGetInnerText(rowItem.cells[2]);
	}
	cellItem = null;
	for (var i=0; i<cellList.length; i++)
	{
		if(psIsEqual(psGetInnerText(cellList[i]),"City:"))
		{
			cellItem = cellList[i];
			break;
		}
	}
	if(cellItem != null)
	{
		var rowItem = cellItem.parentNode;
		profile.city = psGetInnerText(rowItem.cells[2]);
	}
	cellItem = null;
	for (var i=0; i<cellList.length; i++)
	{
		if(psIsEqual(psGetInnerText(cellList[i]),"State/Zip:"))
		{
			cellItem = cellList[i];
			break;
		}
	}
	if(cellItem != null)
	{
		var rowItem = cellItem.parentNode;
		var state_zip = psGetInnerText(rowItem.cells[2]);
		var se = /(\w*)\/([\d*\-]*)/gi;
		profile.state = (state_zip.search(se)>-1)? RegExp.$1:state_zip;
		profile.zipcode = (state_zip.search(se)>-1)? RegExp.$2:state_zip;
	}
	
	var prd = new psProduct();

	if (ord.getOrder()) // Get order info from source code successfully?
	{
		// Post Pageviewtag as cartview
		for (var r = 0; r < rows.length; r++) // item for each row
		{
			var isProduct = false;
			for (var i = 0; i < rows[r].cells.length; i++) // item for each row
			{
				if(psGetInnerText(rows[r].cells[i]).toUpperCase().indexOf("FUJ")>-1)
				{
					isProduct = true;
					break;
				}
			}
			if(isProduct)
			{
				if (prd.getItem9(rows[r])) // Get shop9 item successfully?
					psCreateShopAction9Tag(prd.id, prd.name, prd.quantity, prd.price, profile.email, ord.id, ord.subtotal, prd.catId);
			}
		}
		// Make sure to have actual postings
		psDisplayShop9s();
		psCreateRegistrationTag(profile.email,profile.email,profile.city,profile.state,profile.zipcode,profile.newsletter,profile.subscribe);
		// Post order tag finally
		psCreateOrderTag(ord.id, ord.subtotal, ord.shipping, profile.email, profile.city,profile.state, profile.zipcode);
		// Delete cookie after checking successfully
		psSetCookie(G_PS_COOKIE_PROD_CATID, "", "delete");
	}
}

/*====================== 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;
	/*
	 * Extracting product info from source code for posting productview tag
	 */
	this.getProduct = function()
	{
		try
		{
			this.id = psGetElementValueById("prod_item_number",false);
			var se = /item\s*number\s*\:\s*([\w*\d*-]*[\w*\d*])/gi;
			this.id = (this.id.search(se)>-1)? RegExp.$1:this.id;
			this.name = psTrim(psGetElementValueById("prod_title",false));
			this.catId = (psGetCookie(G_PS_COOKIE_CATID)!=null)? psGetCookie(G_PS_COOKIE_CATID):"BOOKMARKS";
			
			// Store productId along with catId to cookie for use later in shop5 and shop9 views
			psSetValueToCookie(G_PS_COOKIE_PROD_CATID, this.id, 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,indexProd)
	{
		try
		{
			var divList = itemRow.getElementsByTagName("div");
			var divItem = null;
			for(var i = 0; i < divList.length; i++)
			{
				if(psIsEqual(divList[i].className,"cart_prod_desc"))
				{
					divItem = divList[i];
					break;
				}
			}
			if(divItem != null)
			{
				var aList = divItem.getElementsByTagName("a");
				this.id = psHtmlDecode(aList[0].href);
				var se = /http\:\/\/(www\.)?shopfujifilm\.com\/detail\/FUJ\s*\+\s*([\w*\d*-]*[\w*\d*])/gi;
				this.id = ((this.id).search(se)>-1)? RegExp.$2:this.id;
				this.name = psTrim(psHtmlDecode(psGetInnerText(aList[0])));
			}
			this.price = psGetInnerText(itemRow.cells[4]);
			this.quantity = psGetElementValueById("Q" + indexProd,false);
			this.catId = psGetValueFromCookie(G_PS_COOKIE_PROD_CATID, this.id);
			this.catId = (this.catId!=null)? this.catId:"";
			return true;
		}
		catch (ex) { return false; }
	}
	/*
	 * Extracting product info from source code specified by the "current" row
	 * of items table in the receipt page
	 */
	this.getItem9 = function(itemRow)
	{
		try
		{
			this.id = psGetInnerText(itemRow.cells[3]);
			var se = /FUJ\s*([\w*\d*-]*[\w*\d*])/gi;
			this.id = (this.id.search(se)>-1)? RegExp.$1:this.id;
			this.name = psTrim(psHtmlDecode(psGetInnerText(itemRow.cells[5])));
			this.price = psGetInnerText(itemRow.cells[7]);
			this.quantity = psGetInnerText(itemRow.cells[1]);
			this.catId = psGetValueFromCookie(G_PS_COOKIE_PROD_CATID, this.id);
			this.catId = (this.catId!=null)? this.catId:"";
			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; }
	}
	/*
	 * Set user profile to cookie
	 */
	this.writeProfile = function()
	{
		if (this.email == null)
			return;
		// 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);
	}
}

/*
 * 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 = null;
	this.shipping = null;
	this.cusId = null;
	/*
	 * get order info from source code
	 */
	this.getOrder = function()
	{
		try
		{
			var spanList = document.getElementsByTagName("span");
			var spanItem = null;
			for (var i=0; i<spanList.length; i++)
			{
				if(psIsEqual(spanList[i].className,"ordernum"))
				{
					spanItem = spanList[i];
					break;
				}
			}
			if(spanItem != null)
			{
				this.id = psGetInnerText(spanItem);
			}
			var cellList = document.getElementsByTagName("td");
			var cellItem = null;
			for (var i=0; i<cellList.length; i++)
			{
				if(psIsEqual(psGetInnerText(cellList[i]),"Subtotal:"))
				{
					cellItem = cellList[i];
					break;
				}
			}
			if(cellItem != null)
			{
				var rowItem = cellItem.parentNode;
				this.subtotal = psGetInnerText(rowItem.cells[7]);
			}
			cellItem = null;
			for (var i=0; i<cellList.length; i++)
			{
				if(psIsEqual(psGetInnerText(cellList[i]),"Shipping:"))
				{
					cellItem = cellList[i];
					break;
				}
			}
			if(cellItem != null)
			{
				var rowItem = cellItem.parentNode;
				this.shipping = psGetInnerText(rowItem.cells[7]);
			}
			
			
			if (!this.id)
			{
				this.id = psGenerateRandomValue();
			}
			
			if (!this.cusId)
			{
				this.cusId = this.id;
			}
			
			 return true;
		}
		catch (ex) {return false;}
	}
}

/* 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)
{
	while (pCatId.indexOf(String.fromCharCode(44))>-1)
	{
		pCatId = pCatId.replace(String.fromCharCode(44),"");
	}
    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;
}

/* PURPOSE: returns the value of an element based on element_id
 * @pValueFlag: TRUE means VALUE  attribute of SELECT object returned, not innerHTML
 * RETURN: 
 *  Normal tag: decoded innerHTML
 *  INPUT tag: value attribute
 *  SELECT tag: decoded label of the selected option
 */
function psGetElementValueById(pTagId, pValueFlag)
{
    var tag = document.getElementById(pTagId);
    return psGetElementValue(tag, pValueFlag);
}

/* PURPOSE: returns the value of an element based on element object
 * Note: this function returns decoded text
 * to avoid "double" decode, don't invoke psHtmlDecode on returned value again
 * @pValueFlag: TRUE means VALUE  attribute of SELECT object returned, not innerHTML
 * RETURN: 
 *  Normal tag: decoded innerHTML
 *  INPUT tag: value attribute
 *  SELECT tag: decoded label of the selected option
 *  NULL: if element not exist
 */
function psGetElementValue(pTagObj, pValueFlag)
{
    var tagValue = null;
    if (pTagObj != null)
    {
        if (pTagObj.tagName.search(/^INPUT$/i) > -1)
            tagValue = pTagObj.value;
        else if (pTagObj.tagName.search(/^SELECT$/i) > -1)
        {
            if (pValueFlag == true)
                tagValue = pTagObj.options[pTagObj.selectedIndex].value;
            else
                tagValue = psHtmlDecode(pTagObj.options[pTagObj.selectedIndex].innerHTML);// return label instead of value
        }
        else
            tagValue = psHtmlDecode(pTagObj.innerHTML);
    }

    return tagValue;
}

/* PURPOSE: validate email format
 * RETURN: boolean
 */
function psCheckEmail(pEmail) 
{
    if (pEmail)
    {
        var i = pEmail.search(/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/);
        return (i > -1);
    }

    return false;
}

/* 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, ">");
		pValue = pValue.replace(/%2D/gi, "-");
    }

    return pValue;
}

/* PURPOSE: extract main domain from the URL
 * RETURN: main domain
 */
function psGetMainDomain(pUrl){
	var se = /^https*\:\/\/([^\/\:]+)/gi;
	var domain = (pUrl.search(se) > -1) ? RegExp.$1 : null;
	if(domain != null)
	{
		if(domain.indexOf("www")==0)
		{
			domain = domain.substring(4,domain.length);
		}
		if(G_PS_ARR_DOMAIN != null)
		{
			for(var i =0; i<G_PS_ARR_DOMAIN.length; i++)
			{
				se = new RegExp("[\.]" + G_PS_ARR_DOMAIN[i] + "$","gi");
				if(("." + domain).search(se) > -1)
				{
					domain = G_PS_ARR_DOMAIN[i];
					break;
				}
			}
		}
		domain = "." + domain;
	}
	return domain;
	
}


/* 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)
{
    if (!pCookieName)
		return false;

	var pDomain = psGetMainDomain(G_PS_URL_PATH);
	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;
}

/*
 * Generate a random number
 */
function psGenerateRandomValue()
{
	var dtDate = new Date();
	var cusRandom = (dtDate.getTime()%10000000) + (Math.floor(Math.random()*10000));
	return cusRandom;
}

/********************************************************/
/* 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 ==================*/