

function Tracker( ){
	
	
	// set defaults
	
	this.entries = [];
	
	
	this.registered = new Array();
	
	
	// encode relevant urls

	this.url = encodeURIComponent( window.location.toString() );
	this.referrer = encodeURIComponent( document.referrer.toString() );

	this.network_cookie = BFW_Util.getCookie("BUZZ_WIDGET");
	if ( this.network_cookie && window.location.href.match( this.network_cookie ))
	{
		this.url += encodeURIComponent( "?w=1" );
		BFW_Util.deleteCookie("BUZZ_WIDGET");	
	}

	// set defaults
	
	this.defaults = {c:"", u:"", type:"", user:"", buzz:"", query:"", url:this.url, referrer:this.referrer};


	// generate source root

	this.cloud = Cloud.servers[Math.floor(Math.random() * Cloud.servers.length)];
	this.source = "http://" + this.cloud + "/small.gif?type=";
}

Tracker.gClick = function( track_url ) {
	if ( typeof pageTracker != 'undefined' && pageTracker != null )
		pageTracker._trackPageview(track_url);
	
};


Tracker.prototype = {
	setDefaults: function( values ){
		for (key in values) {
			this.defaults[key] = values[key];
		}
	},
	
	add: function( values, unique ){
		
		
		// set defaults

		entry = {};
		for (key in this.defaults) {
			entry[key] = this.defaults[key];
		}
		
		valid = true;
		

		// handle overrides

		for (key in values) {
			entry[key] = values[key];
		}
		
		
		// check for unique
		
		if(unique){
			
		
			// fetch the cookie
			
			unique_cookie = BFW_Util.getCookie("BF-U");
		
		
			// check if it exists
	
			if(unique_cookie){
				
		
				unique_cookie = unique_cookie.split(",");
		
				if(unique_cookie.indexOf(unique) != -1){
					valid = false;
				}
				else{
					unique_cookie.unshift(unique);
				}
				
				if(unique_cookie.length > 100){
					unique_cookie = unique_cookie.slice(0,99);
				}
				
				BFW_Util.setCookie({name:"BF-U", value:unique_cookie.join()});
			}
			else {
				BFW_Util.setCookie({name:"BF-U", value:unique});
			}
		}
		
		
		// add the entry
		
		if(valid){
			this.entries.push( entry );
		}
	},
	
	
	run: function( overrides ) {
		
		
		// check if there are entries to report
		if(this.entries.length){

			if (document.location.href.match(/debug/) )
			{
				console.log("Tracking " + this.entries.length + " entry positions" );
				this.entries.each(function(e){

					var tmp_buzz = {};
					['buzz','query','type','user'].each(function(key){
						if (e[ key ])
						{
							tmp_buzz[ key ] = e[ key ] + '';
							tmp_buzz[ key ] = tmp_buzz[ key ].split(',').first();
						}
					});

					if (tmp_buzz['type'] == 30 || tmp_buzz['type'] == 35 && tmp_buzz['query'])
					{
						console.log( [ tmp_buzz['user'], tmp_buzz['buzz'], tracker.positions[ tmp_buzz['query'] ] ] );
					}
					else if (e.type == "") {
						console.log( [ tmp_buzz['user'], tmp_buzz['buzz'], "Primary page impression" ] );
					}
					else if (e.type == "12") {
						console.log( [ tmp_buzz['user'], tmp_buzz['buzz'], "Unique page impression" ] );
					} else {
						console.log( [ tmp_buzz['user'], tmp_buzz['buzz'], e.type ] );
					}
					

				});
			}


			// if we're tracking the primary view page here and this is not a unique view,
			// delete referrer. Prevents back button from mimicking an additional network view

			if ( this.entries.length == 1 
				&& this.entries[0].type == ''
				&& this.entries[0].referrer != ''
				&& !this.entries[0].referrer.match(/buzzfeed\.com/) )
			{
				this.entries[0].referrer = window.location.href;
			}

			


			// build the list
		
			list = this.entries.shift();
			
			if(list.type != ''){
				list.referrer = '';
			}
			
			
			// set defaults for different checks
			
			different = {};
			last = Object.clone(list);
			multiple = false;
			
		
			// iterate through the entries
		
			while(this.entries.length){
				multiple = true;
				entry = this.entries.shift();
				
				
				// eliminate uncessary fields for defined types
				
				if(entry.type != ''){
					entry.referrer = '';
				}
				
				for (key in list) {
					list[key] += "," + entry[key];
				
					if(!different[key] && last[key] != entry[key]){
						different[key] = 1;
					}
				}
			}
			
			if(multiple){
				for (key in list) {
					if(!different[key] && key != 'type'){
						list[key] = list[key].replace(/,.*$/,'');
					}
				}
			}
						
			// load the image
			var bug = new Image;
			bug.src = this.source + list.type + "&user=" + list.user + "&buzz=" + list.buzz + "&url=" + list.url + "&query=" + list.query + "&referrer=" + list.referrer + "&c=" + list.c + "&u=" + list.u + "&z=" + (new Date).getTime();
		}
	},
	

	
	track: function(){
		
		
			// decode right away if necessary

			if(!this.tracker.registered[this.index].data_obj){
				this.tracker.registered[this.index].data_obj = JSON.parse( this.tracker.registered[this.index].data );
			}
			
			if(!this.tracker.registered[this.index].events[this.event].data_obj){
				this.tracker.registered[this.index].events[this.event].data_obj = JSON.parse( this.tracker.registered[this.index].events[this.event].data );
			}


			// add for every type

			$H( this.tracker.registered[this.index].events[this.event].data_obj ).each( function(pair){
				
								
				// clone the data object
				
				
				
				
				// add type and query
				
				
				
				
				if(!Object.isArray(pair.value)){
					pair.value = [pair.value]
				}
				
				pair.value.each(function(query){
					data = Object.clone( this.tracker.registered[this.index].data_obj );
					data.type	= this.tracker.types[pair.key];
					data.query	= query;
					this.tracker.add(data);
				}.bind(this));
				
				
				// add the data to the tracker
				
				
			}.bind(this) );
			
			if(this.run){
				this.tracker.run();
			}
	},


	addFromAllTriggers: function( root ) {
		root		= $(root);
		css			= ['div[', '], li[', '], a[', ']'].join('track');
		
		
		// initialize the lookup
		
		this.registered = [];
		
		
		// iterate through css matches
		
		$$(css).each(function(element){
			
			
			// set the index
			
			index = this.registered.length;
			
			
			
			// get the tracking info
			
			this.registered.push ({
				data: element.getAttribute('track'),
				events: {}
			});
			
			
			// iterate through defined events
			
			this.events.each(function(event){
				
				this.registered[index].events[event] = {};
				
				if(this.registered[index].events[event].data = element.readAttribute(['track', event].join('_'))){
					if(event == 'load'){
						
						
						// track right away
						
						this.track.bind({tracker:this, event:event, index: index})();
					}
					else {
						
						
						// attatch an event handler to track
						
						Event.observe(element, event, this.track.bind({tracker:this, event:event, index: index, run: true}));
					}	
				}	
			}.bind(this));
		}.bind(this));
	
	
		// run any accumlated tracks
		
		this.run();
	},
	

	trackSiteClick: function( e ) {

		el = e.element();

		if (e.srcElement)
		{
			el = e.srcElement;
		}
		else if (e.currentTarget) 
		{
			el = e.currentTarget;
		}
		
		if (el.tagName && el.tagName.toLowerCase() == 'img' && el.parentNode && el.parentNode.tagName.toLowerCase() == 'a')
		{
			el = el.parentNode;
		}

		track_data = eval( "(" + el.getAttribute('track') + ")" );

		if (!track_data)
			return true;

		var external_click = false;

		if ( !el.href.match(/buzzfeed.com/) )
		{
			external_click = true;
			track_data.referrer = encodeURIComponent(el.href);
			Tracker.gClick( "/_ga/link/" + el.href.replace(/http(s)?:\/\//, '' ) );
		}

		ctracker = new Tracker();
		for( i=0; i < track_data.types.length; i++ )
		{
			track_data.type = track_data.types[i];
			
			if ( typeof track_data['queries'] != 'undefined' && track_data['queries'][i] )
			{
				track_data.query = track_data['queries'][i];
			}
			else if ( external_click )
			{
				track_data.query = encodeURIComponent(el.href);
			}
			else
			{
				track_data.query = '';
			}
			
			ctracker.add( track_data );
		}

		ctracker.run();
	},

	attach: function() {
		
		if (arguments && arguments.length > 0)
		{
			base_el = $(arguments[0]);
		}
		else
		{
			base_el = document;
		}
		
		$A(base_el.getElementsByClassName('track')).each(
			function( el ) {
				el_data =  el.getAttribute( 'track' );
				$A(el.getElementsByTagName('A')).each(
					function (a_el) {
						a_el.setAttribute('track', el_data);
						Event.observe( a_el, 'mousedown', Tracker.prototype.trackSiteClick );
					}
				);
				el.removeClassName('track');
			}
		)
	},
	
	
	registered: [],
	
	events: ['load', 'mousedown', 'mouseover', 'submit'],

	positions: ['','Header','Homepage Flow','B-Page Viral Alert','Index Sidebar','B-Page Sidebar','C-Page Sidebar','Non-ad Flow','Non-ad Header','Non-ad Sidebar Partner','Non-ad Sidebar Raw','Non-ad Sidebar Badge','Non-ad Permalink Flow','Non-ad Clickable Sidebar','Non-ad Related Buzz','Non-ad Viral Related Unit','Viral Related Unit'],

	types: {
		REFERRER_DIRECT: 	0,
		REFERRER_INTERNAL: 	1,
		REFERRER_LINK: 		2,
		REFERRER_SEARCH: 	3,
		REFERRER_NETWORK: 	4,
		SHARE_EMAIL:		5,
		SHARE_FACEBOOK:		6,
		SHARE_STUMBLE:		7,
		SHARE_DELICIOUS:	8,
		SHARE_DIGG:			9,
		SHARE_REDDIT:		10,
		SHARE_MIXX:			11,
		SHARE_TWITTER:		15,
		SHARE_FARK: 	16,
		SHARE_MYSPACE:    17,
		SHARE_REBUZZ:    18,
		SHARE_RESERVED4:    19,
		SHARE_RESERVED5:    20,
		UNIQUE_VISIT: 		12,
		WIDGET_IMPRESSION:	13,
		WIDGET_CLICK:		14,
		BUZZBOX_IMPRESSION  : 21,
		BUZZBOX_CLICK		: 22,
		BUZZBOX_RES2		: 23,
		BUZZBOX_RES3		: 24,
		BUZZBOX_RES4		: 25,
		BUZZBOX_RES5		: 26,
		BUZZBOX_RES6		: 27,
		BUZZBOX_RES7		: 28,
		BUZZBOX_RES8		: 29,
		PROMO_IMPRESSION	: 30,
		PROMO_AD_IMP		: 31,
		BOOST_IMPRESSION	: 32,
		PROMO_IMP_RES3		: 33,
		PROMO_IMP_RES4		: 34,
		PROMO_CLICK			: 35,
		PROMO_AD_CLICK		: 36,
		BOOST_CLICK			: 37,
		PROMO_CLICK_RES3	: 38,
		PROMO_CLICK_RES4	: 39,
		SITE_CLICK			: 100
	}
}



