/**
************************************************************************
*
* This script is used for Third-party applications/domains to send 
* data that needs to be submitted in the backend as a Cobalt lead.
*
* Third-party calls this function with the appropriate parameter.
* Parameter definition:
*        eventObj - This is the object which contains event_name attribute
*        This object can also contains an optional lead_id attribute
* Calling syntax:
*        cpp.trackEvent(eventObj);
************************************************************************
*/

var cpp = function(){
	
	var _isCobaltSite = (window.ContextManager)?true:false;
	
	var _qualifierPrefix = 'cpp:';
	var _cookieName = 'Cobalt';
	var _getCppParamsMap = function(){
		return {
			'header_session_id': 		{qs:_qualifierPrefix+'rv', ctx:'sessionId'},
			'header_site_id': 			{qs:_qualifierPrefix+'sid', ctx:'siteId'},
			'header_visitor_id': 		{qs:_qualifierPrefix+'vid', ctx:'visitorId'},
			'header_event_id': 			{qs:null, ctx:'eventId'},
			'header_page_name': 		{qs:null, ctx:'pageName'},
			'header_page_label': 		{qs:null, ctx:'pageLabel'},
			'header_page_layout': 		{qs:null, ctx:'pageLayout'},
			'header_request_domain': 	{qs:null, ctx:'requestDomain'},
			'header_request_uri': 		{qs:null, ctx:'requestUri'} 
		};
	}
	var _isNull = function(v) {
		return (v===undefined || v===null || v==='')?true:false;
	}
	var _trim = function(s) {
		return s.replace(/^\s*|\s*$/g,"");
	}
	//copied from ContextManager
	var _URLEncode = function(str){
        // The Javascript escape and unescape functions do not correspond
        // with what browsers actually do...
        var SAFECHARS = "0123456789" + // Numeric
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + // Alphabetic
        "abcdefghijklmnopqrstuvwxyz" +
        "-_.!~*'()"; // RFC2396 Mark characters
        var HEX = "0123456789ABCDEF";
        
        var encoded = "";
        for (var i = 0; i < str.length; i++) {
            var ch = str.charAt(i);
            if (ch == " ") {
                encoded += "+"; // x-www-urlencoded, rather than %20
            } else if (SAFECHARS.indexOf(ch) != -1) {
                encoded += ch;
            } else {
                var charCode = ch.charCodeAt(0);
                if (charCode > 255) {
                    encoded += "+";
                } else {
                    encoded += "%";
                    encoded += HEX.charAt((charCode >> 4) & 0xF);
                    encoded += HEX.charAt(charCode & 0xF);
                }
            }
        } // for
        return encoded;
    }
	
	//the next three cookie-handling functions are referenced from www.quirksmode.org/js/cookies.html
	var _createCookie = function(name,value,days) {
		var expires = "";
		if (days) {
			var date = new Date();
			date.setTime(date.getTime()+(days*24*60*60*1000));
			var expires = "; expires="+date.toGMTString();
		}
		document.cookie = name+"="+value+expires+"; path=/";
	}
	var _readCookie = function(name) {
		var nameEQ = name + "=";
		var ca = document.cookie.split(';');
		for(var i=0;i < ca.length;i++) {
			var c = _trim(ca[i]);
			if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
		}
		return null;
	}
	var _eraseCookie = function(name) {
		_createCookie(name,"",-1);
	}
	
	//two additional helpers methods for cookie-handling
	var _parseCookie = function(name) {
		if(!name) name = _cookieName;
		var str = _readCookie(name);
		var o = {};
		if(!str) {
			return o;
		} 
		var arr = str.split('|');
		for(var i=0, len=arr.length; i<len; i++) {
			arr[i] = _trim(arr[i]);
			var a = arr[i].split('=');
			o[a[0]]=a[1];
		}
		return o;
	}
	var _mapToCookie = function(name, map, days) {
		var arr=[], v='';
		for(k in map) {
			v = (map[k])?map[k]:'';
			arr.push(k+'='+v);
		}
		_createCookie(name, arr.join('|'), days);
	}
	
	//next if we are not in Cobalt dealer site, we might need to set things up in the cookie
	if(!_isCobaltSite && window.location.search.length>0) {
		
		var arr = window.location.search.substring(1).split('&');
		var cookieData=_parseCookie();
		
		for(var i=0, len=arr.length; i<len; i++){
			if(arr[i].length>0 && arr[i].indexOf(_qualifierPrefix)===0) {
				var regex = new RegExp("("+_qualifierPrefix+"[a-zA-Z0-9\.]+)=([^&#]*)");  // /(cpp:[a-zA-Z0-9\.]+)=([^&#]*)/;
				var result = regex.exec(arr[i]); //result[1]=param, result[2]=value 
				if(result.length>1 && result[0].length>0 && result[1].length>0) {
					cookieData[result[1]] = result[2];
				}
			}
		}
		
		//now update the cookie
		_mapToCookie(_cookieName, cookieData, null);
	}
	
	var _mapToQueryString = function(map) {
		var arr=[], v='';
		for(k in map) {
			v = (map[k])?map[k]:'';
			if(!_isNull(v)) arr.push(k+'='+v);
		}
		return arr.join('&');
	}
	
	if(_isCobaltSite) {
		var ptr = 'ctx';
		var _getParamVal = function(p) {
			return ContextManager.getProperty(p);
		}
		var _inferOtherParamValues = function(obj) {
			var v;
			(v=_getParamVal('referrerDomain'))? (obj['header_referrer_domain']=v):null;
			(v=_getParamVal('referrerUri'))? (obj['header_referrer_uri']=v):null;
			obj['header_event_id'] = ContextManager.getEventId() + ContextManager.generateEventIdSuffix();
		}
		
	} else {
		var ptr = 'qs';
		var _getParamVal = function(p) {
			var regEx      = new RegExp("[\\?&]"+p+"=([^&#]*)");
			var paramValue = regEx.exec(window.location.search);
			
			if( paramValue == null ) {
				var o = _parseCookie();
				return (o && !_isNull(o[p]))?o[p]:null;
			} else {
				return paramValue[1];
			}
		}
		
		//no single consistent way to find out values of these params on 3rd party sites
		var _inferOtherParamValues = function(obj) {
			
			//if(document.referrer) {
				var _getReferrer = function() {
					
					// parseUri 1.2.2
					// (c) Steven Levithan <stevenlevithan.com>
					// MIT License
					function parseUri (str) {
						var	o   = parseUri.options,
							m   = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
							uri = {},
							i   = 14;
	
						while (i--) uri[o.key[i]] = m[i] || "";
	
						uri[o.q.name] = {};
						uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
							if ($1) uri[o.q.name][$1] = $2;
						});
	
						return uri;
					};
	
					parseUri.options = {
						strictMode: false,
						key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
						q:   {
							name:   "queryKey",
							parser: /(?:^|&)([^&=]*)=?([^&]*)/g
						},
						parser: {
							strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
							loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
						}
					};
					
					var x = parseUri(document.referrer);
					if(typeof x == 'object' && typeof x.host != 'undefined' && x.host!=window.location.hostname){
						if(!x.host) x.host=null;
						x.relative = (!x.relative)?null:_URLEncode(x.relative);
						
					} else {
						x = {
							host: null,
							relative:null
						};
					}
					return x;
				}
			//}
			
			var referrerObj = _getReferrer();
			
			var _infer = function(p) {
				var v = '';
				switch(true) {
				
				case (p=='header_request_domain'):
					v = window.location.hostname; break;
					
				case (p=='header_request_uri'):
					v = _URLEncode(window.location.pathname); break;
					
				case (p=='header_event_id'):
					v = _generateUid(); break;
					
				case (p=='header_referrer_domain'):
					v = referrerObj['host']; break;
					
				case (p=='header_referrer_uri'):
					v = referrerObj['relative']; break;
				}
				return v;
			}
			
			var _params = ['header_request_domain', 'header_request_uri', 'header_page_label', 'header_page_layout', 'header_event_id', 'header_referrer_domain', 'header_referrer_uri'];
			for (var i=0, len=_params.length, v=null; i<len; i++) {
				v = _infer(_params[i]);
				if(!_isNull(v)) {
					obj[_params[i]] = v;
				}
			}
		}
	}
	var _populateParamValues = function(obj){
		for(x in obj) {
			if(typeof obj[x][ptr] == 'undefined') continue;
			obj[x] = _getParamVal(obj[x][ptr]);
		}
		if(typeof _inferOtherParamValues == 'function') _inferOtherParamValues(obj);
	};
	
	var _getUrl = function() {
		return (_isCobaltSite)?_URLEncode(_getParamVal('url')):_getParamVal(_qualifierPrefix+'url');
	}
	
	var _getEnvFromDealerURL = function() {
		//figure out dealerURL
		var dealerURL = _getUrl();
		var nStart = dealerURL.indexOf('.websites.') + 10;
		var nEnd   = dealerURL.indexOf('.cobaltgroup.');
		if (nStart > 10 && nEnd > nStart) {
			dealerURL = dealerURL.slice(nStart, nEnd);
		} else {
			dealerURL = "prod";
		}
		return dealerURL;
	}
	
	var _createPixelTag = function(obj) {
		var trafficServerSuccessUrl =  _getTrafficServerUrl();
		var queryString = _mapToQueryString(obj);
		return trafficServerSuccessUrl + "?" + queryString;
	}
	
	var _getTrafficServerUrl = function() {
		var trafficServerSuccessUrl =  "http://traffic."+ _getEnvFromDealerURL() +".cobaltgroup.com/websites.gif";
		return trafficServerSuccessUrl;
	}
	
	var _getCppParams = function(){
		var url = _getUrl();
		var obj = _getCppParamsMap();
		_populateParamValues(obj);
		return "&"+_qualifierPrefix+"url=" + url + "&"+_qualifierPrefix+"rv=" + obj.header_session_id + "&"+_qualifierPrefix+"sid=" + obj.header_site_id + "&"+_qualifierPrefix+"vid=" + obj.header_visitor_id;
	}
	
	var _checkMandatoryValues = function(obj) {
		for(p in obj) {
			if(_isNull(obj[p])) return false;
		}
		return true;
	}
	
	var _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; }
	}
	
	//duplicated from ContextManager
	var _generateUid = function(){
        var i; var unit = 4, length=44, st = "";
        // determine # of iterations - each unit is 4 chars
        var count = Math.ceil(length / unit);
        for (i = 1; i <= count; i++) {
            st += (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
        }
        return st.substr(0, length);
    }
	
	return {
		getCppParams: function(){
			return _getCppParams();
		},
		trackEvent: function(eventObj){
			
			if(typeof eventObj != 'object') eventObj = {event_name:null};
			
			if(eventObj.event_name) {
				
				eventObj.event_name = _URLEncode(_trim(eventObj.event_name));
			
				var obj = _getCppParamsMap();
				
				obj.header_page_layout = obj.header_page_label = obj.header_page_name = eventObj.event_name;
				
				_populateParamValues(obj);
				
				if(!_isNull(eventObj.lead_id)){
					obj.lead_id = eventObj.lead_id;
				}
				
				if(_checkMandatoryValues(obj)) {
					var str = _createPixelTag(obj);
					_firePixelTag(str);
				}
			}
			
			if(_isCobaltSite) {
				var eventToken = (eventObj.event_name) ? "." + _trim(eventObj.event_name) : ".unidentified";
				EventManager.publish({
				    eventName: "com.cobaltgroup.ws.thirdPartyEvent" + eventToken
				});
			}
		}
	};
}();
