/** 
 * @fileoverview This file is to be used for implementing Urchin on a website.
 * It is a wrapper class around the Urchin tracker class and allows you to add custom functionality
 * to Urchin tracking.
 *
 * @author Andre Wei andrewei@vkistudios.com
 *
 * Copyright VKI Studios
 */

 /* Function List
  * Privileged Function list
  * addListener
  * getBaseDomain
  * addTrans
  * addItem
  * trackTrans
  * tagCrossDomainLinks
  */
  
var UrchinCrossDomainsList = ""; // comma-separated list of base domains to treat as cross-domain.
var numBaseDomainParts = 2; // number of parts in the base domain.  ie www.example.com = 2, www.example.co.uk = 3

/* BEGIN: VKIUrchin Class */

/**
 * Construct a new VKIUrchin object.
 * @class This is the Urchin wrapper class
 * @constructor
 * @param {string} crossDomainsList Comma-separated list of base domains to treat as cross-domain
 * @param {int} numDomainParts Number of parts in the base domain
 * @returns A new VKI tracker
 */
	  
function VKIUrchin (crossDomainsList, numDomainParts) {

	var self = this;
	var version = "1.7";
	var baseDomain = "";
	var numBaseDomainParts = numDomainParts;
	var vkiCookie = "__utmvki";
	var tranx = new Object();
	tranx['orderID'] = '';
	tranx['affiliate'] = '';
	tranx['total'] = '';
	tranx['tax'] = '';
	tranx['shipping'] = '';
	tranx['city'] = '';
	tranx['state'] = '';
	tranx['country'] = '';
	tranx['items'] = new Array();
	
	var formURL;
	var formLoadTime;
	var formLoadCount;
	var dl;
	
	this.formURL = "";
	this.formLoadTime = 0;
	this.formLoadCount = 0;
	this.dl = document.location;
	
	// set the base domain
	
	var splitHost = this.dl.hostname.split('.');
	
	for (var i = 1; i <= numBaseDomainParts; i++) {
		
		baseDomain = '.' + splitHost[splitHost.length - i] + baseDomain;
	}
	
	baseDomain = baseDomain.substr(1);
	
	/**
	 * Comma-separated list of base domains to treat as cross-domain
	 * @private
	 * @type string
	 */
	var crossDomains = "";
	
	if (crossDomainsList != null && typeof(crossDomainsList) == "string")
		crossDomains = crossDomainsList;
	
	/* BEGIN: Privileged Functions */
	
	/**
	 * Returns the base domain of the website
	 *
	 * @privileged
	 */
	this.getBaseDomain = function() {
		return baseDomain;
	}
	
	/**
	 *  Adds event handler for specified event to an element
	 *  
	 * @privileged
	 * @param {object} element Element to add event listener to
	 * @param {string} type Event to listen for.  Do not prepend event with 'on', as the functions automatically prepends it
	 * @param {object} expression Javascript function to execute on event.  Can be either a function name or anonymous function
	 * @param {boolean} bubbling Sets whether to register the event on bubbling phase (true) or capturing phase (false).  Only applies to W3C compliant browsers.
	 * @returns	True on success, false on failure
	 * @type boolean
	 */
	this.addListener = function (element, type, expression, bubbling) {
		bubbling = bubbling || false;
		
		if (window.addEventListener) { // Standard
			element.addEventListener(type, expression, bubbling);
			return true;		
		} else if(window.attachEvent) { // IE
			element.attachEvent('on' + type, expression);
			return true;
		} else
			return false;
	}
	
	/**
	 *  Adds transaction to Urchin tracking object
	 *  
	 * @privileged
	 * @param {string} unique order ID
	 * @param {string} affiliate store
	 * @param {string} order total excluding taxes and shipping
	 * @param {string} tax amount
	 * @param {string} shipping amount
	 * @param {string} city of customer
	 * @param {string} state of customer
	 * @param {string} country of customer
	 */
	 
	this.addTrans = function (orderID, affiliate, total, tax, shipping, city, state, country) {
		tranx['orderID'] = orderID;
		tranx['affiliate'] = affiliate;
		tranx['total'] = total;
		tranx['tax'] = tax;
		tranx['shipping'] = shipping;
		tranx['city'] = city;
		tranx['state'] = state;
		tranx['country'] = country;
		tranx['items'] = new Array();
	}
	
	/**
	 *  Adds item to Urchin tracking object
	 *  
	 * @privileged
	 * @param {string} unique order ID
	 * @param {string} unique SKU/identifier of the product
	 * @param {string} descriptive product name
	 * @param {string} category of product
	 * @param {string} unit price of product
	 * @param {string} quantity purchased
	 */
	this.addItem = function (orderID, sku, productName, category, price, quantity) {
		var count = tranx['items'].length;
		
		tranx['items'][count] = new Object();
		tranx['items'][count]['orderID'] = orderID;
		tranx['items'][count]['sku'] = sku;
		tranx['items'][count]['productName'] = productName;
		tranx['items'][count]['category'] = category;
		tranx['items'][count]['price'] = price;
		tranx['items'][count]['quantity'] = quantity;
	}
	
	/**
	 *  Sends transaction tracking request to Urchin if the order hasn't already been sent
	 *  
	 * @privileged
	 * @param {string} unique order ID
	 */
	this.trackTrans = function (orderID) {
		try {
			if (orderID == tranx['orderID'] && this.checkSetTrans(orderID)) {
				
				var existingUTMTrans = document.getElementById("utmtrans");
				
				if (existingUTMTrans != null) {
					var existingUTMForm = existingUTMTrans.parentNode;
					
					if (existingUTMForm.tagName.toLowerCase() == "form") {
						existingUTMForm.parentNode.removeChild(existingUTMForm);
					}
				}
				
				var item = null;
				var formHTML = "<form style='display:none;' name='utmform'><textarea id='utmtrans'>\n";
				
				formHTML += 'UTM:T|' + tranx['orderID'] + '|' + tranx['affiliate'] + '|' + tranx['total'] + '|' + tranx['tax'] + '|' + tranx['shipping'] + '|' + tranx['city'] + '|' + tranx['state'] + '|' + tranx['country'] + "\n";
				for (var i = 0; i < tranx['items'].length; i++)
				{
					item = tranx['items'][i];
					formHTML += 'UTM:I|' + item['orderID'] + '|' + item['sku'] + '|' + item['productName'] + '|' + item['category'] + '|' + item['price'] + '|' + item['quantity'] + "\n";
				}
				
				formHTML += '</textarea></form>';
				document.write(formHTML);
				__utmSetTrans();
			}
		}
		catch (e) {}
	}
	
	/**
	 *  Checks if order has already been sent or not.  Sets session cookie to track orders that have been sent.
	 *  
	 * @privileged
	 * @param {string} unique order ID
	 */
	 
	this.checkSetTrans = function (orderID) {
		// Check if this transaction has been sent to Urchin before and this is a reload of the thankyou page
		var strCookieName = vkiCookie;
		var strCookieValue = 'e.' + orderID;
		var strControlCookie = this.readCookie(strCookieName) || '';
		var isNew = (strControlCookie.search(strCookieValue) == -1);
		this.createCookie(vkiCookie, strCookieValue, 1);
		return isNew;
	}
	
	/**
	 *  Creates cookie
	 *  
	 * @privileged
	 * @param {string} cookie name
	 * @param {string} cookie value
	 * @param {string} days until cookie expires
	 * @param {string} optional - domain to set the cookie for
	 */
	 
	this.createCookie = function (name, value, days, cookieDomain) {
	
		var domain = "";
		var expires = "";
		
		if (days) {
			var date = new Date();
			date.setTime(date.getTime()+(days*24*60*60*1000));
			var expires = " expires="+date.toGMTString() + ";";
		}
		
		if (typeof(cookieDomain) != 'undefined')
			domain = " domain=" + cookieDomain + "; ";
		
		document.cookie = name + "=" + value + ";" + expires + domain + "path=/";
	}
	
	/**
	 *  Reads cookie
	 *  
	 * @privileged
	 * @param {string} cookie name
	 * @returns	value of the cookie, or null if cookie not set
	 * @type mixed
	 */
	 
	this.readCookie = 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;
	}

	/**
	 *  Deletes cookie
	 *  
	 * @privileged
	 * @param {string} cookie name
	 */
	 
	this.eraseCookie = function (name, cookieDomain) {
		cookieDomain = cookieDomain || getDomainName();
		this.createCookie(name, "", -1, cookieDomain);
	}

	/* END: Priviledged Functions */
	
	/* BEGIN: Optional Functionality */
	
	this.tagCrossDomainLinks = function() {
		
		// check if getElementsByTagName function exists and we are doing cross-domain tracking
		if ((typeof(document.getElementsByTagName) == "function" || typeof(document.getElementsByTagName) == "object") && crossDomains != "") {
			anchors = document.getElementsByTagName("a");
			domainsList = crossDomains.split(",");
			
			// loop through all anchor tags
			for (i = 0; i < anchors.length; i++) {
				anchor = anchors[i];
				
				// loop through all our list of cross-domains
				for (j = 0; j < domainsList.length; j++) {
					// don't tag links to this base domain
					
					if (baseDomain != domainsList[j]) {
						regexp = new RegExp("^http://.*" + domainsList[j] + "(/?.*)?");
						
						// if the link matches, append cookie information to link
						if (regexp.test(anchor.href)) {
							anchor.href = "javascript:__utmLinker('" + anchor.href + "', true);";
						}
					}
				}
			}
		}
	}
	
	/* END: Optional Functionality */
	
	/* BEGIN: Custom Functionality */
	
	this.onFormLoad = function (formURL) {
		self.formURL = this.scrubString(formURL);
		self.formLoadTime = new Date().getTime();
		
		var path = self.dl.pathname;
		var query = self.dl.search;
		
		if (formURL == '/primary/used-car-quote/request-complete')
			this.leadSubmitted('Used Car', 'Primary');
		else if (formURL == '/primary/finance-quote/request-complete')
			this.leadSubmitted('Finance Quote', 'Primary');
		
		try {
			if (path.charAt(path.length - 1) != "/")
				urchinTracker(path + formURL + query);
			else
				urchinTracker(formURL + query);
			
			if (formURL.search(/error/) == -1)
				this.fieldChanged('started');
			else {
				this.fieldChanged('error');
			}
			
		} catch (e) {}
		
		self.formLoadCount++;
	}
	
	this.newCarQuoteComplete = function () {
		var path = self.dl.pathname;
		var vurl = "/primary/new-car-quote/request-complete";
		
		this.leadSubmitted('New Car', 'Primary');
		
		try {
			if (path.charAt(path.length - 1) != "/")
				vurl = path + vurl;
			
			urchinTracker(vurl);
		} catch (e) {}
	}
	
	this.leadSubmitted = function (leadType, formType) {
		try {
			__utmTrackEvent("Leads", "Urchin Submitted", leadType + " - " + formType);
		} catch (e) {}
	}
	
	this.usedCarQuoteMouseTrapComplete = function () {
		this.leadSubmitted('Used Car', 'MouseTrap');
		this.mouseTrapComplete("/mousetrap/used-car-quote-request");
		urchinTracker('/mousetrap/used-car-quote-request-complete');
	}
	
	this.financeQuoteMouseTrapComplete = function () {
		this.leadSubmitted('Finance Quote', 'MouseTrap');
		this.mouseTrapComplete("/mousetrap/auto-loan-request");
		urchinTracker('/mousetrap/auto-loan-request-complete');
	}
	
	this.multiQuoteMouseTrapComplete = function () {
		this.leadSubmitted('New Car', 'MultiQuote');
		this.mouseTrapComplete("/mousetrap/multi-quote-request");
	}
	
	this.mouseTrapComplete = function (formURL) {
		try {
			__utmTrackEvent("MouseTrap", "Completed", formURL);
		} catch (e) {}
	}
	
	this.fieldChanged = function (fieldName) {
		fieldName = this.scrubString(fieldName);
		try {
			urchinTracker("/form-field" + self.formURL + "/" + fieldName);
		} catch (e) {}
	}
	
	this.formCompleted = function (btnClicked) {
		
		var action = "";
		var elapsedTime = "";
		
		if (btnClicked.toLowerCase() == 'submit')
			action = 'Submitted';
		else
			action = 'Skipped';
		
		if (self.formURL.search(/mousetrap/i) > -1 && action == 'Skipped') {
			try {
				__utmTrackEvent("MouseTrap", action, self.formURL);
			} catch (e) {}
		}
		
		urchinTracker("/form-field" + self.formURL + "/" + action);
		
		try {
			elapsedTime = Math.round((new Date().getTime() - self.formLoadTime)/1000);
			__utmTrackEvent("Forms", "Time to Complete", self.formURL, elapsedTime);
		} catch (e) {}
	}
	
	this.tryAnother = function (btnClicked) {
		btnClicked = this.scrubString(btnClicked);
		
		try {
			urchinTracker(self.formURL + "/try-another-" + btnClicked);
			this.fieldChanged('try-another-' + btnClicked);
		} catch (e) {}
	}
	
	this.errors = function (errors) {
		var i = 0;
		
		try {
			for (i = 0; i < errors.length; i++) {
				__utmTrackEvent("Errors", errors[i], self.formURL);
			}
		} catch (e) {}
	}
	
	this.scrubString = function (str) {
		str = str.replace(/\s+/ig, "_");
		str = str.replace(/[^A-Za-z0-9_/-]+/ig, "");
		return str;
	}
	
	this.recordLandingPage = function () {
		var params = ['(?:make|mk)', '(?:model|md)', 'location_state', 'location_city'];
		var idx;
		var qs = '';
		var matches;
		var lp = document.location.pathname;
		
		if (this.readCookie("__utmc") == null || this.readCookie("__utmb") == null) {
			if (this.readCookie("__utmlp") !== null)
				this.eraseCookie("__utmlp", _udn);
			
			for (idx in params) {
				if ((matches = document.location.search.match("(" + params[idx] + "=[^&]*)")) !== null)
					qs += "&" + matches[0];
			}
			
			if (qs != '') {
				lp = lp + "?" + qs.substr(1,qs.length);
			}
			
			this.createCookie("__utmlp",  lp , 0.1, _udn); 
		}
	}
	
	/* END: Custom Functionality */
	
}

var _vkiurchin = new VKIUrchin(UrchinCrossDomainsList, numBaseDomainParts);

/* BEGIN: initialize page tracking object */

try {
		
	_udn = "." + _vkiurchin.getBaseDomain();
	_uhash = "off";
	
	_vkiurchin.recordLandingPage();
	
	/* OPTIONAL */
	// if cross-domain is enabled, tag all links
	if (UrchinCrossDomainsList != "") {
		_ulink = 1;
		_uanchor = 1;
		_vkiurchin.addListener(window, 'load', _vkiurchin.tagCrossDomainLinks);
	}
	/* OPTIONAL */
	
	_vkiurchin.addListener(window, 'load', function () {
		if (typeof vkiFormLoaded == 'undefined' || !vkiFormLoaded) {
			if (document.strUserDefined) {
				__utmSetVar(document.strUserDefined);
			}
			
			if (document.strTrackPageView) {
				urchinTracker(document.strTrackPageView);
			} else {
				urchinTracker();
			}
		}
	});
} catch(e) {}

/* END: initialize page tracking object */
