/**
 * @author Ryan Hubbard <ryan@evariant.com>
 * @version 1.0 
 * @date 2009-05-14
 * @copyright Copyright (c) 2009 eVariant, LLC
 */

// Load jQuery (my friend)
var DemandConnect = {
	campaign: {
		name: null,
		key: null,
		id: null,
		keyword: null,
		referrer: null
	},
	campaignHistory: null,
	campaignTracking: new Array(
		{key: 'bnrclid', campaignId: 'Banner Ad'},
		{key: 'gccid',   campaignId: 'Google PPC'},
		{key: 'mid',     campaignId: 'Eloqua Email'},
		{key: 'msclid',  campaignId: 'MSN PPC'},
		{key: 'yhclid',  campaignId: 'Yahoo PPC'},
		{key: 'lpclid',  campaignId: 'Landing Page Hard Coded ID'}
		//{key: 'omgclid', campaignId: 'Omniture Google PPC'}
	),

	eloquaDataLookup: null,
	referrer: null,
	
	campaigns: {
		bnrclid:	'Banner Ad',
		gclid:		'Google PPC',
		lpclid: 	'Landing Page Hard Coded ID',
		mid:		'Eloqua Email',
		msclid:		'MSN PPC',
		omgclid: 	'Omniture Google PPC',
		yhclid: 	'Yahoo PPC'
	},
	
	/** 
	 * 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
	 */
	seoCampaigns: {
		aol:		'AOL',
		bing:		'Bing',
		dogpile:	'Other',
		google:		'Google',
		live:		'Live',
		msn:		'MSN',
		yahoo:		'Yahoo'
	},
	seoHosts: new Array(
		{host: 'aol',		campaignId: 'AOL'},		// query param
		{host: 'bing',      campaignId: 'Bing'},		// q param
		{host: 'dogpile',   campaignId: 'Other'},		// No param as its a url rewrite
		{host: 'google',	campaignId: 'Google'},	// q param
		{host: 'live',		campaignId: 'Live'},		// q param
		{host: 'msn',		campaignId: 'MSN'},		// q param
		{host: 'yahoo',		campaignId: '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
	),
	specialCampaigns: {
		seoOther:			'seo_other',
		websiteDirect: 		'website_direct',
		websiteReferral:	'website_referral'
	},
	/**
	 * 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() {
		this.referrer = document.referrer;

		// This line is for testing
		if ( this.getQueryParam('referrer') ) this.referrer = window.location.href.split('referrer=')[1];
		
		this.referringDomain = this.referrer.split('/')[2];
		if ( this.referrer.indexOf('http://now.eloqua.com/e/f2.aspx?elqFormName=') == 0 ) 
			this.clearCampaigns();

	
	},
	logCampaign: function() {
		// Prep Data
		this.campaignHistory = this.getCampaignHistory();
		
		var c = { name: null, key: null, id: null, keyword: null, referrer: null }	
		


		// Determine Non-SEO Campaign
		for ( key in this.campaigns ) {
			if ( this.getQueryParam(key) ) {
				c.id = this.getQueryParam(key);
				c.key = key;
				c.name = this.campaigns[key];
				break;
			}
		}
		/*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].campaignId;
				break;
			}
		}*/

		// Determine SEO Campaign
		if (! c.id ) {
			// If the referrer is ourself do nothing
			if ( this.getDomain(window.location) == this.getDomain(this.referrer) ) {
				return;
			}
			c.id = this.getSeoCampaignId();
			c.keyword = this.getSeoKeyword();
		}
		
		// Add the campaign 
		if (! this.hasCampaign(c.id) && this.referringDomain != 'now.eloqua.com' ) {
			this.addCampaign(c);
		}
		//alert('Campaign: ' + c.name + "\nCampaign ID: " + c.id);
	},
	
	__emailOnChange: function() {
		var elqDt = new Date();
		var elqMs = elqDt.getMilliseconds();
		var elqPPS = '50';
		var elqDLKey = escape('e368af281bb545578050f5da31362189');
		var elqDLLookup = '<C_EmailAddress>' + DemandConnect.email.value + '</C_EmailAddress>';
		//alert(elqDLLookup);
		if ((typeof elqCurE != 'undefined') && (typeof elqPPS != 'undefined')){document.write('<SCR' + 'IPT TYPE="text/javascript" LANGUAGE="JavaScript" SRC="' + elqCurE + '?pps=' + elqPPS + '&siteid=' + elqSiteID + '&DLKey=' + elqDLKey + '&DLLookup=' + elqDLLookup + '&ms=' + elqMs + '"><\/SCR' + 'IPT>');}

	},
	
	/**
	 * 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;
		campaign.timestamp = this.getTimestamp(this.timestampFormat);
		campaign.referrer = this.referrer.replace(';', '');
		//campaign.referrer = this.referrerDomain;
		
		if ( this.campaignHistory.length >= 4 ) {
			this.campaignHistory[3] = campaign;
		} else {
			this.campaignHistory.push(campaign);
		}
		this.setCookie(
			'CampaignHistory', JSON.stringify(this.campaignHistory)
		);
	},
	
	/**
	 * Adds the campaign history information to a form by adding 
	 * hidden inputs to it
	 * @param string The form id to add the history to
	 * @param string OPTIONAL The email address form field id
	 */
	addCampaignsToForm: function(formId, emailId) {
		var form = document.getElementById(formId)
		var c = this.campaignHistory;
		for(var i=0; i<c.length; i++) {
			// Push campaign id
			var obj = document.createElement('INPUT');
				obj.name = 'demandconnect' + i + '_campaignid';
				obj.type = 'hidden';
				obj.value = c[i].id;
			form.appendChild(obj);
			
			// Push timestamp
			var obj = document.createElement('INPUT');
				obj.name = 'demandconnect' + i + '_time';
				obj.type = 'hidden';
				obj.value = c[i].timestamp;
			form.appendChild(obj);
			
			// Push keyworkds
			var obj = document.createElement('INPUT');
				obj.name = 'demandconnect' + i + '_keyword';
				obj.type = 'hidden';
				obj.value = c[i].keyword;
			form.appendChild(obj);			
			
			// Push referrer
			var obj = document.createElement('INPUT');
				obj.name = 'demandconnect' + i + '_referrer';
				obj.type = 'hidden';
				obj.value = c[i].referrer;
			form.appendChild(obj);
		}
		
		// Add most recent 
		if ( c.length > 0 ) {
			index = c.length-1;
			// Push campaign id
			var obj = document.createElement('INPUT');
				obj.name = 'demandconnect_mostrecent_campaignid';
				obj.type = 'hidden';
				obj.value = c[index].id;
			form.appendChild(obj);
			
			// Push timestamp
			var obj = document.createElement('INPUT');
				obj.name = 'demandconnect_mostrecent_time';
				obj.type = 'hidden';
				obj.value = c[index].timestamp;
			form.appendChild(obj);
			
			// Push keyworkds
			var obj = document.createElement('INPUT');
				obj.name = 'demandconnect_mostrecent_keyword';
				obj.type = 'hidden';
				obj.value = c[index].keyword;
			form.appendChild(obj);

			// Push referrer
			var obj = document.createElement('INPUT');
				obj.name = 'demandconnect_mostrecent_referrer';
				obj.type = 'hidden';
				obj.value = c[index].referrer;
			form.appendChild(obj);
		}
		
		//
		var email = document.getElementById(emailId);
		if ( email && (typeof window.GetElqContentPersonalizationValue == 'function') ) {
			this.email = email;
			if ( email.addEventListener )
				email.addEventListener('change', this.__emailOnChange, false);
			else
				email.attachEvent('onchange', this.__emailOnChange);
		}
	},
	
	/**
	 * Clears the campaign history
	 */
	clearCampaigns: function() {
		this.setCookie('CampaignHistory', '');
		this.campaignHistory = new Array();
	},
	
	/**
	 * Retrives and sets the campaign history
	 * @return array The campaign history
	 */ 
	getCampaignHistory: function() {
		if (! this.campaignHistory ) {
			var ch = this.getCookie('CampaignHistory');
			try {
				this.campaignHistory = ch ? JSON.parse(ch) : new Array();
			} catch (e) {
				alert(ch);
				this.campaignHistory =  new Array();	
			}
		}
		return this.campaignHistory;
	},
	
	/**
	 * 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.referrer == undefined || this.referrer.length <= 0)
			return this.specialCampaigns.websiteDirect;	
		
		// Determine domain
		var host = this.getSeoHost();
		if ( this.seoCampaigns[host] )
			return this.seoCampaigns[host];
		
		// It may be another search engine so search for keywords
		var seo_key = this.getSeoKeyword();
		if ( seo_key )
			return this.specialCampaigns.seoOther;
		
		return this.specialCampaigns.websiteReferral;
		
		// 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 referrer
	 * @return object The SEO Host (its actually just domain minus the extension)
	 */
	getSeoHost: function() {
		var host = this.getDomain(this.referrer, true);
			host = host.split('.')[0].toLowerCase();

		return host;
	},

	/** 
	 * 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.referrer) )
				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.campaignHistory;
		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=/";
	},
	
	/**
	 * 
	 * @param string The Eloqua Data Lookup ID
	 */
	setEloquaDataLookup: function(id) {
		
	}
};

 
// 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){this.JSON={};}
(function(){function f(n){return n<10?'0'+n:n;}
if(typeof Date.prototype.toJSON!=='function'){Date.prototype.toJSON=function(key){return isFinite(this.valueOf())?this.getUTCFullYear()+'-'+
f(this.getUTCMonth()+1)+'-'+
f(this.getUTCDate())+'T'+
f(this.getUTCHours())+':'+
f(this.getUTCMinutes())+':'+
f(this.getUTCSeconds())+'Z':null;};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);}
text=String(text);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();


