/* @FILE_COMMENT_HEADER_FIRST_LINE

Copyright (C) 2007 Selyem Software

@FILE			analytics.js
@SYNOPSIS	Client for Selyem Analytics.
@VERSION	1.02
@DATE			2007-08-25
@PAGE			n/a
@SITE			n/a
@DEPENDS	n/a

@FILE_COMMENT_HEADER_LAST_LINE */


////////////////////
/// PRIVATE DATA ///
////////////////////

var _sa_version = "1";
var _sa_session_tid = 0;
var _sa_activity_tid = 0;
var _sa_activity_event = null;
var _sa_activity_timestamp = "";
var _sa_code = "";


///////////////
/// ANALYZE ///
///////////////

/// SA ANALYZE ///
function _saAnalyze(code)
	{
	_sa_code = code;
	if(_saSessionStart() )
		_saAnalyzeSession();
	else
		_saAnalyzePage();
	for(i=0;i < document.links.length; i++)
		_saEventAdd(document.links[i], "click", _saAnalyzeClick);
	_saEventAdd(window, "mousemove", _saActivityUpdate);
	}

/// SA ANALYZE SESSION ///
function _saAnalyzeSession()
	{
	d = new Date();
	_saAnalyzeSend("s","&s="+((d.getTime()/1000)-(_saTimeDLS()*60*60))+"&vi="+_saSessionVisitor()+"&d="+document.domain+"&r="+document.referrer+"&a="+navigator.userAgent+"&l="+navigator.browserLanguage+"&p="+navigator.platform+"&u="+navigator.cpu+"&c="+navigator.cookieEnabled+"&o="+navigator.online+"&sw="+screen.width+"&sh="+screen.height+"&cd="+screen.colorDepth+"&z="+(-1*d.getTimezoneOffset()/60)+"&f="+_saFlashVersion()+"&ww="+window.outerwidth+"&wh="+window.outerheight+"&t="+document.title+"&u="+document.URL);
	_saActivityReset(); // page-activity
	_saSessionReset();
	}

/// SA ANALYZE PAGE ///
function _saAnalyzePage()
	{
	_saAnalyzeSend("p","&t="+document.title+"&u="+document.URL);
	_saActivityReset(); // page-activity
	_saSessionReset();
	}

/// SA ANALYZE CLICK ///
function _saAnalyzeClick(e)
	{
	obj = _saEventLink(e);
	c = obj.className;
	_saAnalyzeSend("c","&l="+_saObjectLinkType(obj)+"&t="+_saStringStripHtml(_saObjectLinkDescription(obj))+"&c="+c.match(/__.+__/)+"&r="+obj.href+"&h="+obj.onclick+"&x="+e.clientX+"&y="+e.clientY);
	_saActivityReset(); // click-activity
	_saSessionReset();
	}

/// SA ANALYZE ACTIVITY ///
function _saAnalyzeActivity()
	{
	if(_sa_activity_event)
		_saAnalyzeSend("a", "&a="+_sa_activity_event+"&s="+_sa_activity_timestamp);
	_saActivityReset();
	_saSessionReset();
	}

/// SA ANALYZE END ///
function _saAnalyzeEnd()
	{
	_saAnalyzeSend("e", "");
	}

/// SA ANALYZE SEND ///
function _saAnalyzeSend(event,data)
	{
	if(event != "e" && _saSessionStart() )
		_saAnalyzeSession();
	_saImgSend("http://analytics.selyem.com/_analytics_s.php","_c="+_sa_code+"&_v="+_sa_version+"&_e="+event+"&_s="+_saSessionId()+data);
	}


///////////
/// IMG ///
///////////

/// SA IMG NO CACHE URL ///
function _saImgNoCacheUrl(url)
	{
	return url + (url.indexOf('?') == -1 ? '?' : '&') + 'nocache=' + new Date().getTime();
	}

/// SA IMG SEND ///
function _saImgSend(url,data)
	{
	var image = new Image();
	image.src = _saImgNoCacheUrl(url + "?" + data);
	}


////////////////
/// ACTIVITY ///
////////////////

/// SA ACTIVITY RESET ///
function _saActivityReset()
	{
	_saTimerClear(_sa_activity_tid);
	_sa_activity_tid = _saTimerSet("_saAnalyzeActivity()", 1 * 60 * 1000);
	_sa_activity_event = null;
	}

/// SA ACTIVITY UPDATE ///
function _saActivityUpdate(e)
	{
	_sa_activity_event = e.type;
	_sa_activity_timestamp = new Date().getTime()/1000 - _saTimeDLS()*60*60;
	}


///////////////
/// SESSION ///
///////////////

/// SA SESSION START
function _saSessionStart()
	{
	if(_saCookieGet("_sa_sid") == null)
		{
		_saCookieSet("_sa_sid", _saSessionString());
		_saSessionReset();
		return true;
		}
	return false;
	}

/// SA SESSION RESET ///
function _saSessionReset()
	{
	_saTimerClear(_sa_session_tid);
	_sa_session_tid = _saTimerSet("_saSessionStop()", 10 * 60 * 1000);
	}

/// SA SESSION STOP ///
function _saSessionStop()
	{
	_saAnalyzeEnd();
	_saCookieDelete("_sa_sid");
	_saTimerClear(_sa_session_tid);
	_sa_session_tid = 0;
	}

/// SA SESSION ID ///
function _saSessionId()
	{
	return _saCookieGet("_sa_sid");
	}

/// SA SESSION VISITOR ///
function _saSessionVisitor()
	{
	if(_saCookieGet("_sa_vid") == null)
		_saCookieSet("_sa_vid", _saSessionString(), 6 * 30 * 24 * 60);
	return _saCookieGet("_sa_vid");
	}

/// SA SESSION ///
function _saSessionString()
	{
	h = "abcdefghijklmnopqrstuvwxyz0123456789";
	s = "";
	for(i=0; i<31; i++)
		s += h.charAt(_saRandom(36));
	return s;
	}


//////////////
/// COOKIE ///
//////////////

/// SA COOKIE GET ///
function _saCookieGet(name)
	{
	var start = document.cookie.indexOf(name+"=");
	
	if((!start) && (name != document.cookie.substring(0,name.length)))
		return null;
	if(start == -1)
		return null;
		
	var len = start + name.length+1;
	var end = document.cookie.indexOf(";",len);
	if(end == -1)
		end = document.cookie.length;
	
	return unescape(document.cookie.substring(len,end));
	}

/// SA COOKIE SET ///
function _saCookieSet(name,value,expires,path,domain,secure)
	{
	if(expires)
		{
		var date = new Date();
		date.setTime(date.getTime()+expires*60*1000);
		expires = ";expires="+date.toGMTString();
		}
	else
		expires = "";
	var cookieString = name+"="+escape(value) + expires + ((path) ? ";path="+path : "") + ((domain) ? ";domain="+domain : "") + ((secure) ? ";secure" : "");
	document.cookie = cookieString;
	}
	
/// SA COOKIE DELETE ///
function _saCookieDelete(name,path,domain)
	{
	if(_saCookieGet(name))
		document.cookie = name+"="+((path) ? ";path="+path : "") + ((domain) ? ";domain="+domain : "") + ";expires=Thu, 01-Jan-70 00:00:01 GMT";
	}


/////////////
/// TIMER ///
/////////////

/// SA TIMER SET ///
function _saTimerSet(string,ms)
	{
	return setTimeout(string,ms);
	}

/// SA TIMER CLEAR ///
function _saTimerClear(string)
	{
	clearTimeout(string);
	}
	

/////////////
/// EVENT ///
/////////////

/// SA EVENT ADD ///
function _saEventAdd(obj,evt,fun)
	{
	if(obj.addEventListener)
		{
		obj.addEventListener(evt,fun,false);
		return true;
		}
	else if(obj.attachEvent)
		{
		var r = obj.attachEvent("on"+evt,fun);
		return r;
		}
	else
		obj["on"+evt] = fun;
	}

/// SA EVENT LINK ///
function _saEventLink(e)
	{
	obj = _saEventTarget(e);
	for(;;)
		{
		if(_saObjectIsLink(obj))
			return obj;
		obj = obj.parentNode;
		if(obj == undefined)
			return null;
		}
	}

/// SA EVENT TARGET ///
function _saEventTarget(e)
	{
	return e.target ? e.target : e.srcElement;
	}


//////////////
/// OBJECT ///
//////////////

/// SA OBJECT LINK DESCRIPTION ///
function _saObjectLinkDescription(obj)
	{
	if(_saObjectLinkType(obj) == "text")
		return obj.innerHTML;
	return obj.firstChild.alt ? obj.firstChild.alt : obj.firstChild.src.substr(obj.firstChild.src.lastIndexOf("/")+1);
	}

/// SA OBJECT LINK TYPE ///
function _saObjectLinkType(obj)
	{
	return obj.innerHTML.search(/<img/i) != -1 ? "image" : "text";
	}

/// SA OBJECT IS LINK ///
function _saObjectIsLink(obj)
	{
	return obj.parentNode.innerHTML.search(/<a/i) != -1;
	}


/////////////
/// FLASH ///
/////////////

/// SA FLASH VERSION ///
function _saFlashVersion()
	{
	return "0";
	}


//////////////
/// RANDOM ///
//////////////

/// SA RANDOM ///
function _saRandom(range)
	{
	return Math.floor(Math.random()*range);
	}


/// SA TIME DLS ///
function _saTimeDLS()
	{
	var rightNow = new Date();
	var date1 = new Date(rightNow.getFullYear(), 0, 1, 0, 0, 0, 0);
	var date2 = new Date(rightNow.getFullYear(), 6, 1, 0, 0, 0, 0);
	var temp = date1.toGMTString();
	var date3 = new Date(temp.substring(0, temp.lastIndexOf(" ")-1));
	var temp = date2.toGMTString();
	var date4 = new Date(temp.substring(0, temp.lastIndexOf(" ")-1));
	var hoursDiffStdTime = (date1 - date3) / (1000 * 60 * 60);
	var hoursDiffDaylightTime = (date2 - date4) / (1000 * 60 * 60);
	return hoursDiffDaylightTime - hoursDiffStdTime;
	}
	
	
//////////////
/// STRING ///
//////////////
function _saStringStripHtml(string)
	{
	if(string)
		return string.replace(/(<([^>]+)>)/ig,"");
	else
		return "";
	}


/*
@HISTORY
	1.02 2007-08-25 tbs
		Fixed under-reported page events bug.
	1.01 2007-08-14 tbs
		Strip html tags from link text.
	1.00 2007-07-23 tbs
		Initial version.

@NOTES
	Features
	- split a session in two if too much time has gone by (e.g. an hour?)
	- add input,select,textarea,object?,embed?,iframe?,button,area tracking
	- add accurate/pay geo ip city database
	- correct x,y coords
	- replace EventAdd()'s with one function? (e.g. window.onlick)

*/