/* 
	Analyte 1.0 (c) 2008 Bryan Elliott
	
	Purpose:
		Simplify inclusion of Google Analytics into any site
	
	Use:
		<script src="/path/to/analyte.js" type="text/javascript" id="UA-xxxxxx-x"></script>
	
	License:
		Unlimited license granted to Abacus Studios, Inc. and I-Site, Inc.
		All other parties licensed under CC-BY-SA-3.0:
		
			Creative Commons Attribution / Share Alike 3.0 US
				Fulltext and synopsis at
					http://creativecommons.org/licenses/by-sa/3.0/us/

		This license need not appear in minified or otherwise compressed forms 
		of this script, so long as the script is in active use by a web site or 
		application, and no other credit is claimed.
*/
var Analyte = {
	//Flags to tell your browser easy
	Browser: {
		IE:     !!(window.attachEvent && !window.opera),
		Opera:  !!window.opera,
		WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
		Gecko:  navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1,
		MobileSafari: !!navigator.userAgent.match(/iPhone.*Mobile.*Safari/)
	},
	//To tell if you're in SSL mode
	ssl:'https:'== document.location.protocol,
	//Simple observe function
	observe: function (o,e,f) {
		//Make sure 'this' is the element we applied the handler to
		var IE=Analyte.Browser.IE, __method = IE?
			function () { return f.apply(o, arguments); }:
			f;
			
		// Hook for commonality of event registry
		if (e=='ready') return Analyte.onReady(__method);
		
		//And call the right function for the browser
		return o[IE?'attachEvent':'addEventListener']((IE?'on':'')+e,__method,false);
	},
	//shorthand for .getElementsByTagName, with the object defaulting to document.
	_tags: function (a,o) { if (!o) o=document; return o.getElementsByTagName(a); },
	
	//Simple function to extend an object by the contents of another.
	extend: function (d,s) { for (var i in s) d[i]=s[i]; },
	
	//Basically, a cross browser DOMContentLoaded.  Fires before onload (which happens
	//when all images are in)
	onReady: function () {
		Analyte.onReady.execute.apply(Analyte.onReady,arguments);
	},
	
	docTrack: function () {
		//Attach a click handler to all non page elements so they get tracked as well
		var elements = Analyte._tags('a');
		for (var i=0; i<elements.length; i++) {
			t = elements[i].getAttribute('href');
			if (!/\.[^\/]*$/.test(t)) //linked URL is folder or clean URL.  Ignore.
				continue;
			if (!/\.(html|htm|asp|aspx|pl|rb|php|php3|phtml|shtml|jsp|cfm)$/i.test(t))
				//Linked URL is not a page.  Add the click handler.
				Analyte.observe(elements[i],'click',function () {
					var link=this.href.replace(/^[^\/]*\/\/[^\/]*\//,'/');
					if (!!window.pageTracker)
						pageTracker._trackPageview(link);
					else
						urchinTracker(link);
				});
		}
	},
	//Once the analytics script is loaded, find the UA ID and set up the global pageTracker
	googleAnalyticsLoader: function () {
		var i,t,elements;
		//Make sure that the _gat object is available, if not, wait another 50 ms and try again
		if (!window._gat)
			return setTimeout(Analyte.googleAnalyticsLoader,250);
			
		//UA ID should be the ID attribute of the tag for this script.  Search script tags for it.
		var i,t,elements = Analyte._tags('script');
		for (var i=0; i<elements.length; i++)
			if (/^UA-/i.test(t=elements[i].getAttribute('id'))) break;
			
		//If it's not, we can't continue
		if (t==null) return false;
		
		//set up the global pageTracker object
		window.pageTracker = _gat._getTracker(t);
		pageTracker._initData();
		pageTracker._trackPageview();
		Analyte.docTrack();	
	}	
};
with (Analyte) {
	//Core stuff for onReady
	extend(onReady,{
		repo: [],
		bound: false,
		ready: false,
		//The pseudo event aggregator
		imReady: function () {
			if (onReady.ready) return;
			onReady.ready=true;
			for (i=0; i<onReady.repo.length; i++) {
				onReady.repo[i].apply();
			}	
		},
		//drop the function in, or if the DOM is ready, just run it.
		register: function (fnc) {
			if (!onReady.ready)
				onReady.repo.push(fnc);
			else
				fnc.apply();
			return;
		}
	});

	//Different functions for different browsers (*sigh*)
	switch (true) {
		case (document.addEventListener && !Browser.Opera):
			//execute is called by onReady itself
			onReady.execute = function (fnc) {
				if (!onReady.bound) {
					onReady.bound=true;				
					document.addEventListener('DOMContentLoaded', onReady.imReady, false);
				}
				onReady.register(fnc);
			};
		break;
		case (Browser.IE):
			onReady.execute = function (fnc) {
				if (!onReady.bound) {
					onReady.bound=true;
					onReady.checkReady();
				}
				onReady.register(fnc);
			};
			//For browsers without DOMContentLoaded support, checkReady
			//handles this by polling.
			onReady.checkReady = function () {
				try {
					document.documentElement.doScroll('left');
				} catch (error) {
					setTimeout(onReady.checkReady,50);
					return;
				}
				onReady.imReady();
			};
		break;
		case (Browser.Opera):
			onReady.execute = function (fnc) {
				if (!onReady.bound) {
					onReady.bound=true;				
					document.addEventListener('DOMContentLoaded', function () {
						if (onReady.ready) return;
						for (var i=0; i<document.styleSheets.length; i++) 
							if (document.styleSheets[i].disabled) {
								setTimeout(arguments.callee,50);
								return;
							}
						onReady.imReady();
					}, false);
				}
				onReady.register(fnc);
			};
		break;
		case (Browser.Safari):
			onReady.execute = function (fnc) {
				if (!onReady.bound) {
					onReady.bound=true;
					onReady.checkReady();
				}
				onReady.register(fnc);
			};
			onReady.checkReady = function () {
				if (document.readyState != 'loaded' && document.readyState != 'complete') {
					setTimeout(arguments.callee, 50);
					return;
				}
				if (numStyles === undefined) {
					var numStyles = document.getElementsByTagName('style').length;
					var links = document.getElementsByTagName('link');
					for (var i=0; i<links.length; i++) {
						var t=links[i].getAttribute('rel');
						if (t!=null && t.toLowercase()=='stylesheet')
							numStyles++;
					}
				}
				if (document.styleSheets.length != numStyles) {
					setTimeout(arguments.callee, 50);
					return;
				}
				onReady.imReady();
			};
		break;
	}
	//load ALWAYS fires, so in the event there's an error, we still get our functions 
	// to run, just a little later
	observe(window,'load',onReady.imReady);

	//Add the Anaylitics script tag, and go asynch so that it can load up
	observe(window,'ready',function () {
		//If the GA scripts are included in the HTML, just go to the docTrack part
		//Handle new and old versions
		if (!!window._gat) {
			if (!!window.pageTracker) return docTrack();
			return googleAnalyticsLoader();
		}
		if (!!window.urchinTracker) return docTrack();
		
		//Load the GA script, matching security
		var gaJs = ((ssl) ? "https://ssl." : "http://www.")+'google-analytics.com/ga.js';
		var gsTag = document.createElement('script');
		gsTag.setAttribute('src',gaJs);
		gsTag.setAttribute('type','text/javascript');
		_tags('head')[0].appendChild(gsTag);
		
		//Go asynch, to give it time to load
		setTimeout(googleAnalyticsLoader,50);
	});
	observe(window,'unload',function () {
		delete window.Analyte;
	});
};
