var trackerJSDomain = "http://www.fxgm.eu/CookieMonster/",
    cookieKey = "MID7",
    errors = "",
    swfStore = null,
    cookieInitilized = false,
    savedMid = null,
    cookieReadyCallback;

jQuery.support.cors = true; // force cross-site scripting (as of jQuery 1.5)

// Flash Detect (from www.featureblend.com)
var FlashDetect = new function () {	var self = this; self.installed = false; self.raw = ""; self.major = -1; self.minor = -1; self.revision = -1; self.revisionStr = ""; var activeXDetectRules = [{ "name": "ShockwaveFlash.ShockwaveFlash.7", "version": function (obj) { return getActiveXVersion(obj); } }, { "name": "ShockwaveFlash.ShockwaveFlash.6", "version": function (obj) { var version = "6,0,21"; try { obj.AllowScriptAccess = "always"; version = getActiveXVersion(obj); } catch (err) { } return version; } }, { "name": "ShockwaveFlash.ShockwaveFlash", "version": function (obj) { return getActiveXVersion(obj); } }]; var getActiveXVersion = function (activeXObj) { var version = -1; try { version = activeXObj.GetVariable("$version"); } catch (err) { } return version; }; var getActiveXObject = function (name) { var obj = -1; try { obj = new ActiveXObject(name); } catch (err) { obj = { activeXError: true }; } return obj; }; var parseActiveXVersion = function (str) { var versionArray = str.split(","); return { "raw": str, "major": parseInt(versionArray[0].split(" ")[1], 10), "minor": parseInt(versionArray[1], 10), "revision": parseInt(versionArray[2], 10), "revisionStr": versionArray[2] }; }; var parseStandardVersion = function (str) { var descParts = str.split(/ +/); var majorMinor = descParts[2].split(/\./); var revisionStr = descParts[3]; return { "raw": str, "major": parseInt(majorMinor[0], 10), "minor": parseInt(majorMinor[1], 10), "revisionStr": revisionStr, "revision": parseRevisionStrToInt(revisionStr) }; }; var parseRevisionStrToInt = function (str) { return parseInt(str.replace(/[a-zA-Z]/g, ""), 10) || self.revision; }; self.majorAtLeast = function (version) { return self.major >= version; }; self.minorAtLeast = function (version) { return self.minor >= version; }; self.revisionAtLeast = function (version) { return self.revision >= version; }; self.versionAtLeast = function (major) { var properties = [self.major, self.minor, self.revision]; var len = Math.min(properties.length, arguments.length); for (i = 0; i < len; i++) { if (properties[i] >= arguments[i]) { if (i + 1 < len && properties[i] == arguments[i]) { continue; } else { return true; } } else { return false; } } }; self.FlashDetect = function () { if (navigator.plugins && navigator.plugins.length > 0) { var type = 'application/x-shockwave-flash'; var mimeTypes = navigator.mimeTypes; if (mimeTypes && mimeTypes[type] && mimeTypes[type].enabledPlugin && mimeTypes[type].enabledPlugin.description) { var version = mimeTypes[type].enabledPlugin.description; var versionObj = parseStandardVersion(version); self.raw = versionObj.raw; self.major = versionObj.major; self.minor = versionObj.minor; self.revisionStr = versionObj.revisionStr; self.revision = versionObj.revision; self.installed = true; } } else if (navigator.appVersion.indexOf("Mac") == -1 && window.execScript) { var version = -1; for (var i = 0; i < activeXDetectRules.length && version == -1; i++) { var obj = getActiveXObject(activeXDetectRules[i].name); if (!obj.activeXError) { self.installed = true; version = activeXDetectRules[i].version(obj); if (version != -1) { var versionObj = parseActiveXVersion(version); self.raw = versionObj.raw; self.major = versionObj.major; self.minor = versionObj.minor; self.revision = versionObj.revision; self.revisionStr = versionObj.revisionStr; } } } } } (); }; FlashDetect.JS_RELEASE = "1.0.4";

// SwfStore for cross-domain flash cookies (from nfriedly.com)
(function () { "use strict"; var counter = 0; var alpnum = /[^a-z0-9_]/ig; window.SwfStore = function (config) { config = config || {}; var defaults = { swf_url: 'storage.swf', namespace: 'swfstore', debug: false, timeout: 10, onready: null, onerror: null }; var key; for (key in defaults) { if (defaults.hasOwnProperty(key)) { if (!config.hasOwnProperty(key)) { config[key] = defaults[key] } } } config.namespace = config.namespace.replace(alpnum, '_'); if (window.SwfStore[config.namespace]) { throw "There is already an instance of SwfStore using the '" + config.namespace + "' namespace. Use that instance or specify an alternate namespace in the config." } this.config = config; function id() { return "SwfStore_" + config.namespace + "_" + (counter++) } function div(visible) { var d = document.createElement('div'); document.body.appendChild(d); d.id = id(); d.style.background = "transparent"; if (!visible) { d.style.position = "absolute"; d.style.top = "-2000px"; d.style.left = "-2000px" } return d } if (config.debug) { if (typeof console === "undefined") { var loggerOutput = div(false); window.console = { log: function (msg) { var m = div(false); m.innerHTML = msg; loggerOutput.appendChild(m) } } } this.log = function (type, source, msg) { source = (source === 'swfStore') ? 'swf' : source; if (typeof (console[type]) !== "undefined") { console[type]('SwfStore - ' + config.namespace + ' (' + source + '): ' + msg) } else { console.log('SwfStore - ' + config.namespace + ": " + type + ' (' + source + '): ' + msg) } } } else { this.log = function () { } } this.log('info', 'js', 'Initializing...'); SwfStore[config.namespace] = this; var swfContainer = div(config.debug); var swfName = id(); var flashvars = "logfn=SwfStore." + config.namespace + ".log&amp;" + "onload=SwfStore." + config.namespace + ".onload&amp;" + "onerror=SwfStore." + config.namespace + ".onerror&amp;" + "LSOName=" + config.namespace; swfContainer.innerHTML = '<object height="1" width="1" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab" id="' + swfName + '" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000">' + '	<param value="' + config.swf_url + '" name="movie">' + '	<param value="' + flashvars + '" name="FlashVars">' + '	<param value="always" name="allowScriptAccess">' + '	<embed height="1" align="middle" width="1" pluginspage="http://www.macromedia.com/go/getflashplayer" ' + 'flashvars="' + flashvars + '" type="application/x-shockwave-flash" allowscriptaccess="always" quality="high" loop="false" play="true" ' + 'name="' + swfName + '" bgcolor="#ffffff" src="' + config.swf_url + '">' + '</object>'; this.swf = document[swfName] || window[swfName]; this._timeout = setTimeout(function () { SwfStore[config.namespace].log('error', 'js', 'Timeout reached, assuming ' + config.swf_url + ' failed to load and firing the onerror callback.'); if (config.onerror) { config.onerror() } }, config.timeout * 1000) }; function checkData(data) { if (typeof data === "function") { throw 'SwfStore Error: Functions cannot be used as keys or values.' } } SwfStore.prototype = { version: "1.5", ready: false, set: function (key, value) { this._checkReady(); checkData(key); checkData(value); this.swf.set(key, value) }, get: function (key) { this._checkReady(); checkData(key); return this.swf.get(key) }, getAll: function () { this._checkReady(); var data = this.swf.getAll(); if (data.__flashBugFix) { delete data.__flashBugFix } return data }, clear: function (key) { this._checkReady(); checkData(key); this.swf.clear(key) }, _checkReady: function () { if (!this.ready) { throw 'SwfStore is not yet finished initializing. Pass a config.onready callback or wait until this.ready is true before trying to use a SwfStore instance.' } }, "onload": function () { var that = this; setTimeout(function () { clearTimeout(that._timeout); that.ready = true; that.set('__flashBugFix', '1'); if (that.config.onready) { that.config.onready() } }, 0) }, onerror: function () { clearTimeout(this._timeout); if (this.config.onerror) { this.config.onerror() } } } } ());

//A function that invokes the callback function after the cookie is initialized 
function waitForMid(callback) {

	if (!cookieInitilized) {						// check if mid has a value
		var count = 0;
		$.timer(1000, function (timer) {				// wait first, run callback function later
			if (cookieInitilized || count > 11) {
				timer.stop();
				if (typeof callback == "function") {	// validate callback
					callback();
				}
			}
			count++;
		});
	}
	else {
		if (typeof callback == "function") {			// validate callback
			callback();
		}
	}
}

// Errors
function HandleException(message, ex) {
	errors += "Tracker.js - " + message;
	if (ex !== null) {
		errors += ": '" + ex + "'";
	}
	errors += "\r\n";
}

function ResetErrors() {
	errors = "";
}

// Improved version. Taken from http://stackoverflow.com/questions/901115/get-query-string-values-in-javascript/5158301#5158301
function getURLParamByName(name) {
    try {
    	var match = RegExp('[?&]' + name.toLowerCase() + '=([^&]*)').exec(window.location.search.toLowerCase());
    	if (match !== null) {
    		return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
    	}
    	return '';
    } catch (ex) {
        HandleException("getURLParamByName", ex);
    }
}

function getBrowserNameAndVersion() {

	var nVer = navigator.appVersion,
        nAgt = navigator.userAgent,
        browserName = navigator.appName,
        browserFullVersion = parseFloat(navigator.appVersion),
        nameOffset,
        verOffset,
        ix;

	if ((verOffset = nAgt.indexOf("MSIE")) !== -1) {                // In MSIE, the true version is after "MSIE" in userAgent
		browserName = "Microsoft Internet Explorer";
		browserFullVersion = nAgt.substring(verOffset + 5);
	} else if ((verOffset = nAgt.indexOf("Firefox")) !== -1) {      // In Firefox, the true version is after "Firefox"
		browserName = "Firefox";
		browserFullVersion = nAgt.substring(verOffset + 8);
	} else if ((verOffset = nAgt.indexOf("Chrome")) !== -1) {       // In Chrome, the true version is after "Chrome"
		browserName = "Chrome";
		browserFullVersion = nAgt.substring(verOffset + 7);
	} else if ((verOffset = nAgt.indexOf("Safari")) !== -1) {       // In Safari, the true version is after "Safari" or after "Version"
		browserName = "Safari";
		browserFullVersion = nAgt.substring(verOffset + 7);
		if ((verOffset = nAgt.indexOf("Version")) !== -1) {
			browserFullVersion = nAgt.substring(verOffset + 8);
		}
	} else if ((verOffset = nAgt.indexOf("Opera")) !== -1) {        // In Opera, the true version is after "Opera" or after "Version"
		browserName = "Opera";
		browserFullVersion = nAgt.substring(verOffset + 6);
		if ((verOffset = nAgt.indexOf("Version")) !== -1) {
			browserFullVersion = nAgt.substring(verOffset + 8);
		}
	} else if ((nameOffset = nAgt.lastIndexOf(' ') + 1) < (verOffset = nAgt.lastIndexOf('/'))) {    // In most other browsers, "name/version" is at the end of userAgent
		browserName = nAgt.substring(nameOffset, verOffset);
		browserFullVersion = nAgt.substring(verOffset + 1);
		if (browserName.toLowerCase() == browserName.toUpperCase()) {
			browserName = navigator.appName;
		}
	}

	// trim the fullVersion string at semicolon/space if present
	if ((ix = browserFullVersion.indexOf(";")) !== -1) {
		browserFullVersion = browserFullVersion.substring(0, ix);
	}
	if ((ix = browserFullVersion.indexOf(" ")) !== -1) {
		browserFullVersion = browserFullVersion.substring(0, ix);
	}

	return [browserName, browserFullVersion];

}

function GetOSName() {
	var osName = "Unknown OS";
	try {
		if (navigator.appVersion.indexOf("Win") !== -1) {
			osName = "Windows";
		} else if (navigator.appVersion.indexOf("Mac") !== -1) {
			osName = "MacOS";
		} else if (navigator.appVersion.indexOf("X11") !== -1) {
			osName = "UNIX";
		} else if (navigator.appVersion.indexOf("Linux") !== -1) {
			osName = "Linux";
		} else {
			HandleException("GetOSName - Failed to recognize OSName. navigator.appVersion='" + navigator.appVersion + "'", null);
		}
	} catch (ex) {
		HandleException("GetOSName", ex);
	}
	return osName;
}

function GetOSVersion(osName) {
	var osVersion = "",
        BrowserData;
	try {
		BrowserData = navigator.userAgent.split(/\s*[;)(]\s*/);
		if (BrowserData.length > 0) {
			for (var i = 0; i < BrowserData.length; i++) {
				var data = BrowserData[i];
				if (data.match(osName + " ")) {
					osVersion = data.split(" ").pop();
					break;
				}
			}
			if (osVersion === "") {
				HandleException("GetOSVersion - Failed to recognize OSVersion. BrowserData='" + BrowserData + "'", null);
			}
		}
		if (osVersion === "") {
			HandleException("GetOSVersion - Failed to recognize OSVersion. navigator.userAgent='" + navigator.userAgent + "'", null);
		}
	} catch (ex) {
		HandleException("GetOSVersion", ex);
	}
	return osVersion;
}

// get .net version (works for IE 6 to 8 only)
function GetDotNetVersion() {
	var dotNetVersion = "";
	try {
		var a = navigator.userAgent.match(/\.NET CLR [0-9.]+/g);
		if (a !== null) {
			var major = 0,
			    minor = 0,
			    build = 0,
			    parts,
			    dotnet;

			dotNetVersion = "0.0.0";
			for (var i = 0; i < a.length; i++) {
				dotnet = a[i].split(" ")[2];
				parts = dotnet.split(".");
				if (parts[0] > major) {
					major = parts[0];
					minor = parts[1];
					build = parts[2];
					dotNetVersion = dotnet;
				} else if (parts[0] === major && parts[1] > minor) {
					minor = parts[1];
					build = parts[2];
					dotNetVersion = dotnet;
				}
			}
		}
	} catch (ex) {
		HandleException("GetDotNetVersion", ex);
	}
	return dotNetVersion;
}

function GetScreenResolution() {
	var screenW = 640,
        screenH = 480;
	try {
		if (parseInt(navigator.appVersion) > 3) {
			screenW = screen.width;
			screenH = screen.height;
		} else if (navigator.appName === "Netscape" && parseInt(navigator.appVersion) === 3 && navigator.javaEnabled()) {
			var jToolkit = java.awt.Toolkit.getDefaultToolkit(),
			    jScreenSize = jToolkit.getScreenSize();
			screenW = jScreenSize.width;
			screenH = jScreenSize.height;
		}
	} catch (ex) {
		HandleException("GetScreenResolution", ex);
	}

	var screenResolution = screenW + "x" + screenH;
	return screenResolution;
}

function GetBrowserCookie(name) {
	var nameEQ = name + "=",
    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 SetBrowserCookie(name, value) {
	// 30/12/9999 23:59:59 (with client GMT)
	var date = new Date(9999, 11, 30, 23, 59, 59, 999);
	var expires = "; expires=" + date.toGMTString();
	document.cookie = name + "=" + value + expires + "; path=/";
}

function GetLocalStorage(name) {
	if (window.localStorage) {
		return localStorage.getItem(name);
	}
}

function SetLocalStorage(name, value) {
	if (window.localStorage) {
		localStorage.setItem(name, value);
	}
}

function ReportErrors() {
	if (errors !== "") {
		try {
			$.ajax({
				url: trackerJSDomain + "Home/ReportErrors",
				dataType: 'json',
				crossDomain: true,
				data: "errors=" + errors,
				cache: false,
				success: ResetErrors(),
				error: ResetErrors()
			});
		}
		catch (ex) {
			HandleException("ReportErrors", ex);
			// write to browser console?
		}
	}
}

function invokeCookieReady(mid) {
	savedMid = mid;
	if (typeof cookieReadyCallback == "function") {
		cookieReadyCallback(mid);
	}
	cookieInitilized = true;
}

function SendVisit(machineId, swfStore) {

	var osName = GetOSName(),
		osVersion = GetOSVersion(osName),
		dotNetVersion = GetDotNetVersion(),
		browserNameAndVersion = getBrowserNameAndVersion(),
		browserName = browserNameAndVersion[0],
		browserVersion = browserNameAndVersion[1],
		screenResolution = GetScreenResolution(),
		referrerUrl = getURLParamByName("referrerUrl"),
		visitedURL = escape(getURLParamByName("location")),
		btag = getURLParamByName("btag"),
		bfpTag = getURLParamByName("bfptag"),
		userIdParam = "",
		parameters = "";

	if (visitedURL === null || visitedURL.length === 0) {
		visitedURL = escape(location.href);
		if (referrerUrl === null || referrerUrl.length === 0) {
			referrerUrl = document.referrer;
		}
	}

	//Check if user id exists as variable
	if (typeof userId !== 'undefined') {
		userIdParam = userId;
	}

	parameters =
		"machineId=" + machineId +
		"&osName=" + osName +
		"&osVersion=" + osVersion.replace("/", " ") +
		"&dotNetVersion=" + dotNetVersion +
		"&BrowserName=" + browserName +
		"&BrowserVersion=" + browserVersion +
		"&screenResolution=" + screenResolution +
		"&referrerUrl=" + referrerUrl +
		"&visitedUrl=" + visitedURL +
		"&userId=" + userIdParam +
		"&btag=" + btag +
		"&bfpTag=" + bfpTag +
		"&errors=" + errors;

	$.ajax({
		url: trackerJSDomain + "Home/Visit",
		dataType: 'json',
		data: parameters,
		crossDomain: true,
		cache: false,
		beforeSend: ResetErrors(), // reset errors since they are now in the QueryString.
		success: function (data) {
			if (swfStore !== null) {
				try {
					swfStore.set(cookieKey, data);
				} catch (ex) {
					HandleException("SendVisit- Error setting flash cookie. Parameters: '" + parameters.replace(/&/g, " ") + "'. Exception: ", ex);
				}
			}
			try {
				SetLocalStorage(cookieKey, data);
			} catch (ex) {
				HandleException("SendVisit- Error setting localStorage. Parameters: '" + parameters.replace(/&/g, " ") + "'. Exception: ", ex);
			}
			try {
				SetBrowserCookie(cookieKey, data);
			} catch (ex) {
				HandleException("SendVisit- Error setting browser cookie. Parameters: '" + parameters.replace(/&/g, " ") + "'. Exception: ", ex);
			}

			invokeCookieReady(data);

			ReportErrors();
		},
		error: function (jqXHR, textStatus, errorThrown) {
			invokeCookieReady(null);
			HandleException("SendVisit- Error sending visit. Parameters: '" + parameters.replace(/&/g, " ") + "'. jqXHR: '" + jqXHR + "'. textStatus: '" + textStatus + "'. Exception: ", errorThrown);
			ReportErrors();
		}
	});
}

function OnFlashReady(swfStore) {

	ResetErrors();

	var flashMachineId = "",
		localStorageMachineId = "",
	    browserMachineId = "",
	    machineId = "";

	if (swfStore !== null) {
		try {
			flashMachineId = swfStore.get(cookieKey);
		} catch (ex) {
			HandleException("Error getting Flash cookie", ex);
		}
	}

	try {
		browserMachineId = GetBrowserCookie(cookieKey);
	} catch (ex) {
		HandleException("Error getting browser cookie", ex);
	}

	try {
		localStorageMachineId = GetLocalStorage(cookieKey);
	} catch (ex) {
		HandleException("Error getting localStorage", ex);
	}

	if (flashMachineId !== null && flashMachineId !== "") {
		machineId = flashMachineId;
	} else if (localStorageMachineId !== null && localStorageMachineId !== "") {
		machineId = localStorageMachineId;
	} else if (browserMachineId !== null && browserMachineId !== "") {
		machineId = browserMachineId;
	}

	SendVisit(machineId, swfStore);
}

function initArrayIndexOf() {
	if (!Array.prototype.indexOf) {
		Array.prototype.indexOf = function (obj, start) {
			for (var i = (start || 0); i < this.length; i++) {
				if (this[i] == obj) {
					return i;
				}
			}
			return -1;
		};
	}
}

initArrayIndexOf(); // always check for indexOf prototype - needed for most browser detection funcs
// on document ready
$(function () {
	// Check for Flash 9+ needed for LSO (Flash Cookie)
	if (FlashDetect.majorAtLeast(9)) {
		swfStore = new SwfStore({

			namespace: 'CookieMonster', // this must match all other instances that want to share cookies
			swf_url: 'http://registrationams.tradenetworks.com/cookiemonster/Flash/storage.swf', // to work cross-domain, use the same absolute url on both pages (meaning http://site.com/path/to/store.swf not just /path/to/store.swf)
			debug: false, // messages go to the console if available, otherwise the bottom of the page

			onready: function () { OnFlashReady(swfStore); },

			onerror: function () {
				HandleException("Error initializing flash cookie", null);
				ReportErrors();
				OnFlashReady(null);
			}
		});
	} else {
		if (!FlashDetect.installed) {
			HandleException("Flash is not installed ", null);
		} else {
			HandleException("Flash version 9+ required. Current version: " + FlashDetect.major, null);
		}
		ReportErrors();
		OnFlashReady(null);
	}

});
