sst_debug = window.location.toString().substring(0,20) == 'http://localhost/sst';
sst_account_id = null;		// user needs to set this later

sst_home_url = sst_debug ? "http://localhost/sst" : document.location.protocol+"//simplestartuptools.com";

// Image object for ping-backs; have to keep in global scope to make sure it doesn't get GC'ed
sst_img_dummy = new Image();
	
// The GUID for this page-load only.
sst_load_guid = sst_guid();

// The GUID for this user's web-session on this website.
sst_visitor_id = sst_readCookie( "__sstv" );
if ( ! sst_visitor_id )
{
	sst_visitor_id = sst_readCookie( "sst_visitor_id" );		// old cookie name, still supported for continuity
	if ( ! sst_visitor_id )			// old cookie not present
	{
		sst_visitor_id = window.location.toString().indexOf('smartbear') > 0 && sst_readCookie( "visitor" );		// Smart Bear visitor cookie?
		if ( ! sst_visitor_id )		// truly a new visitor?
		{
			sst_visitor_id = sst_guid();
		}
	}
	else						// old-style cookie; delete it as we add the new one
	{
		sst_eraseCookie( "sst_visitor_id" );
	}
	sst_createCookie( "__sstv", sst_visitor_id, 300 );
}

function sst_S4() {
   return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
}
function sst_guid() {
   return (sst_S4()+sst_S4()+sst_S4()+sst_S4()+sst_S4()+sst_S4()+sst_S4()+sst_S4());
}

// Best style of URL encoding, falling back to weaker algorithm if unavailable
function sst_urlencode( text )
{
	return window.encodeURIComponent ? encodeURIComponent(text) : escape(text);
}

// Attach a listener to any event, cross-browser
function sst_hook_event( el, eventName, callback )
{
	if ( el.addEventListener )		// W3C-style, most modern browsers support
		el.addEventListener( eventName, callback, false );
	else if ( el.attachEvent )		// IE-style
		el.attachEvent( 'on'+eventName, callback );
}

// Gets the target element from a hook event, or null if we can't
function sst_get_event_target( e )
{
	if(!e)var e=window.event;
	var t=e.target?e.target:e.srcElement;
	if(t.nodeType&&t.nodeType==3)
		t=t.parentNode;
	return t;
}

// Gets the parent element of any element, or null if none
function sst_get_element_parent( el )
{
	return el.parentElement || el.parentNode;
}

// Gets any sort of URL attribute out of an element, looking up the parent chain if it isn't there
function sst_get_element_url( el )
{
	do{
		if(el.href&&!el.src)return el.href;
		el=sst_get_element_parent(el);
	} while(el);
	return"";
}

// Gets any sort of title attribute out of an element, looking up the parent chain if it isn't there
function sst_get_element_title( el )
{
	do{
		var txt=el.text?el.text:el.innerText;
		if(txt)return txt;
		if(el.alt)return el.alt;
		if(el.title)return el.title;
		if(el.src)return el.src;
		el=sst_get_element_parent(el);
	} while(el);
	return"";
}

function sst_createCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

function sst_readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function sst_eraseCookie(name) {
	sst_createCookie(name,"",-1);
}

// Converts a javascript map into a URL-encoded name/value pair string
function sst_map_to_url( map )
{
	var k = 0;
	var url = "";
	for ( var key in map )
	{
		if ( k++ > 0 )
			url += '&';
		url += sst_urlencode(key) + '=' + sst_urlencode(map[key]);
	}
	return url;
}

// Truncate with ellipses if the string is too long
function sst_truncate( str, n )
{
	if ( str.length > n )
		return str.substr( 0, n-3 ) + '...';
	return str;
}

function sst_pause( iMilliseconds )
{
	var end = new Date().getTime() + iMilliseconds;
	var cur;
	do { cur = new Date(); }
	while ( cur.getTime() < end );
}

// Log an event back to the SST servers
function sst_ping( type, waitFor, params )
{
	var k = 0;
	
	// Always add the account GUID to AJAX calls.
	if ( ! sst_account_id )
	{
		alert( "FAIL: sst_set_account() has to be called first." );
		return false;
	}
	params['ver'] = 6;
	params['account_id'] = sst_account_id;
	params['visitor_id'] = sst_visitor_id;
	params['type'] = type;
	
	// Finish building the URL
	var url = sst_home_url + '/api/ping.php?' + sst_map_to_url(params);
	if ( url.length >= 2040 )		// XXX: Long URL backstop.  This completely sucks, but shouldn't blow past it.  Just don't err.
	{
		url = url.substr(0,2040);		// XXX: is truncation better than nothing?
	}
	
	// Load
	sst_img_dummy.src = url;
	
	// If the load is supposed to be in-line, wait for it
	if ( waitFor )
		sst_pause(500);
}

// Munge label text into something we'll actually submit
function sst_normalize_label( label )
{
	var i = label.lastIndexOf('$');
	if ( i >= 0 )
		label = label.substr( i+1 );
	return label;
}

// Returns true if this label should be uploaded, false to ignore it
function sst_accept_label( label )
{
	if (// ASP.NET internals 
		label == "__VIEWSTATE" || label == "__EVENTARGUMENT" || 
		label == "__EVENTTARGET" || label == "__EVENTVALIDATION" ||
		label == "__LASTFOCUS" ||
		// SST special fields we don't need to repeat
		label == "sst_visitor_id"
	)
		return false;
	return true;
}

// Allows the user to send custom forms too.
function sst_send_form( name, waitFor, fields )
{
	try
	{
		// Start known param block
		var params = {
			'form_raw_id': sst_load_guid,		// This particular invocation of the form
			'name': name ? name : ''			// check for null/undefined
		};
		
		// Load fields
		if ( !!fields )
		{
			for ( var key in fields )
			{
				params[ sst_truncate( 'f_' + key, 255 ) ] = sst_truncate( fields[key], 255 );
			}
		}
		
		// Ping the form
		sst_ping( 'form', waitFor, params );			// wait before proceeding
	}
	catch ( e )
	{
		if ( sst_debug )
		{
			alert( "SST SEND EVENT FAIL: " + objToString(e,2) );
		}
	}
}

function sst_autoFormOnSubmit( form )
{
	try
	{
		// Load form name
		var name = form.getAttribute('name');
		if ( ! name )
			name = form.getAttribute('id');
		
		// Load fields
		var emptyCounter = 0;
		var fields = {};
		for ( var e = 0 ; e < form.length ; e++ )
		{
			var el = form.elements[e];
			var label = sst_normalize_label( el.name );
			if ( sst_accept_label( label ) )
			{
				if ( label.length == 0 )		// handle empties, particularly for submit buttons
					label = '__blank' + (++emptyCounter);
				fields[ label ] = el.value;
			}
		}
		
		// Senf the form
		sst_send_form( 'form', true, fields );
	}
	catch ( e )
	{
		if ( sst_debug )
		{
			alert( "FORM SUBMIT FAIL: " + objToString(e,2) );
		}
	}
	
	// Always proceed with form submit!  Never block the user experience
	return true;
}

function sst_attach_form( formName )
{
	// Attach all forms which match ID or NAME attributes
	for ( var i = 0 ; i < document.forms.length ; i++ )
	{
		var f = document.forms[i];
		if ( formName == '*' || f.getAttribute('id') == formName || f.getAttribute('name') == formName )
		{
			sst_hook_event( f, "submit", function(ev){ sst_autoFormOnSubmit( sst_get_event_target(ev) ); } );
		}
		
		// Regardless of whether we capture form data, fill hidden fields with our info
		for ( var k in f.elements )
		{
			try
			{
				if ( f.elements[k].name == 'sst_visitor_id' )
					f.elements[k].value = sst_visitor_id;
			}
			catch(e){/*ignore*/}
		}
	}
}

function sst_attach_all_forms()
{
	sst_attach_form( '*' );
}

function sst_phone_home()
{
	try
	{
		var params = {
			'url': sst_truncate( window.location.toString(), 255 ),
			'page_title': sst_truncate( document.title, 255 ),
			'referer': sst_truncate( document.referrer, 255 )
		};
		sst_ping( 'ping', false, params );
	} catch(e){ if ( sst_debug ) alert("Error phoning home: " + e.message); }
}

function sst_ping_on_event( type, ev )
{
	try
	{
		var el = sst_get_event_target( ev );
		var params = {
			'url': sst_truncate( sst_get_element_url(el), 255 ),
			'referer': sst_truncate( window.location.toString(), 255 ),
			'page_title': sst_truncate( sst_get_element_title(el), 255 )
		};
		sst_ping( type, true, params );
	}catch(e){ if ( sst_debug ) alert(objToString(e)); }
	return true;
}

function sst_hooks_on_load()
{
	var pattern_not_html=new RegExp("\\.(7z|aac|avi|cab|csv|doc(x|m)?|exe|flv|gif|gz|jpe?g|js|m4a|mp(3|4|e?g)|mov|msi|ods|pdf|phps|png|ppt(x|m)?|rar|rtf|sea|sit|tar|torrent|txt|wma|wmv|xls(x|m)?|xml|zip)$","i");
	var pattern_url=new RegExp("^(https?|ftp|telnet|mailto):","i");
	var pattern_url_insite=new RegExp("^https?:\/\/(.*)"+location.host.replace(/^www\./i,""),"i");
	var aTags = document.getElementsByTagName("a");
	for( var i=0;i<aTags.length;i++ )
	{
		var a = aTags[i];
		var url = a.href;
		if ( pattern_url.test(url) )		// not e.g. javascript or '#' or something not link-able
		{
			if ( ! pattern_url_insite.test(url) )
				sst_hook_event( a, 'mousedown', function(ev){ return sst_ping_on_event( 'outbound', ev ); } );
			if ( pattern_not_html.test(url) )
				sst_hook_event( a, 'mousedown', function(ev){ return sst_ping_on_event( 'media', ev ); } );
		}
	}
}

function sst_set_account( accountGuid )
{
	try
	{
		if ( sst_account_id )
		{
			alert( "FAIL: sst_set_account() has already been called." );
			return;
		}
		sst_account_id = accountGuid;
		
		// Always phone home!
		sst_phone_home();
		
		// Set the GetClicky custom data fields to track through
		if ( typeof(window['clicky_custom']) == 'undefined' )
			window['clicky_custom'] = {};
		if ( typeof(window.clicky_custom['session']) == 'undefined' )
			window.clicky_custom['session'] = {};
		window.clicky_custom.session['sst_account_id'] = sst_account_id;
		window.clicky_custom.session['sst_visitor_id'] = sst_visitor_id;
		
		// Hook outbound links and non-HTML downloads, after page-load
		sst_hook_event( window, 'load', sst_hooks_on_load );
		
	} catch(e) {
		// always eat and throw away Javascript errors so customers aren't nailed.
	}
}



