
function MapSurface()
{
    var me;
    if (this.constructor == MapSurface){
        me = this;
    }else{
        me = arguments[arguments.length-1];
    }

	me.apiUrl = 'http://www.mapsurface.com/api/1.0/';
	//me.apiUrl = 'http://localhost/mapsurface2/api/1.0/';

	me.configTracker = function(){
		if(! document.location.href.indexOf("file:///") > -1 ) {
			me.recordPage();
			me.addLinkTracking();
		}
	}
	
	me.recordPage = function(){	
		entity = encodeURIComponent( document.location.href );
		referrer = encodeURIComponent( document.referrer );	
		url = me.apiUrl + 'addRequest.aspx?';
		url += 'rf=' + referrer;
		url += '&url=' + entity;
		me.addImage( url, true ); 
	}
	
	me.addLinkTracking = function(){
		if (!document.getElementsByTagName) return false;
		
		links = document.getElementsByTagName('a');
		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);
			}
		}
		
		inputs = document.getElementsByTagName('input');
		for (var i = 0; i < inputs.length; i++) {
		
			type = inputs[i].getAttribute('type');
			if ( type == 'submit' || type == 'button' ){
				me.addEvent( inputs[i], 'mousedown', me.recordClick, false );
				me.addEvent( inputs[i], 'keypress', me.linkKeyPress, false );
				if (! inputs[i].getAttribute('id') ){
					inputs[i].setAttribute('id','button_' + i);
				}	
			}
		}
	}
	
	me.linkKeyPress = function(e) {
		var keyID = (window.event) ? event.keyCode : e.keyCode;
		if (keyID == 13) {
			me.recordClick(e);
		}
	}
	
	me.recordClick = function(e){
	
		source = me.findEventSource(e);
		tag = source.tagName;
		var id,label,target,url
		
		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';
			}
		}
		
		target = encodeURIComponent( target )
		url = encodeURIComponent( document.location.href );
		encodedLabel = encodeURIComponent( me.simpleEncode( label ) );
		label = encodeURIComponent( label );
		
		imgurl = me.apiUrl + 'addLink.aspx?id=' + id + '&label=' + label + '&target=' + target + '&url=' + url + '&encodedlabel=' + encodedLabel + '&order=' + me.findLinkPos( id );
		me.addImage( imgurl, true ); 
	}
	
	//----------------------
	
	me.addImage = function( passedurl, reload ) {
		eltImg = document.createElement( 'img' );
		eltImg.setAttribute('id','tackerloadimg');
		eltImg.setAttribute('width',1);
		eltImg.setAttribute('height',1);
		me.addEvent(eltImg, 'load', me.removeImage, false);
		urlcompsite = passedurl 
		if( reload )
			urlcompsite += '&rand=' + Math.random(); 
			
		urlcompsite += '&accid=' + msAccID;
		eltImg.setAttribute("src", urlcompsite);
		document.body.appendChild( eltImg );
	}
	
	me.removeImage = function() {
		if( document.getElementById('tackerloadimg') )
		{
			var eltImg = document.getElementById('tackerloadimg');
			eltImg.parentNode.removeChild(eltImg);
		}
	}

	me.addScript = function( url ) {
		
		eltScript = document.createElement("script");
		eltScript.setAttribute('id','tackerloadimg');
		eltScript.setAttribute("type", "text/javascript");
		
		if( url.indexOf('?') > -1)
			url += '&';
		else
			url += '?';
			
		url += 'rand=' + Math.random() + '&accid=' + msAccID;
		eltScript.setAttribute("src", url);
		document.getElementsByTagName('head')[0].appendChild(eltScript);
		return eltScript;
	}
	
	//----------------------
	
	me.altKeyCheck = function(e) {
		var keyID = (window.event) ? event.keyCode : e.keyCode;
		var altKey = (window.event) ? event.altKey : e.altKey;
		var ctrlKey = (window.event) ? event.ctrlKey : e.ctrlKey;
		var shiftKey = (window.event) ? event.shiftKey : e.shiftKey;
		
		// keyID == 0 for Mac Firefox
		if(((keyID == 88)||(keyID == 900))&&(altKey == true))  // Alt X
		{ 
			eltScript = me.addScript( me.apiUrl + 'mapsurfacedashboard.js' );
		}else if( ctrlKey && shiftKey && (keyID == 88)||(keyID == 900) ){  // Shift Ctrl X
			eltScript = me.addScript( me.apiUrl + 'mapsurfacedashboard.js' );	
		}
	}


	me.findEventSource = function(e) {
		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.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.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 += me.replaceChars( node.childNodes[i].nodeValue );
			}	
			if( node.childNodes[i].nodeType == 1 ) {
				text = me.getInnerText( node.childNodes[i], text);
			}
		}
		return text;
	}
	
	//----------------------

	me.findNodeText = function( node, text ) {
		for (var i = 0; i < node.childNodes.length; i++)
		{
			if( node.childNodes[i].nodeType == 3 )
				text += me.replaceChars( node.childNodes[i].nodeValue );
				
			if( node.childNodes[i].nodeType == 1 )
				text = me.findNodeText( node.childNodes[i], text);

		}
		return text;
	}
	
	me.findImageAlt = function( elt ) {
		text = '';
		if( elt.getElementsByTagName('IMG').length > -1 )
		{
			eltCol = elt.getElementsByTagName('IMG');
			if( eltCol.length > 0 )
				text = eltCol[0].getAttribute('alt');
		}
		return text;
	}


	me.findLink = function( elt ) {
		if( elt.tagName == 'A' )
			return elt;
		else
			if(	elt.parentNode )
				return me.findLink( elt.parentNode );
			else
				return null;
	}
	
	me.getScrollTop = function() {
		return window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
	}

	me.getElementsByClassName = function( 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.simpleEncode = function( input ) {
		output = '';
		if( typeof input != 'undefined' )
		{
			for( i = 0; i < input.length; ++i )
			{
				codeNum = input.charCodeAt(i);
				if( (codeNum >= 48) && (codeNum <= 59) )
					output += input.charAt(i);
				
				if( (codeNum >= 65) && (codeNum <= 90) ) 
					output += input.charAt(i);
				
				if( (codeNum >= 97) && (codeNum <= 122) ) 
					output += input.charAt(i);
					
				if( (codeNum == 120) || (codeNum == 32) ) 
					output += ' ';
			}
		}
		return me.trim( output );
	}
	
	
	me.trim = function( str ) {
		return str.replace(/^\s*|\s*$/g,"");
	}

	me.findLinkPos = function( id ) {
		posNum = 0;
		linksElements = document.getElementsByTagName('a');
		for (var i = 0; i < linksElements.length; i++) 
		{
			if (linksElements[i].id == id) 
				posNum = i;
		}
		return posNum;
	}

	me.replaceChars = function ( input ) {
		input = input.replace(String.fromCharCode(160),String.fromCharCode(32));
		return input;
	}
	
	me.encodeUrl = function( str )
	{
		return encodeURIComponent( str );
	}

	
	me.listeners = [];

	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.addEvent(window, 'load', me.configTracker, false);
	me.addEvent(document, 'keydown', me.altKeyCheck, false);
	me.addEvent(window, 'unload', me.unload, false );

}

var _ms = new MapSurface();





