/**
 * @author Ryan Hubbard <ryan@evariant.com>
 * @version 1.0 
 * @date 2009-05-14
 * @copyright Copyright (c) 2009 eVariant, LLC
 */

var DemandConnect = {
	campaign: {
		name: null,
		key: null,
		id: null,
		keyword: null
	},
	campaigns: null,
	campaignTracking: new Array(
		{key: 'bnrclid', name: 'Banner Ad'},
		{key: 'gclid',   name: 'Google PPC'},
		{key: 'elq_mid',     name: 'Eloqua Email'},
		{key: 'msclid',  name: 'MSN PPC'},
		{key: 'yhclid',  name: 'Yahoo PPC'},
		{key: 'lpclid',  name: 'Landing Page Hard Coded ID'}
	),
	referer: null,
	/** 
	 * Holds search engines that you want to capture data for. Any search engine not
	 * in the list will be captured as an seo_other campaign
	 */
	seoHosts: new Array(
		{host: 'aol',		campaign: 'AOL'},		// query param
		{host: 'dogpile',   campaign: 'Other'},		// No param as its a url rewrite
		{host: 'google',	campaign: 'Google'},	// q param
		{host: 'live',		campaign: 'Live'},		// q param
		{host: 'msn',		campaign: 'MSN'},		// q param
		{host: 'yahoo',		campaign: 'Yahoo'}		// y param
		//{host: 'altavista',	campaign: 'AltaVista'} // q param
		//{host: 'ask',		campaign: 'Ask Jeeves'} 		// q param
		//{host: 'hotbot',	campaign: 'Hot Bot'} 		// query param
		//{host: 'lycos',	campaign: 'Lycos'} 		// query param
	),
	/**
	 * Holds the params that search engines will use to send in keywords.
	 */
	seoKeywordParams: new Array('q', 'p', 'query'),
	timestampFormat: 'm/d/Y h:i A',
	
	/**
	 * Simulated Constructor
	 */
	__construct: function() {
		// Prep Data
		this.campaigns = this.getCampaignHistory();
		this.referer = document.referrer;
		var c = { name: null, key: null, id: null, keyword: null }	
		
		// This line is for testing
		if ( this.getQueryParam('referer') ) this.referer = window.location.href.split('referer=')[1];
		
		// Determine Non-SEO Campaign
		var ct = this.campaignTracking;
		for(var i=0; i<ct.length; i++) {
			var key = ct[i].key
			if ( this.getQueryParam(key) ) {
				c.id = this.getQueryParam(key);
				c.key = key;
				c.name = ct[i].name;
				break;
			}
		}

		// Determine SEO Campaign
		if (! c.id ) {
			// If the referer is ourself do nothing
			if ( this.getDomain(window.location) == this.getDomain(this.referer) ) {
				return;
			}
			c.id = this.getSeoCampaignId();
			c.keyword = this.getSeoKeyword();
		}
		
		// Add the campaign 
		if (! this.hasCampaign(c.id) ) {
			this.addCampaign(c);
		}
		//alert('Campaign: ' + c.name + "\nCampaign ID: " + c.id);
	},
	
	/**
	 * Adds a campaign to the users campaign history
	 * @param string The campaign id
	 */
	addCampaign: function(campaign) {
		if ( campaign == null || campaign.id == '' )
			return false;
		
		this.campaign = campaign;
		if ( this.campaigns.length >= 4 ) {
			this.campaigns[3].id = campaign.id;
			this.campaigns[3].keyword = campaign.keyword;
			this.campaigns[3].timestamp = this.getTimestamp(this.timestampFormat);
		} else {
			this.campaigns.push({ 
				id: campaign.id,
				keyword: campaign.keyword,
				timestamp: this.getTimestamp(this.timestampFormat)
			});
		}
		this.setCookie(
			'CampaignHistory', JSON.stringify(this.campaigns)
		);
	},
	
	/**
	 * Adds the campaign history information to a form by adding 
	 * hidden inputs to it
	 * @param string The form id to add the history to
	 */
	addCampaignsToForm: function(id) {
		var form = document.getElementById(id)
		var c = this.campaigns;
		for(var i=0; i<c.length; i++) {
			// Push campaign id
			var obj = document.createElement('INPUT');
				obj.name = 'demandconnect' + i;
				obj.type = 'hidden';
				obj.value = c[i].id;
			form.appendChild(obj);
			
			// Push timestampe
			var obj = document.createElement('INPUT');
				obj.name = 'demandconnect' + i + '_time';
				obj.type = 'hidden';
				obj.value = c[i].timestamp;
			form.appendChild(obj);
		}
	},
	
	/**
	 * Clears the campaign history
	 */
	clearCampaigns: function() {
		this.setCookie('CampaignHistory', '');
		this.campaigns = new Array();
	},
	
	/**
	 * Retrives and sets the campaign history
	 * @return array The campaign history
	 */ 
	getCampaignHistory: function() {
		if (! this.campaigns ) {
			var ch = this.getCookie('CampaignHistory');
			this.campaigns = ch ? JSON.parse(ch) : new Array();
		}
		return this.campaigns;
	},
	
	/**
	 * Retrieves a cookie value
	 * @param string The cookie name to retrieve
	 */
	getCookie: function(name) {	
		var nameEQ = name + "=";
		var ca = document.cookie.split(';');
		for(var i=0;i < ca.length;i++) {
			var c = ca[i];
			while (c.charAt(0)==' ') 
				c = c.substring(1,c.length);
			if (c.indexOf(nameEQ) == 0) 
				return c.substring(nameEQ.length,c.length);
		}
		return null;
	},
	
	/** 
	 * Returns the domain name of a url (Note: strips the www)
	 * @param string The url to use
	 * @param string OPTIONAL Whether to return the registered host name
	 * @return string The host name
	 */ 
	getDomain: function(url, registered) {
		if (! url )
			return '';
		var domain = new String(url).split('\/')[2];
		if ( registered ) {
			domain = domain.split('.').reverse();
			return domain[1] + '.' + domain[0];
		}
		return domain.replace(/^www\./, '');
	},
	
	/**
	 * Get the campaign id
	 * @return The campaign id
	 */
	getSeoCampaignId: function() {	
		// No referrer
		if (this.referer == undefined || this.referer.length <= 0)
			return 'website_direct';	
		
		// Determine domain
		var seo = this.getSeoHost();
		if ( seo )
			return 'seo_' + seo.campaign.toLowerCase();
		
		// It may be another search engine so search for keywords
		var seo_key = this.getSeoKeyword();
		if ( seo_key )
			return 'seo_other';
		
		return 'website_referal';
		
		// Format key
		seo_key = unescape(seo_key.toLowerCase());
		seo_key = seo_key.replace(/( |\+)/im, "_");
		seo_key = seo_key.replace(/https?(:\/\/)?/im, "");
		seo_key = seo_key.replace(/\W/im, "");
		seo_key = seo_key.replace(/^\s+|\s+$/g,"");
		return 'seo_' + seo.campaign.toLowerCase() + '_' + seo_key;	
	},
	
	/**
	 * Determines the DemandConnect.seoHosts object from the referer
	 * @return object The SEO Host (its actually just domain minus the extension)
	 */
	getSeoHost: function() {
		var host = this.getDomain(this.referer, true);
			host = host.split('.')[0];
		for(var i=0; i<this.seoHosts.length; i++) {
			if ( host == this.seoHosts[i].host ) {
				return this.seoHosts[i];
			}
		}
		return null;
	},

	/** 
	 * Determine the search engine keyword
	 * @return string The keyword
	 */
	getSeoKeyword: function() {
		var key;
		var params = this.seoKeywordParams;
		for(var i=0; i<params.length; i++ ) {
			if ( key = this.getQueryParam(params[i], this.referer) )
				return key
		}
		return null;
	},

	/**
	 * Retrieve a timestamp
	 * @param string The format of the string. This is similiar to PHP dates
	 * @see http://jacwright.com/projects/javascript/date_format
	 */
	getTimestamp: function(format) {
		// construction date
		var d = new Date();
		return d.format(format);
	},

	/**
	 * Returns a query string parameters value
	 * @param string The key value
	 * @param string OPTIONAL The url to retrieve the param from. Defaults to the webpages url
	 * @return string The key's value
	 */
	getQueryParam: function(key, url) {
		if (! url )
			url = window.location.href;
		key = key.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
		var regexS = "[\\?&]"+ key +"=([^&#]*)";
		var regex = new RegExp( regexS );
		var results = regex.exec( url );
		return results == null
			? ''
			: results[1];
	},
	
	/**
	 * Determines if the campaign is listed in the campaign history
	 * @param string The campaign id
	 * @return bool True Whether or not the campaign is in the history
	 */
	hasCampaign: function(campaign_id) {
		var c = this.campaigns;
		for(var i=0; i<c.length; i++) {
			if ( c[i].id == campaign_id )
				return true;
		}
		return false;
	},
	
	/**
	 * @param string The name of the cookie
	 * @param string The cookie value
	 * @param int The number of days until the cookie expires
	 */
	setCookie: function(name, value, days) {
		if ( days ) {
			var date = new Date();
			date.setTime(date.getTime()+(days*24*60*60*1000));
			var expires = "; expires="+date.toGMTString();
		} else 
			var expires = "";
		document.cookie = name + "=" + value + expires + "; path=/";
	}
};

////////////////////////////////////////////////////////////////////////////////
// Added by Vic
var eventCollector = '';
function addEvent(e) {
 if ( e == null || e == '' )
  return;
 if ( eventCollector == null || eventCollector == '' )
  eventCollector = e;
 else
  eventCollector = eventCollector+','+e;
};
function getEventCollector() {
 return eventCollector;
};
function setEventCollector(e) {
 eventCollector = e;
};
function appendCookie(name, value, days) {
 if ( value == null || value == '' )
  return;
 if ( DemandConnect.getCookie(name) == null )
  DemandConnect.setCookie(name, value, days)
 else
  DemandConnect.setCookie(name, DemandConnect.getCookie(name)+','+value, days)
};
////////////////////////////////////////////////////////////////////////////////

// Simulates PHP's date function
Date.prototype.format=function(format){var returnStr='';var replace=Date.replaceChars;for(var i=0;i<format.length;i++){var curChar=format.charAt(i);if(replace[curChar]){returnStr+=replace[curChar].call(this);}else{returnStr+=curChar;}}return returnStr;};Date.replaceChars={shortMonths:['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'],longMonths:['January','February','March','April','May','June','July','August','September','October','November','December'],shortDays:['Sun','Mon','Tue','Wed','Thu','Fri','Sat'],longDays:['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],d:function(){return(this.getDate()<10?'0':'')+this.getDate();},D:function(){return Date.replaceChars.shortDays[this.getDay()];},j:function(){return this.getDate();},l:function(){return Date.replaceChars.longDays[this.getDay()];},N:function(){return this.getDay()+1;},S:function(){return(this.getDate()%10==1&&this.getDate()!=11?'st':(this.getDate()%10==2&&this.getDate()!=12?'nd':(this.getDate()%10==3&&this.getDate()!=13?'rd':'th')));},w:function(){return this.getDay();},z:function(){return"Not Yet Supported";},W:function(){return"Not Yet Supported";},F:function(){return Date.replaceChars.longMonths[this.getMonth()];},m:function(){return(this.getMonth()<11?'0':'')+(this.getMonth()+1);},M:function(){return Date.replaceChars.shortMonths[this.getMonth()];},n:function(){return this.getMonth()+1;},t:function(){return"Not Yet Supported";},L:function(){return"Not Yet Supported";},o:function(){return"Not Supported";},Y:function(){return this.getFullYear();},y:function(){return(''+this.getFullYear()).substr(2);},a:function(){return this.getHours()<12?'am':'pm';},A:function(){return this.getHours()<12?'AM':'PM';},B:function(){return"Not Yet Supported";},g:function(){return this.getHours()%12||12;},G:function(){return this.getHours();},h:function(){return((this.getHours()%12||12)<10?'0':'')+(this.getHours()%12||12);},H:function(){return(this.getHours()<10?'0':'')+this.getHours();},i:function(){return(this.getMinutes()<10?'0':'')+this.getMinutes();},s:function(){return(this.getSeconds()<10?'0':'')+this.getSeconds();},e:function(){return"Not Yet Supported";},I:function(){return"Not Supported";},O:function(){return(this.getTimezoneOffset()<0?'-':'+')+(this.getTimezoneOffset()/60<10?'0':'')+(this.getTimezoneOffset()/60)+'00';},T:function(){return"Not Yet Supported";},Z:function(){return this.getTimezoneOffset()*60;},c:function(){return"Not Yet Supported";},r:function(){return this.toString();},U:function(){return this.getTime()/1000;}};

// JSON Class
if(!this.JSON){JSON={};}
(function(){function f(n){return n<10?'0'+n:n;}
if(typeof Date.prototype.toJSON!=='function'){Date.prototype.toJSON=function(key){return this.getUTCFullYear()+'-'+
f(this.getUTCMonth()+1)+'-'+
f(this.getUTCDate())+'T'+
f(this.getUTCHours())+':'+
f(this.getUTCMinutes())+':'+
f(this.getUTCSeconds())+'Z';};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf();};}
var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==='string'?c:'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4);})+'"':'"'+string+'"';}
function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==='object'&&typeof value.toJSON==='function'){value=value.toJSON(key);}
if(typeof rep==='function'){value=rep.call(holder,key,value);}
switch(typeof value){case'string':return quote(value);case'number':return isFinite(value)?String(value):'null';case'boolean':case'null':return String(value);case'object':if(!value){return'null';}
gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==='[object Array]'){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||'null';}
v=partial.length===0?'[]':gap?'[\n'+gap+
partial.join(',\n'+gap)+'\n'+
mind+']':'['+partial.join(',')+']';gap=mind;return v;}
if(rep&&typeof rep==='object'){length=rep.length;for(i=0;i<length;i+=1){k=rep[i];if(typeof k==='string'){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}else{for(k in value){if(Object.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}
v=partial.length===0?'{}':gap?'{\n'+gap+partial.join(',\n'+gap)+'\n'+
mind+'}':'{'+partial.join(',')+'}';gap=mind;return v;}}
if(typeof JSON.stringify!=='function'){JSON.stringify=function(value,replacer,space){var i;gap='';indent='';if(typeof space==='number'){for(i=0;i<space;i+=1){indent+=' ';}}else if(typeof space==='string'){indent=space;}
rep=replacer;if(replacer&&typeof replacer!=='function'&&(typeof replacer!=='object'||typeof replacer.length!=='number')){throw new Error('JSON.stringify');}
return str('',{'':value});};}
if(typeof JSON.parse!=='function'){JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==='object'){for(k in value){if(Object.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v;}else{delete value[k];}}}}
return reviver.call(holder,key,value);}
cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return'\\u'+
('0000'+a.charCodeAt(0).toString(16)).slice(-4);});}
if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){j=eval('('+text+')');return typeof reviver==='function'?walk({'':j},''):j;}
throw new SyntaxError('JSON.parse');};}}());

// Initalize
DemandConnect.__construct();

