

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 _gaq != 'undefined' && _gaq != null ){
    	_gaq.push(['_trackPageview', track_url, 'clicked']);
    }
	//	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){

			// piggy back on our main click type to record
			// a viral exchange credit when a partner link is clicked
			var clicked = this.entries.find(function(ev){
				return ev.type == 100;
			});
			if ( clicked && clicked.query && !clicked.query.match(/buzzfeed.com/) )
			{ 
				this.entries.unshift({
					buzz: clicked.user,
					user: clicked.user,
					c: clicked.u,
					u: clicked.u,
					type: this.types.VXN_CLICK_IN,
					types: [this.types.VXN_CLICK_IN],
					domain: '',
					query: '',
					url: ''
				});
				this.entries.unshift({
					buzz: 'buzz',
					user: 'buzz',
					c: '7BA7',
					u: '7BA7',
					type: this.types.VXN_CLICK_OUT,
					types: [this.types.VXN_CLICK_OUT],
					domain: '',
					query: '',
					url: ''
				});
			}
			else
			{
				// we want to ignore clicks that happen within buzzfeed
				this.entries = this.entries.without(clicked);
				if (!this.entries.length)
					return false;
			}
			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 );
			}

			// 
			// if (el.getAttribute('rel:' + this.event + '_callback'))
			// {
			// }
			// 

			// add for every type

			$H( this.tracker.registered[this.index].events[this.event].data_obj ).each( function(pair){

				if (pair.key == 'callback')
				{
					try{
						eval( pair.value + "(" + this.tracker.registered[this.index].data + ");" );
					} catch(e) {}
					return true;
				}
				
				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();
			}
	},


	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;
		}

		// get every track element
		//$A(base_el.getElementsByClassName('track')).each(
		var handler = function( el ) {
				var el_data =  el.getAttribute( 'track' );

				var reg_data = { data: el_data,	events: {} };
				this.registered.push(reg_data);

				// iterate through defined events (click,load,mousedown)
				this.events.each(function(event){

					reg_data.events[event] = {};

					// look for attribues like track_load, track_mousedown, etc
					var t_data = el.readAttribute('track_' + event);
					if( t_data ) {

						reg_data.events[event].data = t_data;
						if(event == 'load'){

							// track right away
							this.track.bind({tracker:this, event:event, index: (this.registered.length - 1) })();

						}
						else {

							// attatch an event handler to track
							Event.observe(el, event, this.track.bind({tracker:this, event:event, index: (this.registered.length - 1), run: true}));

						}	
					}	

				}, this);

				// this is the older style click tracking
				$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');
		}.bind(this);
		universal_dom.assign_handler({bucket:'track',handler:handler});

		this.run();
	},
	
	
	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','Bottom-Of-Page Promo','Multi Homepage Flow','Valley of The Nerds', 'AOL Related Promo', 'Targeted-B', 'Targeted-C', 'Targeted-A'],

	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,
		VXN_CLICK_OUT		: 23,
		VXN_CLICK_IN		: 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
	}
}



