/**
 *	@author:	Danny Ng
 *	@company:	First Rate
 *	@version:	0.4.2b
 *	@modified:	29/10/09
 */
 
// Strip leading and trailing white-space
String.prototype.trim = function() { return this.replace(/^\s*|\s*$/g, ''); }

// Check if string is empty
String.prototype.empty = function() {
	if (this.length == 0)
		return true;
	else if (this.length > 0)
		return /^\s*$/.test(this);
}

// Breaks cookie into an object of keypair cookie values
function crumbleCookie(c)
{
	var cookie_array = (c) ? c.split(';') : document.cookie.split(';');
	var keyvaluepair = {};
	
	for (var cookie = 0; cookie < cookie_array.length; cookie++)
	{
		var key = cookie_array[cookie].substring(0, cookie_array[cookie].indexOf('=')).trim();
		var value = cookie_array[cookie].substring(cookie_array[cookie].indexOf('=')+1, cookie_array[cookie].length).trim();
		keyvaluepair[key] = value;
	}

	return keyvaluepair;
}

// Breaks query string into an object of keypair parameter values
function crumbleQS(qs, delimiter)
{
	var pure_qs = qs.substring(qs.indexOf('?')+1, qs.length).trim();
	var split_qs = (delimiter) ? pure_qs.split(delimiter) : pure_qs.split('&');
	var keyvaluepair = {};
	
	for (var i = 0; i < split_qs.length; i++)
	{
		var key = split_qs[i].substring(0, split_qs[i].indexOf('=')).trim();
		var value = split_qs[i].substring(split_qs[i].indexOf('=')+1, split_qs[i].length).trim();
		keyvaluepair[key] = (value.length == 0) ? null : value;		
	}
	
	return keyvaluepair;
}

/**
 *	Reads the acquisition logic from utmv cookie
 *
 *	@params		-	delimiter <string>
 *	@return		-	<object>
 *					=>	fr_source
 *					=>	fr_medium
 *					=>	fr_name
 *					=>	fr_term
 *					=>	fr_content
 *					=>	fr_date
 *
 *	@pre-condition	-	pageTracker is initialised properly
 *	@post-condition	-	return an object of logic properties
 */
function crumbleLogic(delimiter)
{
	var keyvaluepair = {};
	var crumbs = crumbleCookie();
	var logic_delimiter = (delimiter) ? delimiter : '|';
	
	if (crumbs['__utmv'])
	{
		var crumble_logic = decodeURIComponent(decodeURIComponent(crumbs['__utmv'])).match(/frAcquisition=(.*)/);
		if (crumble_logic && crumble_logic.length && crumble_logic.length == 2)
		{
			var data_sets = crumble_logic[1].split(logic_delimiter);
			for (var i = 0; i < data_sets.length; i++)
			{
				var key = data_sets[i].substring(0, data_sets[i].indexOf(':')).trim();
				var value = data_sets[i].substring(data_sets[i].indexOf(':')+1, data_sets[i].length).trim();
				keyvaluepair[key] = value;		
			}
			
			return keyvaluepair;
		}
	}
	
	return null;
}

// Adds string to the beginning of existing utmv
function unshiftVar(pt, str, delimiter)
{
	if (checkTracker(pt))
	{
		var current = decodeURIComponent(decodeURIComponent(crumbleCookie()['__utmv']));
		if (current)
		{			
			current = current.substring(current.indexOf('.')+1, current.length).trim();
			(delimiter) ? pt._setVar(str + delimiter + current) : pt._setVar(str + current);
		}
		else
			pt._setVar(str);
		
		return decodeURIComponent(crumbleCookie()['__utmv']);
	}
	
	return false;
}

// Appends string to the existing utmv
function appendVar(pt, str, delimiter)
{
	if (checkTracker(pt))
	{
		var current = decodeURIComponent(decodeURIComponent(crumbleCookie()['__utmv']));
						
		if (current)
		{
			current = current.substring(current.indexOf('.')+1, current.length).trim();
			(delimiter) ? pt._setVar(current + delimiter + str) : pt._setVar(current + str);
		}
		else
			pt._setVar(str);
		
		return decodeURIComponent(crumbleCookie()['__utmv']);
	}
	
	return false;
}

/**
 *	Google Analytics cookie holder for utma, utmb, utmz
 *
 *	@params		-	hostname <string>
 *	@return		-	<object>
 *					=>	domainhash
 *					=>	uniqueid
 *					=>	ftime
 *					=>	ltime
 *					=>	stime
 *					=>	sessions
 *					=>	gifrequest
 *					=>	user
 *					=>	source
 *					=>	medium
 *					=>	name
 *					=>	term
 *					=>	content
 *					=>	ctime
 *					=>	responses
 *
 *	@pre-condition	-	pageTracker initialised properly
 *	@post-condition	-	store object of Google cookie values based on domain hash
 */
function gaCookies(hostname)
{
	var values;
	//var hash_hostname = _gat.s(hostname);	// Google's domain hashing function
	var crumbs = crumbleCookie();
	
	for (var c in crumbs)
	{
		values = crumbs[c].split('.');
		//if (values[0] != hash_hostname)
		//	continue;

		switch(c)
		{
			// Format: domain-hash.unique-id.ftime.ltime.stime.session-counter
			case '__utma':
				this.domainhash = values[0];
				this.uniqueid = values[1];
				this.ftime = values[2];
				this.ltime = values[3];
				this.stime = values[4];
				this.sessions = values[5];
				break;
			// Format: domain-hash.gif-requests.10.stime
			case '__utmb':
				this.gifrequest = values[1];
				break;
			case '__utmv':
				if (values.length > 2)
				{
					values.shift();
					this.user = values.join('.');
				}
				else
					this.user = values[1];
				break;
			// Format: domain-hash.1222209815.28.4.utmcsr=X|utmccn=X|utmcmd=X|utmctr=X
			case '__utmz':
				var utms = /utm[a-z]+=(.)*/.exec(crumbs[c])[0];	// extract utms
				var split_utm = utms.match(/utm[a-z]+=[^\|]+/g);	// split individual utm
				for (var i = 0; i < split_utm.length; i++)
				{
					var key = split_utm[i].substring(0, split_utm[i].indexOf('='));
					var val = decodeURIComponent(split_utm[i].substring(split_utm[i].indexOf('=')+1, split_utm[i].length));
					val = val.replace(/^\(|\)$/g, '');
					switch(key)
					{
						case 'utmcsr':
							this.source = val;
							break;
						case 'utmcmd':
							this.medium = val;
							break;
						case 'utmccn':
							this.name = val;
							break;
						case 'utmctr':
							this.term = val;
							break;
						case 'utmcct':
							this.content = val;
							break;
						case 'utmgclid':
							this.gclid = val;
							break;
					}
				}
				this.ctime = values[1];
				this.responses = values[3];
				break;
		}
	}
}

// Safe way of getting cookie values
gaCookies.prototype.get = function(v) {	return (this[v]) ? decodeURIComponent(decodeURIComponent(this[v])) : null; }

/**
 *	Sets acquisition by referrer logic to utmv via _setVar() - always at the end
 *
 *	Acquisition Logic Syntax:
 *		frAcquisition=fr_source:<source>|fr_medium:<medium>|fr_name:<name>[|fr_term:<term>][|fr_content:<content>]|fr_ftime:<date>
 *		
 *	Custom URL Syntax:
 *		fr_source=<source>&fr_medium=<medium>[&fr_name=<name>][&fr_term=<term>][&fr_content=<content>]
 *	
 *	<source> 	::= campaign source (e.g. google, yahoo, newsletter)
 *	<medium> 	::= campaign medium (e.g. cpc, email, referral)
 *	<name>	 	::= campaign name (e.g Search - Product, November08)
 *	<term>	 	::= campaign keyword (e.g. {YSMKEY}, {keyword})
 *	<content>	::= campaign content (e.g. island ad, banner ad, skyscraper)
 *	<date>		::= arrival date (yyyymmdd)
 *
 *	@params		-	pageTracker <object>, hostname <string>
 *	@return		-	<void>
 *
 *	@pre-condition	-	pageTracker initialised properly
 *	@post-condition	-	acquisition logic set in utmv
 */
function frAcquisitionByReferrer(pageTracker, hostname)
{
	var campaign = new gaCookies(hostname);
	
	// Make sure pageTracker is initialised and reference the correct cookie domains
	if (checkTracker(pageTracker))
	{
		var logic = '';
		var crumbs = crumbleCookie();
		var logic_key = 'frAcquisition=';
		var qs = crumbleQS(document.location.toString());
		
		// Acquisition data
		var fr_source = (qs['fr_source']) ? qs['fr_source'] : campaign.get('source');
		var fr_medium = (qs['fr_medium']) ? qs['fr_medium'] : campaign.get('medium');
		var fr_name = (qs['fr_name']) ? qs['fr_name'] : campaign.get('name');
		var fr_term = (qs['fr_term']) ? qs['fr_term'] : campaign.get('term');
		var fr_content = (qs['fr_content']) ? qs['fr_content'] : campaign.get('content');
		var date = new Date();
		var fr_date = date.getUTCFullYear().toString() + ((date.getUTCMonth() < 9) ? '0' + (date.getUTCMonth()+1).toString() : (date.getUTCMonth()+1).toString()) + ((date.getUTCDate() < 10) ? '0' + date.getUTCDate().toString() : date.getUTCDate().toString());
		
		// UTM cookie data
		var utmv = campaign.get('user');		
					
		// Check for acquisition logic
		if (utmv && utmv.match(logic_key))
		{
			var crumble_logic = crumbleLogic();
			
			// Overwrite if new source is different to direct
			if ((crumble_logic['fr_source'] && crumble_logic['fr_source'].toLowerCase() == 'direct') &&
				(fr_source.toLowerCase() != 'direct'))
			{
				// Generate logic
				logic = logicGenerator(fr_source, fr_medium, fr_name, fr_term, fr_content, fr_date);				
				pageTracker._setVar(utmv.replace(/frAcquisition=(.*)/, logic));
				//alert('1)Your UTMV Value was set to:\n' + campaign.get('user').replace(/frAcquisition=(.*)/, logic));
			}
			else
			{
				cleanLogic(utmv, pageTracker, hostname);	// clean previous bugs
				return;
			}
		}
		else
		{
			var utmv_delimiter = '/';	
			
			// Check Adwords. Don't really need to check query string as genuine adwords traffic would have utmgclid cookie
			if (campaign.get('gclid') || crumbleQS(document.location.toString())['gclid'])
			{
				// Set google/cpc
				fr_source = 'google';
				fr_medium = 'cpc';
			}
			
			// Generate logic
			logic = logicGenerator(fr_source, fr_medium, fr_name, fr_term, fr_content, fr_date);

			// Check _setVar()
			if (crumbs['__utmv'])
			{
				// Always append acquisition logic with delimiter
				var res = appendVar(pageTracker, logic, utmv_delimiter);
				//alert('2)Your UTMV Value was set to:\n' + res);
			}
			else
			{
				// Write acquisition logic
				pageTracker._setVar(logic);
				//alert('3)Your UTMV value was set to:\n' + logic);
			}
		}		
	}
}

/**
 *	Helper method to generate logic
 *
 *	@params		-	fr_source <string>, fr_medium <string>, fr_name <string>, fr_term <string>, fr_content <string>, fr_date <string>
 *	@return		-	logic <string>
 */
function logicGenerator(fr_source, fr_medium, fr_name, fr_term, fr_content, fr_date)
{
	var logic_key = 'frAcquisition=';
	var logic_delimiter = '|';
	var logic = [ (fr_source) ? 'fr_source:' + fr_source : null, (fr_medium) ? 'fr_medium:' + fr_medium : null, (fr_name) ? 'fr_name:' + fr_name : null, (fr_term) ? 'fr_term:' + fr_term : null, (fr_content) ? 'fr_content:' + fr_content : null, 'fr_date:' + fr_date].join(logic_delimiter);
	logic = logic.replace(/\|{2,}/, '|'); // strip | for null values
	logic = logic_key + logic;
	
	return decodeURIComponent(decodeURIComponent(logic));
}

// Hack function to regenerate logic based on cookies & query string directly
function regenerateLogic(hostname)
{
	var campaign = new gaCookies(hostname);
	var qs = crumbleQS(document.location.toString());
		
	// Acquisition data
	var fr_source = (qs['fr_source']) ? qs['fr_source'] : campaign.get('source');
	var fr_medium = (qs['fr_medium']) ? qs['fr_medium'] : campaign.get('medium');
	var fr_name = (qs['fr_name']) ? qs['fr_name'] : campaign.get('name');
	var fr_term = (qs['fr_term']) ? qs['fr_term'] : campaign.get('term');
	var fr_content = (qs['fr_content']) ? qs['fr_content'] : campaign.get('content');
	var date = new Date();
	var fr_date = date.getUTCFullYear().toString() + ((date.getUTCMonth() < 9) ? '0' + (date.getUTCMonth()+1).toString() : (date.getUTCMonth()+1).toString()) + ((date.getUTCDate() < 10) ? '0' + date.getUTCDate().toString() : date.getUTCDate().toString());
	
	var utmv_delimiter = '/';	
			
	// Check Adwords. Don't really need to check query string as genuine adwords traffic would have utmgclid cookie
	if (campaign.get('gclid') || crumbleQS(document.location.toString())['gclid'])
	{
		// Set google/cpc
		fr_source = 'google';
		fr_medium = 'cpc';
	}
	
	// Generate logic
	return logicGenerator(fr_source, fr_medium, fr_name, fr_term, fr_content, fr_date);
}

/**
 *	Destroys acquisition logic
 *
 *	@params		-	utmv <string>, pageTracker <object>
 *	@return		-	<void>
 */
function destroyLogic(utmv, pageTracker, hostname)
{
	if (checkTracker(pageTracker))
	{
		var replace_regex = /frAcquisition(.*)fr_date:\d{8}/;
		utmv = utmv.replace(replace_regex, '');	// strip logic only
		if (!utmv.empty())
			pageTracker._setVar(utmv);
		else
			pageTracker._setVar(regenerateLogic(hostname));
	}
}

/**
 *	Cleans acquisition logic
 *
 *	@params		-	utmv <string>, pageTracker <object>, hostname <string>
 *	@return		-	<void>
 */
function cleanLogic(utmv, pageTracker, hostname)
{
	var multiple_logic = /frAcquisition/g;
	var incomplete_logic_1 = /frAcquisition=\|fr_date/g;
	
	if (((utmv.match(incomplete_logic_1) != null) && (utmv.match(incomplete_logic_1).length >= 1)) ||
		((utmv.match(multiple_logic) != null) && (utmv.match(multiple_logic).length > 1)))
	{
			destroyLogic(utmv, pageTracker, hostname);
	}
}

/**
 *	Checks whether pageTracker is an object (initialised) or not
 *
 *	@params		-	pageTracker <object>
 *	@return		-	<boolean>
 */
function checkTracker(pageTracker) { return (typeof pageTracker == 'object') ? true : false; }

/*****************************************# DEBUG #*****************************************/

function printObject(o)
{
	var output = '';
	for (var key in o)
	{
		if (typeof o[key] == 'string')
			output += key + ': \'' + o[key] + '\',<br />';
		else if (typeof o[key] == 'object')
			printObject(o[key]);
	}
	
	return output;
}

/*****************************************# Custom Ezibuy #*****************************************/

// Check if visitor is an existing customer
function isExistingCustomer(str) {	return (/Existing Customer/g.test(str)) ? true : false; }

// Cleans customer utmv cookie that has multiple 'Existing Customer/'
function cleanCustomerCookie(pageTracker)
{
	if (checkTracker(pageTracker))
	{
		if (crumbleCookie()['__utmv'])
		{
			var cookie = decodeURIComponent(decodeURIComponent(crumbleCookie()['__utmv']));
			if (/(Existing Customer\/){2,}/g.test(cookie))
			{
				cookie = cookie.substring(cookie.lastIndexOf('Existing Customer'));
				pageTracker._setVar(cookie);
				return true;
			}
		}
	}

	
	return false;
}

// Tags visitor as existing customer if is an existing customer
function tagExistingCustomer(pageTracker)
{
	if (checkTracker(pageTracker))
	{
		if (crumbleCookie()['__utmv'])
		{
			var cookie = decodeURIComponent(decodeURIComponent(crumbleCookie()['__utmv']));
			if (!isExistingCustomer(cookie))
			{
				unshiftVar(pageTracker, 'Existing Customer');
				return true;
			}
		}
	}
	
	return false;
}
