var DpLoc = {
	
	/**
	 * The current URL.
	 * @type {String}
	 */
	pageLoc: '',
	
	/**
	 * The referer URL
	 * @type {String}
	 */
	pageRef: '',
	
	/**
	 * The actual page title
	 * @type {Stirng}
	 */
	pageTitle: '',
	
	/**
	 * The domain to save cookies to
	 * @type {String}
	 */
	cookieDomain: '',
	
	/**
	 * The name of the cookie that stores the tracking ID.
	 * @type {String}
	 */
	trackCookieName: 'dploc_tid',
	
	/**
	 * The expiry for tracking cookies. 0 means session cookie.
	 * @type {Integer}
	 */
	trackCookieExpire: 90,
	
	/**
	 * The url to the server where the files are held.
	 * @type {String}
	 */
	serverUrl: '',
	
	/**
	 * Any extra data to save with tracking data (user-defined)
	 * @type {Object}
	 */
	extraData: false,
	
	/**
	 * Any extra data to send with the validate request.
	 * @type {Object}
	 */
	extraDataValidate: false,
	
	/**
	 * The tracking ID for the user.
	 * @type {Integer}
	 */
	trackId: null,
	
	/**
	 * The current image element that is used to send tracking data.
	 * @type {HTMLElement}
	 */
	imgEl: false,
	
	/**
	 * User registered a function to be called when chat is available
	 * @type {Function}
	 */
	chatAvailableFn: null,
	
	/**
	 * User registered a function to be called when chat is unavailable
	 * @type {Function}
	 */
	chatUnavailableFn: null,





	/**
	 * Initiate the tracking system on the page.
	 * 
	 * @param {Object} options Options initiate with. Completely optional.
	 */
	init: function(options) {
		
		options = options || {};
	
		//------------------------------
		// Get info
		//------------------------------
		
		this.pageLoc = document.location.toString();
		this.pageRef = document.referrer.toString();
		this.pageTitle = document.title.toString();
		
		// Cookie domain is .example.com
		if (document.location.host) {
			var host = document.location.host;
			var portSep = host.indexOf(':');
			if (portSep != -1) {
				host = host.substring(0, portSep);
			}
			var parts = host.split('.');
			var domain = '';
			if (parts.length > 1 && parseInt(parts[parts.length - 1]) != parts[parts.length - 1]) {
				domain = '.' + parts[parts.length - 2] + '.' + parts[parts.length - 1];				
				this.cookieDomain = domain;
			}
		}
		
		
		//------------------------------
		// Settings
		//------------------------------
		
		// Script to pass data to		
		if (options.serverUrl) {
			this.serverUrl = options.serverUrl;
		}
		
		// Additional custom information		
		if (options.extraData) {
			this.extraData = options.extraData;
		}
		
		if (options.extraDataValidate) {
			this.extraDataValidate = options.extraDataValidate;
		}
		
		if (options.chatAvailableFn) {
			this.chatAvailableFn = options.chatAvailableFn; 
		}
		
		if (options.chatUnavailableFn) {
			this.chatUnavailableFn = options.chatUnavailableFn; 
		}
		
		// If there are funcs to check chat availablility,
		// we should ask the script to check chat
		if (this.chatAvailableFn || this.chatUnavailableFn) {
			if (!this.extraDataValidate) {
				this.extraDataValidate = {};
			}
			
			this.extraDataValidate.check_chat = true;
		}		
		
		//------------------------------
		// Start everything off; get tracking id
		//------------------------------
		
		if (options.trackCookieName) {
			this.trackCookieName = options.trackCookieName;
		}
		
		if (options.trackCookieExpire) {
			this.trackCookieExpire = options.trackCookieExpire;
		}
		
		this.trackId = this.getCookie(this.trackCookieName, 0);
		
		this.verifyTrackId();
	},
	
	
	
	
	
	/**
	 * First step is to get a tracking ID from the server, or verify an existing tracking ID.
	 * This is done by fetching another javascript file. The server inserts the tracking ID into
	 * some code that sets the cookie in this class.
	 * 
	 * @see #verifyTrackIdDo
	 */
	verifyTrackId: function() {
		var data = this.extraDataValidate || {};
		data.tid = this.trackId;
		
		var url = this.getServerUrl('tid.php', data);
		this.createScriptTag(url);
	},
	
	
	
	
	
	/**
	 * Called by the server to pass the tracking ID back. This sets the tracking cookie,
	 * and then performs the required stuff to track the location etc.
	 * 
	 * @see #verifyTrackId
	 */
	verifyTrackIdDo: function(trackId, misc) {
		trackId = parseInt(trackId);
		
		misc = misc || {};
		
		this.trackId = trackId;
		this.setCookie(this.trackCookieName, trackId, this.trackCookieExpire);
		
		if (this.chatAvailableFn && misc.chatAvailable) {
			this.chatAvailableFn();
		} else if (this.chatUnavailableFn && !misc.chatAvailable) {
			this.chatUnavailableFn();
		}
		
		this.sendData();
	},
	
	
	
	
	
	/**
	 * Perform the tracking functions.
	 */
	sendData: function() {
		
		if (this.imgEl) {
			document.body.removeChild(this.imgEl);	
		}
		
		var data = this.extraData || {};
		data.tid = this.trackId;
		data.url = this.pageLoc;
		data.ref = this.pageRef;
		data.title = this.pageTitle;
		
		var src = this.getServerUrl('loc.php', data);
		this.imgEl = this.sendMiscData(src);
	},
	
	
	
	
	
	/**
	 * Creates an image to send data to the server, but doesn't manage anything else.
	 * 
	 * @param {String} src The url
	 * @param {Boolean} randUrl True to add a random bit to the url to prevent caching
	 * @return {HTMLElement} The image el
	 */
	sendMiscData: function(src, randUrl) {
		var imgEl = document.createElement('img');
		
		// hidden, not display:none since that means it wont load
		imgEl.style.visibility = 'hidden';
		imgEl.style.position = 'absolute';
		imgEl.style.top = '0';
		imgEl.style.left = '-9999px';
		
		if (randUrl) {
			if (src.indexOf('?') == -1) {
				src += '?';
			} else {
				src += '&amp;';
			}
			
			src += 'x=' + (new Date()).getTime();
		}
		
		imgEl.src = src;
		
		document.body.appendChild(imgEl);
		
		return imgEl;
	},
	
	
	
	
	
	/**
	 * Get the server URL for a file, and add any data to the query string
	 * 
	 * @param {String} file The file
	 * @param {Object} data An object as a hash
	 * @param {Boolean} amp True to use &amp; instead of & as the sep
	 * @return {String} The full URL
	 */
	getServerUrl: function(file, data, amp) {
		
		var url = this.serverUrl + 'locator/' + file;
		
		if (data) {
			var add = [];
			for (i in data) {
				add.push(i + '=' + encodeURIComponent(data[i]));
			}
			
			if (amp) {
				add = add.join('&amp;');
			} else {
				add = add.join('&');
			}
			
			if (add) {
				url += '?' + add;
			}
		}
		
		return url;
			
	},
	
	
	
	
	
	/**
	 * Loads another script dynamically.
	 * @param {String} src The script src to load
	 * @param {HTMLElement} el (Optional) The element to append the tag to. Defaults to head.
	 */
	createScriptTag: function(src, el) {
		
		if (!document.getElementsByTagName) {
			return;
		}
		
		if (!el) {
			// Get the head tag (to append the script to)
			// - If its not ready yet (rare), just try again in 500ms
			var head = document.getElementsByTagName('head');
			if (!head || !head[0]) {
				window.setTimeout(function(){
					DpLoc.createScriptTag(src);
				}, 500);
				return;
			}
			el = head[0];
		}
		
		var script = document.createElement('script');
		script.setAttribute('type', 'text/javascript');
		script.setAttribute('src', src);
		
		el.appendChild(script);
		
		return script;
	},
	
	
	
	
	
	/**
	 * Create a new cookie.
	 * 
	 * @param {String} name The name of the cookie
	 * @param {String} value The value
	 * @param {Integer} days How long to keep the cookie. If not specified, will be session
	 */
	setCookie: function(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 = '';
		}
		
		var domain = '';
		if (this.cookieDomain) {
			domain = '; domain=' + this.cookieDomain;
		}

		document.cookie = name+'='+value + expires + domain + '; path=/';
	},
	
	
	
	
	
	/**
	 * Get the value of a cookie
	 * 
	 * @param {String} name The name of the cookie
	 * @param {Object} defaultValue The default value to return if the cookie doesnt exist
	 * @return {Object} The cookie value
	 */
	getCookie: function(name, defaultValue) {
		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);
			}
		}
		
		if (typeof defaultValue != 'undefined') {
			return defaultValue;
		}
		
		return null;
	}
};
