/*

 * @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
 
 */

 /* Function List
  * Privileged Function list
  * addListener
  * getBaseDomain
  * addTrans
  * addItem
  * trackTrans
  * tagElements
  */
 
var GAWebPropID = '';

if (location.hostname.search(/vkistudios.net/) > -1)
	var GAWebPropID = "UA-13228725-1"; // Test GA account to track data to
else
	var GAWebPropID = "UA-9667366-1"; // Production GA account to track data to
  
var GACrossDomainsList = "safekids.org,convio.net"; // comma-separated list of base domains to treat as cross-domain.
var GADownloadsList = "pdf|doc|zip"; // pipe-separated list of file extensions to treat as document download
var numBaseDomainParts = 2; // number of parts in the base domain.  ie www.example.com = 2, www.example.co.uk = 3

/* 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) {

	var baseDomain = "";
	var numBaseDomainParts = numDomainParts;
	var vkiCookie = "__utmvki";
	this.loc = document.location;
	
	// set the base domain
	
	var splitHost = this.loc.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;
	
	/**
	 * Comma-separated list of file extensions to track downloads for
	 * @private
	 * @type string
	 */
	var downloadsList = "";
	
	if (trackDownloadsList != null && typeof(trackDownloadsList) == "string")
		downloadsList = trackDownloadsList;
	
	/* 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 {
			VKIPageTracker._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 {
			VKIPageTracker._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} unique order ID
	 */
	this.trackTrans = function (orderID) {
		try {
			if (this.checkSetTrans(orderID)) {
				VKIPageTracker._trackTrans();
			}
		}
		catch (err) {}
	}
	
	/**
	 *  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 GA 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);
	}
	
	/**
	 *  Splits query string parameters and stores key/value in assoc array
	 *  
	 * @privileged
	 * @param {string} url
	 */
	this.splitQS = function (url) {		
		
		var url = url.substring(url.indexOf('?') + 1);
		var params = url.split('&');
		var delimPos;
		var ret = new Object();
		
		for (var i = 0; i < params.length; i++) {
			delimPos = params[i].indexOf('=');
			name = params[i].substring(0, delimPos);
			val = params[i].substring(delimPos + 1);
			ret[name] = val;
		}
		
		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() {
		
		var anchors, anchor, forms, form = null;
		var domainsList = [];
		var i, j = 0;
		var regexp, patternDocslist = null;
		var oldHTML = '';
		var url, params, name, val, hidden, useHash = null;
		
		if (typeof(VKIPageTracker) == "object") {
			// check if getElementsByTagName function exists and we are doing cross-domain tracking
			if ((typeof(document.getElementsByTagName) == "function" || typeof(document.getElementsByTagName) == "object")) {
				anchors = document.getElementsByTagName("a");
				forms = document.getElementsByTagName("form");
				
				if (crossDomains != "")
					domainsList = crossDomains.split(",");
				
				// loop through all anchor tags
				for (i = 0; i < anchors.length; i++) {
					anchor = anchors[i];
					
					// tag cross-domain links
					if (crossDomains != "") {
						// 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("^https?://.*" + domainsList[j] + "(/?.*)?");
								
								// if the link matches, append cookie information to link
								if (regexp.test(anchor.href)) {
									/* 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 = anchor.innerHTML;
									useHash = (anchor.hash == "") ? true : false;
									anchor.href = VKIPageTracker._getLinkerUrl(anchor.href, useHash);
									anchor.innerHTML = oldHTML;
								}
							}
						}
					}
					
					// tag download links
					if (downloadsList != "") {
						patternDocslist = new RegExp("\\.(?:" + downloadsList + ")($|\\&|\\?)");
						
						if (patternDocslist.test(anchor.href)) {
							_vkiga.addListener(anchor, "click", _vkiga.trackDownload);
							
							if (anchor.target != "_blank" && anchor.onclick == null) {
								
								anchor.onclick = function (e) {
										if (!e) var e = window.event;
										
										e = (e.srcElement) ? e.srcElement : this;
										setTimeout(function(){_vkiga.loc.href = e.href}, 500);
										
										return false;
									};
							}
						}
					}
				}
				
				// loop through all form tags
				if (crossDomains != "") {
					for (i = 0; i < forms.length; i++) {
						form = forms[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("^https?://.*" + domainsList[j] + "(/?.*)?");
								
								// if the link matches, append cookie information to link
								if (regexp.test(form.action)) {
									
									
									
									if (form.method.toUpperCase() == 'GET') {
										url = VKIPageTracker._getLinkerUrl(form.action);
										params = _vkiga.splitQS(url);
										for (name in params)
										{
											if (name.search('__utm') > -1) {
												val = params[name];
												
												hidden = document.createElement('input');
												hidden.setAttribute('type', 'hidden');
												hidden.setAttribute('name', name);
												hidden.setAttribute('value', val);
												form.appendChild(hidden);
											}
										}
									}
									else {
										useHash = (form.action.search(/#/) > -1) ? false : true;
										url = VKIPageTracker._getLinkerUrl(form.action, useHash);
										form.action = url;
									}
								}
							}
						}
					}
				}
				
			}
		}
	}
	
	/**
	 *  Sends page view to GA to track file downloads
	 *  
	 * @privileged
	 * @param {event} DOM event
	 */
	 
	this.trackDownload = function (e) {
		var targ;
		if (!e) var e = window.event;
		if (e.target) targ = e.target;
		else if (e.srcElement) targ = e.srcElement;
		if (targ.nodeType == 3) // defeat Safari bug
			targ = targ.parentNode;
		
		var lnk = (targ.pathname.charAt(0) == "/") ? targ.pathname : "/" + targ.pathname;
		
		if (targ.search && targ.pathname.indexOf(targ.search) == -1) lnk += targ.search;
		
		if (targ.hostname !== location.hostname) lnk = "/external/" + targ.hostname + lnk;
		
		if (typeof(VKIPageTracker) == "object") {
			try {
				VKIPageTracker._trackPageview(lnk);
			} catch (err) {}
		}
	}
	/* END: Optional Functionality */
}

var _vkiga = new VKIGA(GACrossDomainsList, GADownloadsList, numBaseDomainParts);

/* BEGIN: initialize page tracking object */

try {
	
	/* Check if there are any utm x-domain params in the query string & if they are url-encoded */
	
	if (_vkiga.loc.search.search(/utmccn.*%7C/) > -1) {
		var params = _vkiga.splitQS(_vkiga.loc.search);
		var hash = "#";
		
		for (var name in params) {
			if (name.search('__utm') > -1) {
				if (hash != '#')
					hash += '&';
					
				hash += name + '=' + decodeURIComponent(params[name]);
			}
		}
		
		if (hash != '#') {
			_vkiga.loc.hash = hash;
		}
	}
	
	var VKIPageTracker = _gat._getTracker(GAWebPropID);
	VKIPageTracker._setDomainName("." + _vkiga.getBaseDomain());
	VKIPageTracker._setAllowHash(false);
	VKIPageTracker._setAllowAnchor(true);
	
	/* OPTIONAL */
	// if cross-domain is enabled, tag all links
	if (GACrossDomainsList != "" || GADownloadsList != "") {
		if (GACrossDomainsList != "")
			VKIPageTracker._setAllowLinker(true);
			
		_vkiga.addListener(window, 'load', _vkiga.tagElements);
	}
	/* OPTIONAL */
	
	if (CONVIO.referrer.length > 0) {
		VKIPageTracker._setReferrerOverride(CONVIO.referrer);
	}	 
	
	if (document.strTrackPageView) {
		VKIPageTracker._trackPageview(document.strTrackPageView);
	} else {
		VKIPageTracker._trackPageview();
	}
} catch(err) {}

/* END: initialize page tracking object */
