// $Revision: 24856 $
// $Date: 2008-11-24 19:32:20 +0100 (Mon, 24 Nov 2008) $

////////////////////////////////////////////////////////////////////////
// Analytics class
////////////////////////////////////////////////////////////////////////

/**
 * Main Analytics class.
 * The Analytics is available as a global variable analytics
 * 
 * @author     Daniel Sevcik <daniel.sevcik@dev.webdevelopers.cz>
 * @version    $Revision: 24856 $
 * @access     public
 */
var Analytics=function() {
    this.currentValues={};		
		
    this.constructor=function() {
	notice('Analytics (revision '+'$Revision: 24856 $'.replace(/[^0-9]/g, '')+')');
	var thisObj=this;

	this._initReferer();
	this._initEntryPage();
				
	if (window.attachEvent) {
	    window.attachEvent("onunload", function() {thisObj.onUnload();});
	} else if (document.addEventListener) {
	    window.addEventListener("unload", function() {thisObj.onUnload();}, true);
	}
	if (window.debugMsgs.length) {
	    alert(window.debugMsgs.join("\n\n"));
	    window.debugMsgs=[];
	}
    }

    /**
     * Sets the entry page if not known yet.
     *
     * @access private
     * @return void
     */
    this._initEntryPage=function() {
	var referer=document.referrer || document.referer;
	var defaultVal;
				
	if (this._isURLInSite(referer)) {
	    defaultVal=referer;
	} else {
	    defaultVal=document.location.href;
	}
	this._initValue('entryPage', defaultVal, false);				
	notice('entryPage='+getAnalyticsCookie('entryPage'));
	this.currentValues['entryPage']=getAnalyticsCookie('entryPage');
    }
		
    /**
     * Sets the referer if not known yet.
     * See wiki/Analytics_Module
     *
     * @access private
     * @return void
     */
    this._initReferer=function() {
	// Set the current referer only if it is not originating from current website.
	var refererHeader=document.referrer || document.referer;
	var refererAnalytics=getAnalyticsCookie('originalReferer');

	notice('originalReferer: header:='+refererHeader+', stored:='+refererAnalytics);
	
	if (refererAnalytics) {
	    if (refererAnalytics == 'Analytics:Blocked' && refererHeader) {
		this._initValue('originalReferer', 'Analytics:Typed-in', true);
	    }
	} else {
	    if (refererHeader) {
		if (this._isURLInSite(refererHeader)) { 
		    this._initValue('originalReferer', 'Analytics:In-site:'+refererHeader, true);
		} else {
		    this._initValue('originalReferer', refererHeader, true);								
		}
	    } else {
		this._initValue('originalReferer', 'Analytics:Blocked', true);
	    }
	}
	notice('originalReferer='+getAnalyticsCookie('originalReferer'));
	this.currentValues['originalReferer']=getAnalyticsCookie('originalReferer');
    }

    this._isURLInSite=function(url) {
	return url && this.extractHost(url) == document.location.host;				
    }

    /**
     * Sets the referer if not known yet.
     * Note: Always update the referrer for every external link (agreed)
     *
     * @access private
     * @param string name of the value
     * @param string defaultVal default value
     * @param bool override if defaultVal is non-empty always override the current value with the defaultVal 
     * @return void
     */
    this._initValue=function(name, defaultVal, override) {
	// Set the default
	var val=false;
	if (typeof defaultVal !== 'string' || !defaultVal.length) {
	    val=getAnalyticsCookie(name);
	    warning('Cannot get the default value for '+name+'!\nOld cookie value: '+val+'\nDefault: '+defaultVal);
	} else if (override || !getAnalyticsCookie(name)) {
	    val=defaultVal;
	    setAnalyticsCookie(name, val);
	} else {
	    val=getAnalyticsCookie(name);						
	}
    }

    this.onUnload=function() {
	notice('Re-saving all the values..');
	for(var name in this.currentValues) {
	    if (this.currentValues[name]) {
		setAnalyticsCookie(name, this.currentValues[name]);
	    }
	}
	if (window.debugMsgs.length) {
	    alert(window.debugMsgs.join("\n\n"));
	    window.debugMsgs=[];
	}
    }

    /**
     * Extract the host name from the URL.
     *
     * @access public
     * @return string
     */
    this.extractHost=function(url) {
	var parts=(url+'').match(/:\/\/([^:/]+)/);
	return parts && parts[1] && parts[1].toLowerCase();
    }

    // Call constructor
    this.constructor();
}

////////////////////////////////////////////////////////////////////////
// Function definitions
////////////////////////////////////////////////////////////////////////
function notice(msg) {return debug(msg, 0);}
function warning(msg) {return debug(msg, 1);}
function error(msg) {return debug(msg, 2);}

/**
 * Print the debugging msg to the javascript console (FireBug) if available.
 *
 * @access public
 * @param string msg
 * @param int severity 0: notice (default), 1: warning, 2: error
 * @return string msg
 */
window.debugMsgs=[];
function debug(msg, severity) {
		
    if (!window.console || !window.console.log) {  // No FireBug installed
	// For other browsers...
	if (document.location.search.match(/\?debug/) || (document.referer || document.referrer).match(/debug/)) {
	    window.debugMsgs.push(msg);
	}
	return;
    }
    msg='System: '+msg;

    switch (severity) {
    case 2: window.console.err(msg); break
    case 1: window.console.warn(msg); break
    default: window.console.log(msg);				
    }
}

/**
 * 
 *
 * @access Public
 * @param string name
 * @param string value
 * @param string expiration in seconds relative to the current time
 * @param string path
 * @param string domain
 * @param bool secure
 * @return void
 */
function setAnalyticsCookie(name, value) {
    name='analytics_'+name;
    var expiration=3600 * 24 * 30;
    var path='/';
    var domain=document.location.host.replace(/^www.?\./, '');
    var secure=false;

    var expirationDate;
    if (expiration) {
	expirationDate=new Date();
	expirationDate.setTime (expirationDate.getTime() + expiration);
    } 
    document.cookie = name + "=" + escape (value) + ((expirationDate) ? "; expires=" + expirationDate.toGMTString() : "") + (path ? "; path=" + path : "") + ((domain) ? "; domain=" + domain : "") + ((secure) ? "; secure" : "");
}

/**
 * 
 *
 * @access private
 * @param int 
 * @param 
 * @param 
 * @return void
 */
function getAnalyticsCookie(name) {
    name='analytics_'+name;		
    var arg = name + "=";
    var alen = arg.length;
    var clen = document.cookie.length;
    var i = 0;
    while (i < clen) {
	var j = i + alen;
	if (document.cookie.substring(i, j) == arg)
	    return _getCookieVal (j);
	i = document.cookie.indexOf(" ", i) + 1;
	if (i == 0) break;
    }
    return null;
}

/**
 * 
 *
 * @access private
 * @param int 
 * @param 
 * @param 
 * @return void
 */
function _getCookieVal(offset) {
    var endstr = document.cookie.indexOf (";", offset);
    if (endstr == -1)
	endstr = document.cookie.length;
    return unescape(document.cookie.substring(offset, endstr));
}

/**
 * 
 *
 * @access private
 * @param int 
 * @param 
 * @param 
 * @return void
 */
function deleteAnalyticsCookie(name) { 
    var path='/';
    var domain=document.location.host.replace(/^www.?\./, '');
    if (getAnalyticsCookie(name)) {
	document.cookie='analytics_' + name + "=" + ((path) ? "; path=" + path : "") + ((domain) ? "; domain=" + domain : "") + "; expires=Thu, 01-Jan-70 00:00:01 GMT";
    }
}

////////////////////////////////////////////////////////////////////////
// INITIALIZATION
////////////////////////////////////////////////////////////////////////

new Analytics();
