// v1.0 2010-10-18


/**
* @class ToyotaWebTrends interacts with the core WebTrends library to add an abstraction layer to fire events
* @param {string} dcsid The DCSID value issued by WebTrends for the data source to be used by this script
* @param {string} domain The domain name of the Smart Source Data collector.
* @example
* var wt = new ToyotaWebTrends(wt_od_dcs_id, wt_od_domain);
* @constructor
*/
function WebTracker ()
{
	this.loaded=0;
	this.submitted=0;
	this._trackParams = {};
	this._trackers = {};
	this._startTime=0;
  this._maxTime=3600;
  this._lastInteraction=0;
  this._cookieDomain='';
  this._timers = {
  	total: {start: 0, duration: 0, running: 0}
  };
  this._eventParams = {};
}


WebTracker.prototype.AddTracker = function (o)
{
	if(typeof(o) != "object")
		return;
		
	if(o.Type)
	{
		if(typeof(this._trackers[o.Type])=="undefined")
			this._trackers[o.Type]=[];
		this._trackers[o.Type].push(o);
	}
}

WebTracker.prototype.SetDomain = function (d)
{
	this._cookieDomain = d;
}

/**
* Retrieves a query parameter from the document URL
* @private
* @param {Object} object. The link object.
* @author Panalysis Pty Ltd
* @version 1.0
* @return {String} the query parameter value if found
*/
WebTracker.prototype._getParam = function (strParam){
	var _pstr = document.location.search.substring(1);
	var _uparams = _pstr.split("&");
	for(i = 0; i < _uparams.length; i++){
		var np = _uparams[i].split("=");
		if(this._trim(np[0].toLowerCase()) == strParam.toLowerCase())
			return this._trim(np[1]);
	}
	return "";
}

/**
* Retrieves the a query parameter from the document hash
* @private
* @param {Object} object. The link object.
* @author Panalysis Pty Ltd
* @version 1.0
* @return {String} the query parameter value if found
*/
WebTracker.prototype._getHashParam = function (strParam){
	if(strParam =="")
		return "";
	var _pstr = document.location.hash.substring(1);
	var _uparams = _pstr.split("&");
	var _paramlist = new Object();
	for(var i = 0; i < _uparams.length; i++){
		var np = _uparams[i].split("=");
		if(np.length==2)
		{
			_paramlist[this._trim(np[0])] = this._trim(np[1]);
		}
		
		if(strParam != null && strParam != "" && this._trim(np[0].toLowerCase()) == strParam.toLowerCase())
		{
			return this._trim(np[1]);
			break;
		}
	}
	return _paramlist;
}

/**
* Trims leading and trailing whitespace
* @private
* @param {String} value
* @author Panalysis Pty Ltd
* @version 1.0
* @return trimmed string
*/
WebTracker.prototype._trim = function (val){ return val.replace(/^\s+|\s+$/g, '') ; }

/**
* Sets a cookie
* @private
* @param {String} CookieName the name of the cookie
* @param {String} Value the value to store in the cookie
* @param {Date} Expires The time when the cookie will expire
* @param {String} Domain The domain name for the cookie
* @author Panalysis Pty Ltd
* @version 1.0
* @return void
*/
WebTracker.prototype._setCookie = function(cookieName,cookieValue,expire,strDomain) {
	var pdm = "";
	if (strDomain && strDomain!="") 
		pdm=" domain="+strDomain+";"; 

	if((typeof(expire)) == "object")
		document.cookie = cookieName+"="+cookieValue + ";expires="+expire.toGMTString() + "; path=/;" + pdm;
	else
		document.cookie = cookieName+"="+cookieValue + "; path=/;" + pdm;
}

/**
* Returns the value for a specified cookie
* @private
* @param {String} cookieName. Name of the cookie.
* @author Panalysis Pty Ltd
* @version 1.0
* @return {String} Cookie value
*/
WebTracker.prototype._getCookie = function(strParam){
	var _ucookies = document.cookie.split(";");
	for(i = 0; i < _ucookies.length; i++){
		var np = _ucookies[i].split("=");
		if(this._trim(np[0].toLowerCase()) == strParam.toLowerCase())
		{
			var val ="";
			for(i=1;i<np.length;i++)
			{
				if(i>1)
					val += "=";
				
				val += np[i];
			}
			return unescape(this._trim(val));
		}
	}
	return "";
};


/**
* Sends the data to the various tracking objects
* @return void
* @private
*/
WebTracker.prototype._sendData = function()
{
	// initialise the trackers
	for(var c in this._trackParams)
	{
		if(typeof(this._trackers[c]) == "undefined")
		{
			this._log("Tracking object " + c + " not loaded. Ignoring call");
		}
		else
		{
			this._log("Sending: "  + c + " " +  this._trackinObjToStr(this._trackParams[c])) ; 
			for(var i=0;i<this._trackers[c].length;i++)
			{
				this._trackers[c][i]._init(this._trackParams[c]);
			}
		}
	}
	
	// fire the trackers
	for(var t in this._trackers)
	{
		for(var i=0;i<this._trackers[t].length;i++)
		{
			this._trackers[t][i]._sendData();
		}
	}
	
	this._trackParams={};
};

      
/**
* The event listener for any events triggered inside the application
* @param {UserEvent} eventObj
* @public
*/
WebTracker.prototype.ReceiveEvent = function(eventObj)
{
	if(typeof(eventObj) != "object")
		return;
	
	var ev = "";
	
	if(typeof(eventObj.Event) != "undefined")
		ev = eventObj.Event.toLowerCase();
	else if(typeof(eventObj) != "undefined" && typeof(eventObj.EventClass) != "undefined" && typeof(eventObj.Action) != "undefined")
		ev = eventObj.EventClass.toLowerCase() + eventObj.Action.toLowerCase();
	else
		return;
		
	var ts = Math.round(new Date().getTime() / 1000);
	var myT = this;
	if(this._lastInteraction==0)
		this._lastInteraction = ts;
	if(typeof(this._eventParams[ev]) != "undefined")
	{
		this._eventParams[ev].RunHandlers(eventObj,myT);
		this._lastInteraction = ts;
	}
};

/**
* Executes the unload handlers when the page unloads.
* 
* Please note that this handler when it runs may not capture every interaction into WebTrends as the page may unload before the functions are fully executed.
* The method can be called directly from a close button in which case this method can execute fully.
* @example 
* var wt = new ToyotaWebTrends(wt_od_dcs_id, wt_od_domain);
* wt.TrackYarisBlockBanner();
* 
* function closeit()
* {
* 	wt.Unload();
* }
* window.onbeforeunload = closeit;
* 
* or
* 
* &lt;input type="button" onclick="wt.Unload();document.location.href='http://somesite.com/somepage'"&gt;
* @return void
* @public
*/
WebTracker.prototype.Unload = function()
{
	if(typeof(this._unloadEvents)=="undefined")
		return;
	
	var t = this;
	try {
		for(var i=0; i<this._unloadEvents.length; i++)
		{
			this._unloadEvents[i].call(this,t);
		}
	} catch(err) {}
}

/**
* Sets a timer to start counting the number of seconds for a given timer 
* @param {int} TimerID The ID of the timer
* @return void
* @private
*/
WebTracker.prototype._setTimer = function(tid)
{
	var ts = Math.round(new Date().getTime() / 1000);
	var o = ts - this._lastInteraction;
	
	for(var i in this._timers)
	{
		if(tid != undefined && i != "total" && this._timers[i].running==1)
		{
			this._timers[i].running=0;
			if(o > this._maxTime)
				this._timers[i].duration = 0; // reset the timer
			else
				this._timers[i].duration += ts - this._timers[i].start;
			this._timers[i].start=0;
		}
	}
	
	if(typeof(this._timers[tid])=="undefined")
		this._timers[tid]= {start: ts, duration: 0, running: 1};
	else
	{
		this._timers[tid].start = ts;
		this._timers[tid].running=1;
	}
		
	if(this._timers.total.start==0)
	{
		this._timers.total.start=ts;
		this._timers.total.running=1;
	}
	
	if(o > this._maxTime)
	{
		this._timers.total.duration = 0; // reset the timer
		this._lastInteraction=0;
		this._timers.total.start=0;
	}
	else
		this._timers.total.duration = ts - this._timers.total.start;
};

WebTracker.prototype._trackinObjToStr = function(obj) {
	var s = "";
	for(var i in obj) {
		s += "   " + i+": ";
		
		if(typeof(obj[i]) =="object")
			s += this._trackinObjToStr(obj[i]);
		else
			s += obj[i] +"\n";
	}
	return s;
};


WebTracker.prototype._log = function(msg) {
	if(typeof(console) != "undefined" && typeof(window['debug']) !="undefined")
	{
		console.log(msg);
	}
}


/**
* @class Event wrapper to contain the events to fire when the event is triggered
* @param {string} eventName The name of the event.
* @param {string} fireWhen When the event should be processed. Accepted values are once and always. If the value is set to once, the event will only fire once during the visitors interaction with the banner or until the banner is reloaded.
* @param {function} handler The event handler function.
* @example
* var myT = this; // add a reference to the main object for the call back later on
* var sliderevent = new EventObj(
*   "once", // only record this event once
*   function() { // the function to execute when the event is called
*     var evObj = arguments[0]; // get the event container object with the parameters that is passed to the function
*     myT._dcsext.Banner_Name=myT.BannerName; // the name of the banner
*     myT._dcsext.Slider_Event = 1; // call the WebTrends custom parameter associated with the measure. These MUST match exactly and the custom reports set up first.
*     // add other functions etc as required
*     if(typeof(evObj) != "undefined") { myT._sendData(); }
*   }
* );
*	@public
*/ 
var EventObj = function(fireWhen,handler)
{
  this.Fire=fireWhen;
  this._handlers=Array();
  if(typeof(handler)=="function")
  	this._handlers.push(handler);
  
  /**
  * Adds an event handler to the list of events
  * @param {function} f The function to run as the handler
  * @public
  */
  this.AddHandler = function(f) { 
  	this._handlers.push(f);
  }
  
  /**
  * Runs the event handlers associated with the specified event. Only used to call other events within the code. Use the ReceiveEvent method instead.
  * @param {UserEvent} userEvent A user event object containing the parameters for the event to be recorded
  * @public
  * @see UserEvent
  * @return void
  */
  this.RunHandlers = function(evObj,tObj)
  {
  	var isOK = 0;
  	if(this.Fire.toLowerCase() == "once")
  	{
  		var c = tObj._getCookie(tObj._cookieName);
  		if(c=="") isOK = 1;
  		
  		var key = evObj.Event;
  		if(typeof(evObj.EventClass) != "undefined")
  			key = (evObj.EventClass + evObj.Action).toLowerCase();
  		
  		if(c.indexOf(key)>=0)
  			isOK=0;
  		else
  		{
  			c+= "|" + key;
  			tObj._setCookie(tObj._cookieName,c);
  			isOK=1;
  		}
  	}
  	else if(this.Fire.toLowerCase()=="always")
  		isOK = 1;
  		
  	if(isOK==1)
  	{
	  	for(var i=0; i<this._handlers.length;i++)
	  	{
	  		this._handlers[i].call(this,evObj);
	  	}
	  }
  }
};

