/** public class CobaltPixelTag
  */
function CobaltPixelTag(pixelOptions) {
	this.pixelOptions = (pixelOptions) ? pixelOptions : {};
	this.isSessionVerified = false;
	// set timestamp
	var d = new Date();
	this.timestamp = d.getTime();
}

CobaltPixelTag.prototype.defaultParamSet = ['requestDomain','pageName','pageLabel','pageLayout','requestUri','referrerDomain','referrerUri','visitorId','eventId','sessionId','siteId','leadId','vin','promoName'];

CobaltPixelTag.prototype.writePixelTag = function() {
	if (!this.isSessionVerified) {
		// check session
		if (!this.isSessionExpired()) {
			this.isSessionVerified = true;
			this.writePixelTag();
		} else {
			// verify session ID
			this.verifySession();
		}
	} else {
		//
		var imgString = this.getPixelTag(this.pixelOptions);
		//
		this.firePixelTag(imgString);
		//
		// Perform callback if provided
		if (this.pixelOptions.callback) {
			this.pixelOptions.callback();
		}
	}
}
/**
* 	Given a set of params, return a pixel tag URL string
*/
CobaltPixelTag.prototype.getPixelTag = function(pixelOptions) {
	// Create a unique ID: concat Server-generated guid and 12-char suffix
	pixelOptions.eventId = ContextManager.eventId + ContextManager.generateEventIdSuffix();
	//
	var imgString = ContextManager.PIXEL_IMAGE_URL + '?';
	// check for extra params
	var paramArray = (pixelOptions.paramSet) ? this.defaultParamSet.concat(pixelOptions.paramSet) : this.defaultParamSet;
	imgString += this.getPixelParameters(paramArray);
	// add extra queryString if present
	if (pixelOptions.queryString) { imgString += pixelOptions.queryString; }
	return imgString;
}
/**
*/
CobaltPixelTag.prototype.firePixelTag = function(imgString) {
	var pt = new Image(1, 1);
	pt.src = imgString;
	// need this onload for consistent IE 6 performance, inspired by http://breckman.com/entry.php?id=30
	pt.onload = function() { pt.onload = null; }
}
//
CobaltPixelTag.prototype.verifySession = function() {
	// session expired, get new sessionID
	var _this = this; // use closure to maintain reference to this CobaltPixelTag
	jQuery.ajax({
		type: "GET",
		dataType: "html",
		url: "pixelInformation.ajax", 
		success: function(data) {
			var startKey = data.indexOf(_this.pixelKeys['sessionId']);	// use closure ref
			var st = data.indexOf('=', startKey) + 1;
			var end = data.indexOf('&', startKey);
			var newSessionId = data.substring(st, end);
			if (newSessionId != ContextManager.sessionId) {
				// set new session
				ContextManager.updateProperties("sessionId=" + newSessionId);
			}
			// since we hit the backend, we must reset the session timer
			ContextManager.session.startTime = _this.timestamp;
			_this.isSessionVerified = true;
			_this.writePixelTag();
		},
		error: function(oXHR, err, oExc) {
			//alert(err);
		}
	});
}
//
CobaltPixelTag.prototype.isSessionExpired = function() {
	return ((this.timestamp - ContextManager.session.startTime) > ContextManager.session.duration);
}
//
CobaltPixelTag.prototype.getPixelParameters = function(paramArray) {
	var st = "";
	var key, val;
	var uniqueArray = [];
	// remove any duplicates from the array
	uniqueArray = this.removeDups(paramArray);
	var len = uniqueArray.length;
	for (i=0; i < len; i++) {
		// check for user-submitted override
		if (this.pixelOptions[uniqueArray[i]]) {
			val = this.pixelOptions[uniqueArray[i]];
		} else {
			val = ContextManager[uniqueArray[i]];
		}
		// skip null or undefined values
		if (val) {
			// get key from map
			key = this.getPixelKey(uniqueArray[i]);
			//
			st += key + '=' + val;
			st += '&';
		}
	}
	return st;
}

CobaltPixelTag.prototype.removeDups = function(a) {
	var i,x,y;
	var r = [];
	var n = a.length;
	o:for(i=0; i < n; i++) {
		y = r.length;
		for(x=0; x < y; x++) {
			if(r[x]==a[i]) continue o;
		}
		r[r.length] = a[i];
	}
	return r;
}

CobaltPixelTag.prototype.getPixelKey = function(prop) {
	var key = this.pixelKeys[prop];
	// if undefined in key list, then use contextManager value
	return (key) ? key : prop;
}

CobaltPixelTag.prototype.pixelKeys = {
	dma : 'cs:dma',
	zip : 'cs:zip',
	promoName : 'cs:a',
	webId : 'cs:s',
	make : 'inventory_make',
	model : 'inventory_model',
	trim : 'inventory_trim',
	search : 'inventory_search_type',
	locale : 'cs:loc',
	mileageRange : 'cs:i:mi',
	paymentRange : 'cs:i:pay',
	priceRange : 'cs:i:pr',
	bodyType : 'cs:i:vt',
	vin : 'cs:i:vin',
	yearRange : 'cs:i:y',
	requestDomain : 'header_request_domain',
	pageName : 'header_page_name',
	pageLabel : 'header_page_label',
	pageLayout : 'header_page_layout',
	requestUri : 'header_request_uri',
	referrerDomain : 'header_referrer_domain',
	referrerUri : 'header_referrer_uri',
	visitorId : 'header_visitor_id',
	eventId : 'header_event_id',
	sessionId : 'header_session_id',
	siteId : 'header_site_id',
	leadId : 'lead_id',
	linkoutLabel : 'cs:lo'
}

//***********************************************************************************************
// Linkout functionality
//		- providing static methods for this
//***********************************************************************************************
CobaltPixelTag.linkData = {};
CobaltPixelTag.pixelTagData = {};
/**
*	linkout will perform specified tracking and perform external link
*
* 		linkData : This object will contain:
*			url:			String: URL to link to
*			target:			String: "_self" or "_top" to replace current, or "_blank" for new window
*			windowParams:	A comma-delimited string specifying any properties of the new window.
*		pixelTagData:	Provides any parameter overrides/additions for the pixel tag.
*/
CobaltPixelTag.linkout = function(linkData, pixelTagData) {
	CobaltPixelTag.linkData = (linkData) ? linkData : {};
	CobaltPixelTag.pixelTagData = (pixelTagData) ? pixelTagData : {};
	// ensure valid URL
	if (CobaltPixelTag.isValidUrl(CobaltPixelTag.linkData.url)) {
		CobaltPixelTag.trackLinkout();
	}
}
/*
* Checks whether this is a valid url format
*/
CobaltPixelTag.isValidUrl = function(urlString) {
	if ((urlString.search(/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/) != -1) && (!CobaltPixelTag.isNull(urlString))) {
	   return true;
	} else {
	   return false;
	}         
}
/*  
* Returns true if the parameter is null
*/
CobaltPixelTag.isNull = function(param) {  
	 if ((undefined == param) || (void 0 == param) || (param.length == 0)){
		return true;
	}    
	return false;
}
/**
*	Fire a pixel tag before linking out.
*/
CobaltPixelTag.trackLinkout = function() {
	// add callback : execute the link when tracking is complete.
	CobaltPixelTag.pixelTagData.callback = CobaltPixelTag.doLink;
	//
	// Add linkoutLabel to extra params to track
	if (CobaltPixelTag.pixelTagData.paramSet) {
		// a paramSet has been specified, so add our linkoutLabel to it
		CobaltPixelTag.pixelTagData.paramSet.push('linkoutLabel');
	} else {
		CobaltPixelTag.pixelTagData.paramSet = ['linkoutLabel'];
	}
	//
	var cobaltTag = new CobaltPixelTag(CobaltPixelTag.pixelTagData);
	//
	// **************** TEMPORARY CODE
	if (ContextManager.PIXEL_IMAGE_URL_OLD) {
		// First fire an 'old' tag: THIS CODE SHOULD BE REMOVED AFTER PIXEL TAG ROLLOUT
		var ptString = cobaltTag.getPixelTag(CobaltPixelTag.pixelTagData);
		// remove image name
		var temp = ptString.substring(ptString.indexOf("?"));
		// strip time stamp off the eventID
		var ind = temp.indexOf("header_event_id=")+16;
		var start = temp.substring(0, ind);
		var end = temp.substring(temp.indexOf("&", ind));
		//
		cobaltTag.firePixelTag(ContextManager.PIXEL_IMAGE_URL_OLD + start + ContextManager.eventId + end);
	}
	// **************** END  TEMPORARY CODE
	//
	// Now write the 'new' tag. Callback will execute afterwards.
	cobaltTag.writePixelTag();
}
/**
*	After linkout tracking is complete, execute the link
*/
CobaltPixelTag.doLink = function() {
	// First publish a linkout event for any potential third-party handlers
	// 		- Add cs:lo value to event name
	//		- Pass pixelTagData as publisherData
	var loLabel = (CobaltPixelTag.pixelTagData.linkoutLabel) ? "." + CobaltPixelTag.pixelTagData.linkoutLabel : "";
	var evName = 'com.cobaltgroup.ws.action.link' + loLabel;
	// Before passing along CobaltPixelTag.pixelTagData, first remove the callback, to avoid recursion.
	delete CobaltPixelTag.pixelTagData.callback;
	//
	EventManager.publish({
		eventName:evName,
		publisherData:CobaltPixelTag.pixelTagData
	});
	//
	var tar = CobaltPixelTag.linkData.target;
	if (tar == "_self" || tar == "_top") {
		location.href = CobaltPixelTag.linkData.url;
	} else {
		var winParams = (CobaltPixelTag.linkData.windowParams) ? CobaltPixelTag.linkData.windowParams : "";
		var newWindow = window.open(CobaltPixelTag.linkData.url,"newWin",winParams); 
		newWindow.focus();
	}
}
