// --------------------------------------------------------------------------------
// ow_analytics.js
// Travis Musika
// Contains functionality to provide client-side analytics services.
// --------------------------------------------------------------------------------
///<reference path="ow_util.js">

// OneWeb.Analytics namespace
OneWeb.Analytics = {

	"TRACK_DOWNLOAD_CLASS": "trackDownload",
	"TRACK_EXTERNAL_CLASS": "trackExternal",
	"TRACK_MAILTO_CLASS": "trackMailTo",
	"TRACK_DOWNLOAD_EVENTARGS": "OneWeb,Download,{address}",
	"TRACK_EXTERNAL_EVENTARGS": "OneWeb,ExternalLink,{address}",
	"TRACK_FORM_SUBMIT_EVENTARGS": "OneWeb,Submission,{address}",
	"TRACK_MAILTO_EVENTARGS": "OneWeb,MailTo,{address}",

	"settings": {}, 		// settings will be populated dynamically by the web page
	"includeSubDirs": false,
	"providers": [],
	"trackingClasses": {},

	"OneWebActionMethod": {
		///<summary>Enumerated value defining the method used for tracking OneWeb events</summary>
		"PageView": 0,
		"Event": 1
	},

	//#region Address/Link Tracking

	// --------------------------------------------------------------------------------
	// formatLink()
	"formatLink": function(address, fileOnly) {
		/// <summary>Formats the href address into a link address trackable as a page view.</summary>
		///	<param name="address">address to be parsed</param>
		///	<param name="fileOnly">should it use the full path of the address, or just the file name</param>
		///	<returns>string</returns>
		var host = "", query = "", user = "", i = 0;

		if (address == null || address == "") return "/";
		if (address.indexOf("://") > 0)
			address = address.substring(address.indexOf("://") + 3);
		else if (address.indexOf(":") > 0)
			address = address.substring(address.indexOf(":") + 1);
		if (address.indexOf("?") > 0) {
			query = address.substring(address.indexOf("?"), address.length);
			address = address.substring(0, address.indexOf("?"));
		}
		if (address.charAt(0) != "/") {
			if ((i = address.indexOf("/")) < 0) {
				host = address;
				address = "";
			} else {
				host = address.substring(0, i);
				address = address.substring(i, address.length);
			}
			if ((i = host.indexOf("@")) > 0) {
				// for an address with a user, switch the host/user parts
				user = "/" + host.substring(0, i);
				host = host.substring(i + 1, host.length);
			}
			if (document.location.hostname == host) host = "";

			// reformat the domain name
			host = host.replace(/\./g, "_");
		}
		// add beginning slash if necessary
		if (address.charAt(0) != "/") address = "/" + address;
		// see if we need to make the path absolute
		if (fileOnly)
			address = user + address.substring(address.lastIndexOf("/", address.length));
		if (host.length > 0)
			return "/" + host + user + address + query;
		else
			return user + address + query;
	},

	// --------------------------------------------------------------------------------
	// track()
	"track": function(address) {
		/// <summary>Tracks the submitted address.</summary>
		// call the tracker method for each tracker initialized
		var trackers = OneWeb.Analytics.providers;
		//if (confirm(address))
		if (trackers && trackers.length > 0)
			for (var tracker in trackers)
			if (trackers[tracker] && typeof trackers[tracker].track != "undefined")
			trackers[tracker].track(address);
	},

	// --------------------------------------------------------------------------------
	// trackOnClick()
	"trackOnClick": function() {
		/// <summary>The OnClick handler that formats the track address and calls the ga tracker.</summary>
		var OA = OneWeb.Analytics, OU = OneWeb.Util;
		var a = this;
		if (window.event) a = event.srcElement;

		//loop up until we are at the anchor tag
		while (a.parentNode != null && a.tagName.toLowerCase() != "a" && a.tagName.toLowerCase() != "area")
			a = a.parentNode;

		var address = "";
		if (a.getAttribute("track") && a.getAttribute("track") != "")
			address = a.getAttribute("track");
		else if (a.href != null && a.href != "") {
			for (var c in OA.trackingClasses) {
				if (OU.hasClass(a, c)) {
					address = OA.trackingClasses[c].prefix + OA.formatLink(a.href, OA.trackingClasses[c].fileOnly);
					break;
				}
			}
		}
		if (address == "")
			return;

		// track the click
		OA.track(address);
	},

	// --------------------------------------------------------------------------------
	// trackAndRedirect(address, redirect)
	"trackAndRedirect": function(address, redirect) {
		/// <summary>Tracks the submitted address, then redirects the user.</summary>
		///	<param name="address">page address to track</param>
		///	<param name="redirect">page to redirect the user to</param>
		///	<returns>void<returns

		// call the tracker method
		OneWeb.Analytics.track(address);
		document.location.href = redirect;
	},

	// --------------------------------------------------------------------------------
	// setTrackingLinks()
	"setTrackingLinks": function(useTrackingClasses) {
		/// <summary>Sets up any links marked as requiring tracks.</summary>
		///<param name="useTrackingClasses">Specifies whether to add onclick handlers to track the links using virtual PageViews</param>
		/// <returns>void</void>
		var OA = OneWeb.Analytics, OU = OneWeb.Util;
		var links = document.getElementsByTagName("a");
		var a = null;
		for (var i = 0; i < links.length; i++) {
			a = links[i];
			if (a.getAttribute("track") != null && a.getAttribute("track") != "")
			// create the onclick handler
				OU.addEvent(a, "click", OA.trackOnClick, false);
			else if (useTrackingClasses && a.href != null && a.href != "") {
				for (var c in OA.trackingClasses) {
					if (OU.hasClass(a, c)) {
						OU.addEvent(a, "click", OA.trackOnClick, false);
						break;
					}
				}
			}
		}

		links = document.getElementsByTagName("area");
		a = null;
		for (var i = 0; i < links.length; i++) {
			a = links[i];
			if (a.getAttribute("track") != null && a.getAttribute("track") != "")
			// create the onclick handler
				OU.addEvent(a, "click", OA.trackOnClick, false);
			else if (useTrackingClasses && a.href != null && a.href != "") {
				for (var c in OA.trackingClasses) {
					if (OU.hasClass(a, c)) {
						OU.addEvent(a, "click", OA.trackOnClick, false);
						break;
					}
				}
			}
		}
	},

	// --------------------------------------------------------------------------------
	// addTrackingClass()
	"addTrackingClass": function(className, trackPrefix, fileOnly, eventArgs) {
		/// <summary>Adds the class to the list of custom classes that are tracked as a special page view.</summary>
		///	<param name="className">CSS class to be used to indicate tracking</param>
		///	<param name="trackPrefix">address prefix that will be tracked for this click (prepended to the formatted destination url)</param>
		///	<param name="fileOnly">should it use the full path of the address, or just the file name</param>
		///	<param name="eventArgs">event argument string to use for the tracking class</param>
		///	<returns>void</returns>
		if (className != "" && !OneWeb.Analytics.trackingClasses[className] && trackPrefix != "") {
			OneWeb.Analytics.trackingClasses[className] = { prefix: trackPrefix, fileOnly: fileOnly, eventArgs: eventArgs }
		}
	},

	//#endregion

	//#region Event Tracking

	// --------------------------------------------------------------------------------
	// trackEvent()
	"trackEvent": function() {
		///<summary>Tracks a specific event, if supported by the provider</summary>
		///<returns>void<returns>
		///<remarks>The parameters are variable depending on the provider's event tracking implementation</remarks>
		var trackers = OneWeb.Analytics.providers;
		if (trackers && trackers.length > 0) {
			for (var tracker in trackers) {
				if (trackers[tracker] && typeof trackers[tracker].trackEvent !== "undefined") {
					try {
						// apply the trackEvent method so that we can pass the arguments from this method
						trackers[tracker].trackEvent.apply(trackers[tracker], arguments);
					} catch (e) {
						// swallow exception
					}
				}
			}
		}
	},

	// --------------------------------------------------------------------------------
	// trackEventOnEvent()
	"trackEventOnEvent": function(e) {
		/// <summary>The OnEvent handler that formats the tracking event parameters and calls the ga tracker.</summary>
		if (!e) var e = window.event;
		var type = e.type;
		var el = (e.srcElement) ? e.srcElement : this;

		//loop up until we are at the element tag
		var attr = "trackEvent_" + type;
		while (el.getAttribute(attr) == null && el.parentNode != null)
			el = el.parentNode;
		// valid element            
		if (el.getAttribute(attr) == null)
			return;
		var args = el.getAttribute(attr).split(",");

		// track the click by applying the trackEvent method
		OneWeb.Analytics.trackEvent.apply(OneWeb.Analytics, args);

		// return true so that we don't interfere with other event handlers
		return true;
	},

	// --------------------------------------------------------------------------------
	// setTrackingEvents()
	"setTrackingEvents": function(useTrackingClasses) {
		/// <summary>Sets up any objects marked as requiring tracking for an event.</summary>
		///<param name="useTrackingClasses">Specifies whether to add onclick handlers to track the links using virtual PageViews</param>
		/// <returns>void</void>
		var OA = OneWeb.Analytics, OU = OneWeb.Util;
		var els = document.getElementsByTagName("*");
		var el = null;

		for (var i = 0, l = els.length; i < l; i++) {
			el = els[i];
			if (el.getAttribute("trackEvent") !== null || el.getAttribute("trackevent") != null) {
				var attr = el.getAttribute("trackEvent") || el.getAttribute("trackevent");
				if (attr.length == 0)
					continue;
				var evs = el.getAttribute("trackEvent").split(";");
				for (var j = 0, jl = evs.length; j < jl; j++) {
					// get the arguments for the event tracking
					var args = evs[j].split(",");
					if (args.length < 2)
						continue;
					// get the event name that triggers the track
					args[0] = args[0].toLowerCase();
					if (args[0].substring(0, 2) == "on")
						args[0] = args[0].substring(2, args[0].length);
					else if (args[0].length == 0)
						args[0] = "click";
					// create an attribute with just the tracking parameters
					el.setAttribute("trackEvent_" + args[0], args.slice(1).join(","));
					// create the event handler
					OU.addEvent(el, args[0], OA.trackEventOnEvent, true);
				}
			} else if (useTrackingClasses && (el.tagName == "A" || el.tagName == "AREA")) {
				if (el.getAttribute("track") === null) {
					// create the onclick handler
					if (el.href != null && el.href != "") {
						for (var c in OA.trackingClasses) {
							if (OU.hasClass(el, c)) {
								var args = OA.trackingClasses[c].eventArgs.replace("{address}", OA.formatLink(el.href, OA.trackingClasses[c].fileOnly));
								el.setAttribute("trackEvent_click", args);
								OU.addEvent(el, "click", OA.trackEventOnEvent, true);
								break;
							}
						}
					}
				}
			}

		}

	},

	//#endregion

	//#region Provider handling

	// --------------------------------------------------------------------------------
	// addProvider(provider)
	"addProvider": function(provider) {
		/// <summary>Adds a new provider to the system.</summary>
		/// <returns>void</void>
		if (provider instanceof OneWeb.Analytics.Provider)
			OneWeb.Analytics.providers.push(provider);
	},

	// --------------------------------------------------------------------------------
	// initialize()
	"initialize": function() {
		/// <summary>Initializes the OneWeb Analytics implementation(s).</summary>
		///	<param name="options">initialization options</param>
		/// <returns>void</void>
		var OA = OneWeb.Analytics;

		if (OA.providers.length > 0) {
			for (var provider in OneWeb.Analytics.providers) {
				try {
					if (typeof OA.providers[provider].initialize != "undefined")
						OA.providers[provider].initialize();
				} catch (e) { }
			}

			var body = document.getElementsByTagName("body")[0];
			if (body !== null && body.getAttribute("track") !== null && body.getAttribute("track").length > 0)
				OA.track(body.getAttribute("track"));
			else if (body !== null && body.getAttribute("trackAndRedirect") !== null && body.getAttribute("trackAndRedirect").length > 0) {
				var addrs = body.getAttribute("trackAndRedirect").split(",", 2);
				if (addrs.length === 1)
					OA.trackAndRedirect(null, addrs[0]);
				else if (addrs[0].length === 0)
					OA.trackAndRedirect(null, addrs[1]);
				else
					OA.trackAndRedirect(addrs[2], addrs[1]);
				return;
			} else
				OA.track();

			var options = OneWeb.Analytics.settings;
			var eventTrackingEnabled = (options != null && typeof (options.eventTracking) == "boolean" && options.eventTracking === true);
			var useEventTrackingForOneWeb = (eventTrackingEnabled && typeof (options.oneWebActionMethod) == "number" && options.oneWebActionMethod === OA.OneWebActionMethod.Event);

			// set up the tracking links
			OA.setTrackingLinks(!useEventTrackingForOneWeb);

			// set up the event tracking handlers
			if (eventTrackingEnabled)
				OA.setTrackingEvents(useEventTrackingForOneWeb);
		}
	},

	// --------------------------------------------------------------------------------
	// initializeClasses()
	"initializeClasses": function() {
		/// <summary>Initializes the OneWeb Analytics style class(es) by inserting them into the document.</summary>
		/// <returns>void</void>
		var ss = null;
		if (document.createStyleSheet) {
			ss = document.createStyleSheet();
		} else if (document.styleSheets) {
			var st = document.createElement("style");
			st.setAttribute("type", "text/css");
			document.getElementsByTagName("head")[0].appendChild(st);
			if (!window.createPopup) // For Safari
				st.appendChild(document.createTextNode(''));   
			ss = document.styleSheets[document.styleSheets.length - 1];
		}

		if (ss != null) {
			// create an abstraction function for either insertRule or addRule
			var appendRule = 
				(ss.insertRule) ? function (selector, rules) {ss.insertRule(selector + "{" + rules + "}", ss.cssRules.length);} :
				(ss.addRule) ? function(selector, rules) { ss.addRule(selector, rules, -1); } : 
				null;

			if (appendRule) {
				for (var c in OneWeb.Analytics.trackingClasses) {
					appendRule("A." + c, "display:inline;");
					appendRule("AREA." + c, "display:inline;");
				}
			}
		}
	}

	//#endregion

};

// add the three standard tracking classes
OneWeb.Analytics.addTrackingClass(OneWeb.Analytics.TRACK_DOWNLOAD_CLASS, "/download", !OneWeb.Analytics.includeSubDirs, OneWeb.Analytics.TRACK_DOWNLOAD_EVENTARGS);
OneWeb.Analytics.addTrackingClass(OneWeb.Analytics.TRACK_EXTERNAL_CLASS, "/external", false, OneWeb.Analytics.TRACK_EXTERNAL_EVENTARGS);
OneWeb.Analytics.addTrackingClass(OneWeb.Analytics.TRACK_MAILTO_CLASS, "/mailto", false, OneWeb.Analytics.TRACK_MAILTO_EVENTARGS);

// Provider object definition
OneWeb.Analytics.Provider = function(account) {
    this.getAccount = function() { return account; }
    this.setAccount = function(newAccount) { account = newAccount; }
}

// add overridable functions to the Provider class
OneWeb.Analytics.Provider.prototype = {
    "initialize": function() { },
    "track": function(address) { },
    "trackEvent": function() { }
}

/* 6.0.3887 */ 

