
function AjaxLinkTracker() {

    var me;
    if (this.constructor == AjaxLinkTracker){
        me = this;
    }else{
        me = arguments[arguments.length-1];
    }

	// Configuration
	// ------------
	me.apiURL = 'http://www.misn.com/';
	me.displayCount = true;
	me.displayPercent = true;
	me.displayLabel = true;
	me.numberDays = 28; //1-30
	me.clickOffSet = 10;
	// -----------

	me.url = encodeURIComponent( document.location.href );
	me.listeners = [];
	
	
	me.addLinkTracking = function(){
		if (!document.getElementsByTagName) return false;
	
		// Create ajax objects
		me.clickedXHR = new XHRConnection();
		me.getClicksXHR = new XHRConnection();
		
		// find links in document 
		links = document.getElementsByTagName('a');
	
		// if link does have a id add one
		for (var i = 0; i < links.length; i++) {
			me.addEvent( links[i], 'mousedown', me.recordClick, false );
			me.addEvent( links[i], 'keypress', me.linkKeyPress, false );
			if (! links[i].getAttribute('id') ) {
				links[i].setAttribute('id','link_' + i);
			}
		}
		
		// find buttons in document
		inputs = document.getElementsByTagName('input');
		for (var i = 0; i < inputs.length; i++) {
		
			type = inputs[i].getAttribute('type');
			
			// only attach events to buttons
			if ( type == 'submit' || type == 'button' ){
				me.addEvent( inputs[i], 'mousedown', me.recordClick, false );
				me.addEvent( inputs[i], 'keypress', me.linkKeyPress, false );
				// if button does have a id add one
				if (! inputs[i].getAttribute('id') ){
					inputs[i].setAttribute('id','button_' + i);
				}	
			}
		}
	}
	
	me.linkKeyPress = function(e) {
		// check for return key press
		var keyID = (window.event) ? event.keyCode : e.keyCode;
		if (keyID == 13) {
			me.recordClick(e);
		}
	}

	me.recordClick = function(e) {
		// records click information using ajax
		source = me.findSourceElement(e);
		tag = source.tagName;
		var id,label,target
		
		if( tag == 'IMG'){
			if( source.parentNode.tagName == 'A' )
			{
				id = source.parentNode.getAttribute('id');
				target = source.parentNode.href;
			}
			label = source.getAttribute('alt');
			if (label == null) {
				label = 'image';
			}
		}
		
		if( tag == 'A' ){
			id = source.getAttribute('id');
			target = source.href;
			label = me.getInnerText( source, '' );
		}	
				
		if( tag == 'INPUT' ){
			id = source.getAttribute('id');
			label = source.getAttribute('value');

			if( source.getAttribute('type') == 'submit' ) {
				target = me.getFormTarget( source );
			} else {
				target = 'script';
			}
		}
		
		
		id = encodeURIComponent( id );
		target = encodeURIComponent( target );
		label = encodeURIComponent( label );
			
		var ajaxURL = me.apiURL + 'addclick.php?id=' + id + '&label=' + label + '&target=' + target + '&url=' + me.url + '&rand='+Math.random();
		me.clickedXHR.send( ajaxURL, 'get', me.beenClicked, null  );
		
	}
	
	
	me.beenClicked = function( obj ) {
		//alert( obj.responseText );
	}
	
	
	me.getClickThroughInfo = function (){
		// get click data using ajax
		var ajaxURL = me.apiURL + 'getclicks.php?url=' + me.url + '&days=' + me.numberDays + '&rand='+Math.random();
		me.getClicksXHR.send( ajaxURL, 'get', me.displayClickThroughs, null  );
	}	


	me.displayClickThroughs = function( obj ){
		// display click through data
	
		if (!document.getElementsByTagName) return false;
		
		if(obj.responseXML)
			node = obj.responseXML;
		if(obj.responseXml)
			node = obj.responseXML;	
			
		if(node.childNodes[0].nodeType == 7) {
			rootNode = node.childNodes[1];
		}else{
			rootNode = node.childNodes[0];
		}

		for (var i = 0; i < rootNode.childNodes.length; i++) {
		
			linknode = rootNode.childNodes[i];
			count = linknode.getAttribute('count');
			percent = linknode.getAttribute('percent');
			label = linknode.getAttribute('label');
			id = linknode.childNodes[0].nodeValue;
			
			if ( document.getElementById(id) ) {
			
				eltLink =  document.getElementById(id);
				
				eltDiv = document.createElement( 'div' );
				eltDiv.className = 'linklabel';
				
				var text = ''; 
				if( me.displayPercent )
					text += percent + '% ';
				
				if( me.displayCount )
					text += '(' + count + ') ';
					
				if( me.displayLabel )
					text += label ;
				
				eltText = document.createTextNode( text );
				eltDiv.appendChild( eltText );
				document.body.appendChild( eltDiv );
				
				Drag.init(eltDiv, eltDiv);
				
				ileft = parseInt( me.getPageOffsetLeft( eltLink ) ) + me.clickOffSet;
				itop = parseInt( me.getPageOffsetTop( eltLink ) ) + me.clickOffSet;
				eltDiv.style.left = ileft + 'px';
				eltDiv.style.top = itop + 'px';
				
			}
		} 
		me.labelsCreated = true;
		me.labelsDisplayed = true;

	}
	
	me.keyCheck = function (e) {
		// check to see if user press 'ctrl x'
		var keyID = (window.event) ? event.keyCode : e.keyCode;
		var ctrlKey = (window.event) ? event.ctrlKey : e.ctrlKey;
		
		if((keyID == 88)&&(ctrlKey == true)) { 
			
			eltLabels = me.getElementsByClassName('linklabel');
			if( eltLabels.length == 0 ) {
				me.getClickThroughInfo();
			}else{
				for (var i = 0; i < eltLabels.length; i++) {
					eltLabels[i].parentNode.removeChild(eltLabels[i]);
				}
			}
		}
	}
	
	me.getInnerText = function( node, text ) {
		// returns the text of any element node
		for (var i = 0; i < node.childNodes.length; i++) {
		
			if( node.childNodes[i].nodeType == 3 ) {
				text += node.childNodes[i].nodeValue;
			}	
			if( node.childNodes[i].nodeType == 1 ) {
				text = me.getInnerText( node.childNodes[i], text);
			}
		}
		return text;
	}
	
	me.getFormTarget = function( elt ) {
		// returns the form action attribute from 
		// if given the child node of that form
		target = null;
		parentElt = elt.parentNode;
		if( parentElt.nodeType == 1 ) {
			if( parentElt.tagName == 'FORM' ) {
				target = parentElt.getAttribute('action');
			}else {
				target = me.getFormTarget( elt.parentNode );
			}
		}else {
			target = me.getFormTarget( elt.parentNode );
		}
		return target;
	}
	
	me.addEvent = function( elm, evType, fn, useCapture ) {
		// Updated version which captures passed events 
		if (elm.AddEventListener) 
		{ 
			elm.AddEventListener(evType, fn, useCapture); 
			return true; 
		} else if (elm.attachEvent) { 
			var r = elm.attachEvent('on' + evType, fn);
			me.listeners[me.listeners.length] = [ elm, evType, fn ];
			return r; 
		} else {
			var xEventFn = elm['on' + evType];
			if (typeof elm['on' + evType] != 'function') 
			{
				elm['on' + evType] = fn;
			} else {
				elm['on' + evType] = function(e) { xEventFn(e); fn(e); };
			}
		}
	}
	
	me.unload = function(){
		// page unload event which removes circular references
		// that may cause memory leaks in IE 5/6
		if( window.attachEvent ){
			for (var i = 0; i < me.listeners.length; i++) {
				me.listeners[i][0].detachEvent( 'on' + me.listeners[i][1], me.listeners[i][2] );
			}
		}
	}
	
	me.getElementsByClassName = function( className ) {
		// returns a collection of element nodes which 
		// have the passed className
		var children = document.getElementsByTagName('*') || document.all;
		var elements = new Array();
		for (var i = 0; i < children.length; i++) 
		{
			var child = children[i];
			var classNames = child.className.split(' ');
			for (var j = 0; j < classNames.length; j++) 
			{
				if (classNames[j] == className) 
				{
					elements.push(child);
					break;
				}
			}
		}
		return elements;
	}
	
	me.findSourceElement = function(e) {
		// finds event source
		if (typeof e == 'undefined')
			var e = window.event;

		var source;
		if (typeof e.target != 'undefined') 
		{
			source = e.target;
		} else if (typeof e.srcElement != 'undefined') {
			source = e.srcElement;
		} else {
			return true;
		}

		if (source.nodeType == 3)
			source = source.parentNode;
		
		return source;
	}
	
	me.getPageOffsetLeft = function(elt) {
		var x;
		x = elt.offsetLeft;
		if (elt.offsetParent != null)
			x += me.getPageOffsetLeft(elt.offsetParent);
		return x;
	}
	
	me.getPageOffsetTop = function(elt) {
		var y;
		y = elt.offsetTop;
		if (elt.offsetParent != null)
			y += me.getPageOffsetTop(elt.offsetParent);
		return y;
	}
	
	//------------------------------------------


	// dom-drag.js
	// 09.25.2001
	// www.youngpup.net
	var Drag = {

		obj : null,

		init : function(o, oRoot, minX, maxX, minY, maxY, bSwapHorzRef, bSwapVertRef, fXMapper, fYMapper)
		{
			o.onmousedown = Drag.start;
			o.hmode = bSwapHorzRef ? false : true ;
			o.vmode = bSwapVertRef ? false : true ;

			o.root = oRoot && oRoot != null ? oRoot : o ;

			if (o.hmode  && isNaN(parseInt(o.root.style.left  ))) o.root.style.left   = '0px';
			if (o.vmode  && isNaN(parseInt(o.root.style.top   ))) o.root.style.top    = '0px';
			if (!o.hmode && isNaN(parseInt(o.root.style.right ))) o.root.style.right  = '0px';
			if (!o.vmode && isNaN(parseInt(o.root.style.bottom))) o.root.style.bottom = '0px';

			o.minX = typeof minX != 'undefined' ? minX : null;
			o.minY = typeof minY != 'undefined' ? minY : null;
			o.maxX = typeof maxX != 'undefined' ? maxX : null;
			o.maxY = typeof maxY != 'undefined' ? maxY : null;

			o.xMapper = fXMapper ? fXMapper : null;
			o.yMapper = fYMapper ? fYMapper : null;

			o.root.onDragStart = new Function();
			o.root.onDragEnd = new Function();
			o.root.onDrag = new Function();
		},

		start : function(e)
		{
			
			var o = Drag.obj = this;
			e = Drag.fixE(e);
			var y = parseInt(o.vmode ? o.root.style.top  : o.root.style.bottom);
			var x = parseInt(o.hmode ? o.root.style.left : o.root.style.right );
			o.root.onDragStart(x, y);

			o.lastMouseX = e.clientX;
			o.lastMouseY = e.clientY;

			if (o.hmode) {
				if (o.minX != null) o.minMouseX = e.clientX - x + o.minX;
				if (o.maxX != null) o.maxMouseX = o.minMouseX + o.maxX - o.minX;
			} else {
				if (o.minX != null) o.maxMouseX = -o.minX + e.clientX + x;
				if (o.maxX != null) o.minMouseX = -o.maxX + e.clientX + x;
			}

			if (o.vmode) {
				if (o.minY != null) o.minMouseY = e.clientY - y + o.minY;
				if (o.maxY != null) o.maxMouseY = o.minMouseY + o.maxY - o.minY;
			} else {
				if (o.minY != null) o.maxMouseY = -o.minY + e.clientY + y;
				if (o.maxY != null) o.minMouseY = -o.maxY + e.clientY + y;
			}

			document.onmousemove = Drag.drag;
			document.onmouseup = Drag.end;

			return false;
		},

		drag : function(e)
		{
			e = Drag.fixE(e);
			var o = Drag.obj;

			var ey = e.clientY;
			var ex = e.clientX;
			var y = parseInt(o.vmode ? o.root.style.top  : o.root.style.bottom);
			var x = parseInt(o.hmode ? o.root.style.left : o.root.style.right );
			var nx, ny;

			if (o.minX != null) ex = o.hmode ? Math.max(ex, o.minMouseX) : Math.min(ex, o.maxMouseX);
			if (o.maxX != null) ex = o.hmode ? Math.min(ex, o.maxMouseX) : Math.max(ex, o.minMouseX);
			if (o.minY != null) ey = o.vmode ? Math.max(ey, o.minMouseY) : Math.min(ey, o.maxMouseY);
			if (o.maxY != null) ey = o.vmode ? Math.min(ey, o.maxMouseY) : Math.max(ey, o.minMouseY);

			nx = x + ((ex - o.lastMouseX) * (o.hmode ? 1 : -1));
			ny = y + ((ey - o.lastMouseY) * (o.vmode ? 1 : -1));

			if (o.xMapper) nx = o.xMapper(y)
			else if (o.yMapper) ny = o.yMapper(x)

			Drag.obj.root.style[o.hmode ? 'left' : 'right'] = nx + 'px';
			Drag.obj.root.style[o.vmode ? 'top' : 'bottom'] = ny + 'px';
			Drag.obj.lastMouseX = ex;
			Drag.obj.lastMouseY = ey;

			Drag.obj.root.onDrag(nx, ny);
			return false;
		},

		end : function()
		{
			document.onmousemove = null;
			document.onmouseup   = null;
			Drag.obj.root.onDragEnd(    parseInt(Drag.obj.root.style[Drag.obj.hmode ? 'left' : 'right']), 
										parseInt(Drag.obj.root.style[Drag.obj.vmode ? 'top' : 'bottom']));
			Drag.obj = null;
		},

		fixE : function(e)
		{
			if (typeof e == 'undefined') e = window.event;
			if (typeof e.layerX == 'undefined') e.layerX = e.offsetX;
			if (typeof e.layerY == 'undefined') e.layerY = e.offsetY;
			return e;
		}
	};
	
	me.addEvent( window, 'load', me.addLinkTracking, false );
	me.addEvent( document, 'keydown', me.keyCheck, false );
	me.addEvent( window, 'unload', me.unload, false );

}

var ajaxLinkTracker = new AjaxLinkTracker();


function XHRConnection() { 
    var me;
    if (this.constructor == XHRConnection){
        me = this
    }else{
        me = arguments[arguments.length-1]
    }
    
	me.Request = me.createXHR();
	 
    me.handler = function () {
		if (me.Request.readyState == 4) {
			if (me.Request.status == 200) {
		
				me.processResponse();
			}
		}
	}
	
	me.send = function ( url, action, fnOK ) {
	    me.URL = url;
		me.Action = action;
		me.fnOK = fnOK;
		if( me.Request != null ){
			me.Request.open(me.Action, me.URL, true);
			me.Request.onreadystatechange = me.handler;
			me.Request.send(null);
		}else{
			alert('Could not load XHR object');
		}
	}
}

XHRConnection.prototype.createXHR = function() {
    try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch (e) {}
    try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch (e) {}
    try { return new XMLHttpRequest(); } catch(e) {}
    return null;
}

XHRConnection.prototype.processResponse = function () {
	this.fnOK(this.Request);
}





