/** 
 * @fileoverview This file is to be used for implementing Google Analytics on a website.
 * It is a wrapper class around the GA tracker class and allows you to add custom functionality
 * to GA tracking.
 *
 * @author Andre Wei andrewei@vkistudios.com
 * 
 * Copyright VKI Studios
 */

 /* Function List
  * Privileged Function list
  * addListener
  * getBaseDomain
  * addTrans
  * addItem
  * trackTrans
  * tagElements
  */

/* BEGIN: VKIGA Class */

/**
 * Construct a new VKIGA object.
 * @class This is the GA 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 VKIGA (crossDomainsList, trackDownloadsList, numDomainParts, devEnv) {

	var _vkiCookie = "__utmvki";
	var loc = document.location;
	var self = this;
	var _isIE = new RegExp(/MSIE/).test(navigator.userAgent);
	
	// set the base domain
	numDomainParts = -1*numDomainParts;
	var _baseDomain = loc.hostname.split('.').slice(numDomainParts).join(".");
	
	/**
	 * Pipe-delimited list of base domains to treat as cross-domain
	 * @private
	 * @type string
	 */
	var _crossDomainsList = "";
	
	if (crossDomainsList != null && typeof(crossDomainsList) == "string")
		_crossDomainsList = crossDomainsList;
	
	/**
	 * Comma-separated list of file extensions to track downloads for
	 * @private
	 * @type string
	 */
	var _trackDownloadsList = "";
	
	if (trackDownloadsList != null && typeof(trackDownloadsList) == "string")
		_trackDownloadsList = trackDownloadsList;
	
	/**
	 * Flag for development environment
	 * @private
	 * @type boolean
	 */
	 
	 var _devEnv = devEnv;
	 
	/* BEGIN: Private Functions */
	
	/**
	 * Adds x-domain parameters to the element
	 *
	 * @private
	 * @param {elem} elem HTML Node to add x-domain parameters to
	 */
	 
	function tagCrossDomain(elem) {
		_gaq.push(function () {
			var VKIPageTracker = _gat._getTrackerByName();
			
			var url, utmparams, utm, useHash, oldHTML;
			if (elem.nodeName == "FORM") {
				if (elem.method.toUpperCase() == 'GET' && _vkiga.isIE()) {
					url = VKIPageTracker._getLinkerUrl(elem.action);
					utmparams = self.extractUTMVars(url);
					
					for (utm in utmparams)
					{
						hidden = document.createElement('input');
						hidden.setAttribute('type', 'hidden');
						hidden.setAttribute('name', "cp" + utm);
						hidden.setAttribute('value', utmparams[utm]);
						elem.appendChild(hidden);
					}
				}
				else {
					useHash = (elem.action.search(/#/) > -1) ? false : true;
					
					url = VKIPageTracker._getLinkerUrl(elem.action, useHash);
					elem.action = url;
				}
			}
			else if (elem.nodeName == "A") {
				/* store old inner HTML because in IE, if the text inside the anchor tag matches the href attr, it will display the UTM linking info*/
				oldHTML = elem.innerHTML;
				useHash = (elem.hash == "") ? true : false;
				elem.href = VKIPageTracker._getLinkerUrl(elem.href, useHash);
				elem.innerHTML = oldHTML;
			}
		});
	}
	
	/**
	 *  Checks if order has already been sent or not.  Sets session cookie to track orders that have been sent.
	 *  
	 * @private
	 * @param {string} orderID unique order ID
	 */
	 
	function checkSetTrans (orderID) {
		// Check if this transaction has been sent to GA before and this is a reload of the thankyou page
		var strCookieName = _vkiCookie;
		var strCookieValue = 'e.' + orderID;
		var strControlCookie = readCookie(strCookieName) || '';
		var isNew = (strControlCookie.search(strCookieValue) == -1);
		createCookie(_vkiCookie, strCookieValue, 1);
		return isNew;
	}
	
	/**
	 *  Creates cookie
	 *  
	 * @private
	 * @param {string} name cookie name
	 * @param {string} value cookie value
	 * @param {string} days days until cookie expires
	 * @param {string} cookieDomain optional - domain to set the cookie for
	 */
	 
	function createCookie (name, value, days, cookieDomain) {
		var domain = "";
		var expires = "";
		
		if (days) {
			var date = new Date();
			date.setTime(date.getTime()+Math.ceil(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
	 *  
	 * @private
	 * @param {string} name cookie name
	 * @returns	value of the cookie, or null if cookie not set
	 * @type mixed
	 */
	 
	function readCookie (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
	 *  
	 * @private
	 * @param {string} name cookie name
	 * @param {string} cookieDomain optional - domain to set the cookie for
	 */
	 
	function eraseCookie (name, cookieDomain) {
		cookieDomain = cookieDomain || getDomainName();
		createCookie(name, "", -1, cookieDomain);
	}
	
	/* END: Private Functions */
	
	/* 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 GA 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) {
		try {
			orderID = (_devEnv) ? "QA-" + orderID : orderID;
			
			_gaq.push(['_addTrans', orderID, affiliate, total, tax, shipping, city, state, country]);
		}
		catch (err) {}
	}
	
	/**
	 *  Adds item to GA 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) {
		try {
			orderID = (_devEnv) ? "QA-" + orderID : orderID;
			_gaq.push(['_addItem', orderID, sku, productName, category, price, quantity]);
		}
		catch (err) {}
	}
	
	/**
	 *  Sends transaction tracking request to GA if the order hasn't already been sent
	 *  
	 * @privileged
	 * @param {string} orderID unique order ID
	 */
	this.trackTrans = function (orderID) {
		try {
			orderID = (_devEnv) ? "QA-" + orderID : orderID;
			if (checkSetTrans(orderID)) {
				_gaq.push(['_trackTrans']);
			}
		}
		catch (err) {}
	}
	
	/**
	 * Returns given query string with only query string parameters 
	 * specified in the given array
	 *
	 * @privileged
	 * @param {string} qs query string to modify
	 * @param {array} includeParams pipe-delimited string of query string parameter names to include
	 */
	this.includeQueryParams = function (qs, includeParams) {
		
		// if the list is empty, return the full query string
		if (includeParams == "")
			return qs;
		
		var re = RegExp("(\\?|&)(" + includeParams + ")=[^&]*", "gi");
		
		var matches = qs.match(re);
		
		if (matches == null)
			return "";
			
		for (var i = 0; i < matches.length; i++) {
			matches[i] = matches[i].substr(1);
		}
		
		return "?" + matches.join("&");
	}
	
	this.isIE = function () {
		return _isIE;
	}
	
	this.extractUTMVars = function (str, delimiter) {
		delimiter = (typeof delimiter == 'undefined') ? '&' : delimiter;
		
		var re = RegExp("__utm[^=]+=[^" + delimiter + "]*", "gi");
		
		var matches = str.match(re);
		var ret = new Object();
		var i, utm, utmval;
		
		if (matches != null) {
			for (i = 0; i < matches.length; i++) {
				utm = matches[i].split("=");
				utmval = utm.slice(1).join("=");
				ret[utm[0]] = utmval;
			}
		}
		
		return ret;
	}
	
	/* END: Priviledged Functions */
	
	/* BEGIN: Optional Functionality */
	
	/**
	 * Loops through links & forms and
	 * Appends GA cookie information to all anchor and form tags that are cross-domain links
	 * Adds on-click tracking to all anchor tags that link to a document type we want to track
	 *
	 * @privileged
	 */
	this.tagElements = function() {
		
		if (_crossDomainsList == "" && _trackDownloadsList == "")
			return;
		
		var anchors, anchor, forms, form = null;
		var i, j = 0;
		var regexp, patternDocslist = null;
		var oldHTML = '';
		var url, utmparams, utm, name, val, hidden, useHash = null;
			
		anchors = document.getElementsByTagName("a");
		forms = document.getElementsByTagName("form");
		
		/* compile regexps first to save processing time */
		var crossDomainRegexp = new RegExp("^https?://.*" + _crossDomainsList + "(/?.*)?");
		var patternDocslist = new RegExp("\\.(?:" + _trackDownloadsList + ")($|\\&|\\?|#)");
		var baseDomainRegexp = new RegExp(_baseDomain, "i");
		
		// loop through all anchor tags
		for (i = 0; i < anchors.length; i++) {
			anchor = anchors[i];
			
			// tag cross-domain links
			if (_crossDomainsList != "") {
				// if the link matches, append cookie information to link
				if (!baseDomainRegexp.test(anchor.href) && crossDomainRegexp.test(anchor.href)) {
					tagCrossDomain(anchor);
				}
			}
			
			// tag download links
			if (_trackDownloadsList != "") {
				if (patternDocslist.test(anchor.href)) {
					self.addListener(anchor, "mousedown", _vkiga.trackDownload);
				}
			}
		}
		
		// loop through all form tags
		if (_crossDomainsList != "") {
			for (i = 0; i < forms.length; i++) {
				form = forms[i];
				
				if (!baseDomainRegexp.test(form.action) && crossDomainRegexp.test(form.action)) {
					tagCrossDomain(form);
				}
			}
		}
	}
	
	/**
	 *  Sends page view to GA to track file downloads
	 *  
	 * @privileged
	 * @param {event} e DOM event
	 */
	 
	this.trackDownload = function (evnt) {
		
		var e = (evnt.srcElement) ? evnt.srcElement : this;
        while (e.tagName != "A") {
                e = e.parentNode;
        }
		
		var lnk = (e.pathname.charAt(0) == "/") ? e.pathname : "/" + e.pathname;
		
		var cat = 'Link Tracking';
		var action = 'File Downloaded';
		var label = '' ;
		
		if (e.search && e.pathname.indexOf(e.search) == -1) lnk += e.search;
		
		if (e.hostname !== location.hostname) {
			label = e.hostname + lnk;
		}
		else {
			label = lnk;
		}
		
		_gaq.push(['_trackEvent', cat, action, label]);
	}
	/* END: Optional Functionality */
}

var _vkiga = null;
var _gaq = _gaq || [];

/* BEGIN: initialize page tracking object */
(function () {
	try {
		
		/* BEGIN: Customization Variables */
		var devPropID = "UA-2647064-32";
		var prodPropID = "UA-2647064-32";
		var prodHostnames = new RegExp(/helpareporter.com/i); // regular expression of hostnames to consider part of production.  Otherwise we'll treat it as dev
		var numBaseDomainParts = 2; // number of parts in the base domain.  ie www.example.com = 2, www.example.co.uk = 3
		var GACrossDomainsList = ""; // pipe-delimited list of base domains to treat as cross-domain. ie. "vkistudios.com|vkistudios.net"
		var GADownloadsList = "pdf"; // pipe-delimited list of file extensions to treat as document download ie. "pdf|zip|doc"
		var includeQueryParams = ""; // pipe-delimited list of query parameters to include in pageviews.  If empty string, all query parameters will be allowed through
		/* END: Customization Variables */
		
		var GAWebPropID = '';
		var devEnv = true; // by default, set it to development environment
		
		var loc = document.location;
		
		if (loc.hostname.match(prodHostnames)) {
			GAWebPropID = prodPropID; //  Production GA Account
			devEnv = false;
		}
		else {
			GAWebPropID = devPropID; // Test GA Account
			devEnv = true;
		}
		
		var utmparams, utm, hash;
		
		_vkiga = new VKIGA(GACrossDomainsList, GADownloadsList, numBaseDomainParts, devEnv);
		
		if (_vkiga.isIE() && loc.search.search(/cp__utma=/) > -1) {
			hash = "#";
			utmparams = _vkiga.extractUTMVars(loc.search);
							
			for (utm in utmparams) {
				utmparams[utm] = utmparams[utm].replace("%28", "(");
				utmparams[utm] = utmparams[utm].replace("%29", ")");
				hash += utm + "=" + decodeURIComponent(utmparams[utm]) + "&";
			}
			
			loc.hash = hash;
		}
		
		_gaq.push(	['_setAccount', GAWebPropID],
					['_setDomainName', _vkiga.getBaseDomain()],
					['_setAllowAnchor', true]);
		
		/* OPTIONAL */
		// if cross-domain is enabled, tag all links
		if (GACrossDomainsList != "" || GADownloadsList != "") {
			if (GACrossDomainsList != "") {
				_gaq.push(['_setAllowLinker', true],
						  ['_setAllowHash', false]);
			}
				
			_vkiga.addListener(window, 'load', _vkiga.tagElements);
		}
		/* OPTIONAL */
		
		if (window.top == window.self) {
			
			/* Custom Variable: Visitor Status */
			if (document.strVisitorStatus) {
				_gaq.push(['_setCustomVar',
      				1,                   		// This custom var is set to slot #1.
      				'Visitor Status',      		// The name acts as a kind of category for the user activity.
      				document.strVisitorStatus,  // This is the value of the custom variable.
      				2                    		// Sets the scope to session-level.
   				]);
			}			
			
			/* Custom Variable: Account Type */
			if (document.strAccountType) {
				_gaq.push(['_setCustomVar',
      				2,                   		// This custom var is set to slot #2.
      				'Account Type',      		// The name acts as a kind of category for the user activity.
      				document.strAccountType,    // This is the value of the custom variable.
      				1                    		// Sets the scope to session-level.
   				]);
			}
			
			/* Custom Variable: Source Subscription Type */
			if (document.strSourceSubscriptionType) {
				_gaq.push(['_setCustomVar',
      				3,                   					// This custom var is set to slot #3.
      				'Source Subscription Type',      		// The name acts as a kind of category for the user activity.
      				document.strSourceSubscriptionType,    	// This is the value of the custom variable.
      				1                    					// Sets the scope to session-level.
   				]);
			}
			
			
			if (!document.strTrackPageView && includeQueryParams != "")
				document.strTrackPageView = loc.pathname + _vkiga.includeQueryParams(loc.search, includeQueryParams);
			
			if (document.strTrackPageView) {
				_gaq.push(['_trackPageview', document.strTrackPageView]);
			} else {
				_gaq.push(['_trackPageview']);
			}
			
		}
	} catch(err) {}
})();
/* END: initialize page tracking object */

(function() {
    var ga = document.createElement('script');     ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:'   == document.location.protocol ? 'https://ssl'   : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
