﻿(function () {
	var url = 'http://dev.admin-track.merchantbilling.com/analytics/Statsv2.php';
	var permCookieName = 'mbstats_perm';
	var tempCookieName = 'mbstats_temp';
	var getGuid = function () {
		return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
			var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
			return v.toString(16);
		}).replace(/-/gi, '');
	};	
	/** MB api namespace
	* @namespace
	* @name MB
	*/
	window.MB = {
		/** Upload data to the server using a HTTP GET request.
		* @param {object} data The data object to send to MB tracking server.		
		* @name track
		* @methodOf MB 
		*/
		track: function (data) {
			try {
				var Cookie = jaaulde.utils.cookies;
				if (typeof data === 'undefined')
					data = null;
				var json = {
					Data: data,
					DateTime: new Date().getTime(),
					Hash: location.hash,
					Referrer: document.referrer
				};
				if (Cookie.test()) {
					var perm = Cookie.get(permCookieName);
					var temp = Cookie.get(tempCookieName);
					if (perm === null) {
						perm = getGuid();
						var now = new Date();
						now.setTime(now.getTime() + (24 * 60 * 60 * 1000));
						Cookie.set(permCookieName, perm, { path: '/', expiresAt: now }); // 24 h
					}
					if (temp === null) {
						temp = getGuid();
						Cookie.set(tempCookieName, temp, { path: '/' }); // session
					}
					json.TempGuid = temp;
					json.PermGuid = perm;
				} else {
					return false;
				}
				if (typeof FlashDetect === 'undefined' || FlashDetect === null)
					json.Flash = null;
				else
					json.Flash = { Raw: FlashDetect.raw, Major: FlashDetect.major }
				var img = new Image(1, 1);
				img.src = url + '?data=' + Base64.encode(JSON.stringify(json));
				return true;
			} catch (ex) {
				if (typeof console !== 'undefined' && console !== null && typeof console.log === 'function')
					console.log(ex);
				return false;
			}
		}
	};
} ());

/**
*
*  Base64 encode / decode
*  http://www.webtoolkit.info/
*
**/
var Base64 = {

	// private property
	_keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

	// public method for encoding
	encode: function (input) {
		var output = "";
		var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
		var i = 0;

		input = Base64._utf8_encode(input);

		while (i < input.length) {

			chr1 = input.charCodeAt(i++);
			chr2 = input.charCodeAt(i++);
			chr3 = input.charCodeAt(i++);

			enc1 = chr1 >> 2;
			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
			enc4 = chr3 & 63;

			if (isNaN(chr2)) {
				enc3 = enc4 = 64;
			} else if (isNaN(chr3)) {
				enc4 = 64;
			}

			output = output +
			this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
			this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);

		}

		return output;
	},

	// public method for decoding
	decode: function (input) {
		var output = "";
		var chr1, chr2, chr3;
		var enc1, enc2, enc3, enc4;
		var i = 0;

		input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

		while (i < input.length) {

			enc1 = this._keyStr.indexOf(input.charAt(i++));
			enc2 = this._keyStr.indexOf(input.charAt(i++));
			enc3 = this._keyStr.indexOf(input.charAt(i++));
			enc4 = this._keyStr.indexOf(input.charAt(i++));

			chr1 = (enc1 << 2) | (enc2 >> 4);
			chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
			chr3 = ((enc3 & 3) << 6) | enc4;

			output = output + String.fromCharCode(chr1);

			if (enc3 != 64) {
				output = output + String.fromCharCode(chr2);
			}
			if (enc4 != 64) {
				output = output + String.fromCharCode(chr3);
			}

		}

		output = Base64._utf8_decode(output);

		return output;

	},

	// private method for UTF-8 encoding
	_utf8_encode: function (string) {
		string = string.replace(/\r\n/g, "\n");
		var utftext = "";

		for (var n = 0; n < string.length; n++) {

			var c = string.charCodeAt(n);

			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if ((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}

		}

		return utftext;
	},

	// private method for UTF-8 decoding
	_utf8_decode: function (utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;

		while (i < utftext.length) {

			c = utftext.charCodeAt(i);

			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			}
			else if ((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i + 1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i + 1);
				c3 = utftext.charCodeAt(i + 2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}

		}

		return string;
	}
};

/*
Copyright (c) Copyright (c) 2007, Carl S. Yestrau All rights reserved.
Code licensed under the BSD License: http://www.featureblend.com/license.txt
Version: 1.0.4
*/
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);
			}
		}
	];
	/**
	* Extract the ActiveX version of the plugin.
	* 
	* @param {Object} The flash ActiveX object.
	* @type String
	*/
	var getActiveXVersion = function (activeXObj) {
		var version = -1;
		try {
			version = activeXObj.GetVariable("$version");
		} catch (err) { }
		return version;
	};
	/**
	* Try and retrieve an ActiveX object having a specified name.
	* 
	* @param {String} name The ActiveX object name lookup.
	* @return One of ActiveX object or a simple object having an attribute of activeXError with a value of true.
	* @type Object
	*/
	var getActiveXObject = function (name) {
		var obj = -1;
		try {
			obj = new ActiveXObject(name);
		} catch (err) {
			obj = { activeXError: true };
		}
		return obj;
	};
	/**
	* Parse an ActiveX $version string into an object.
	* 
	* @param {String} str The ActiveX Object GetVariable($version) return value. 
	* @return An object having raw, major, minor, revision and revisionStr attributes.
	* @type Object
	*/
	var parseActiveXVersion = function (str) {
		var versionArray = str.split(","); //replace with regex
		return {
			"raw": str,
			"major": parseInt(versionArray[0].split(" ")[1], 10),
			"minor": parseInt(versionArray[1], 10),
			"revision": parseInt(versionArray[2], 10),
			"revisionStr": versionArray[2]
		};
	};
	/**
	* Parse a standard enabledPlugin.description into an object.
	* 
	* @param {String} str The enabledPlugin.description value.
	* @return An object having raw, major, minor, revision and revisionStr attributes.
	* @type Object
	*/
	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)
		};
	};
	/**
	* Parse the plugin revision string into an integer.
	* 
	* @param {String} The revision in string format.
	* @type Number
	*/
	var parseRevisionStrToInt = function (str) {
		return parseInt(str.replace(/[a-zA-Z]/g, ""), 10) || self.revision;
	};
	/**
	* Is the major version greater than or equal to a specified version.
	* 
	* @param {Number} version The minimum required major version.
	* @type Boolean
	*/
	self.majorAtLeast = function (version) {
		return self.major >= version;
	};
	/**
	* Is the minor version greater than or equal to a specified version.
	* 
	* @param {Number} version The minimum required minor version.
	* @type Boolean
	*/
	self.minorAtLeast = function (version) {
		return self.minor >= version;
	};
	/**
	* Is the revision version greater than or equal to a specified version.
	* 
	* @param {Number} version The minimum required revision version.
	* @type Boolean
	*/
	self.revisionAtLeast = function (version) {
		return self.revision >= version;
	};
	/**
	* Is the version greater than or equal to a specified major, minor and revision.
	* 
	* @param {Number} major The minimum required major version.
	* @param {Number} (Optional) minor The minimum required minor version.
	* @param {Number} (Optional) revision The minimum required revision version.
	* @type Boolean
	*/
	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;
			}
		}
	};
	/**
	* Constructor, sets raw, major, minor, revisionStr, revision and installed public properties.
	*/
	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";

/**
* Copyright (c) 2005 - 2010, James Auldridge
* All rights reserved.
*
* Licensed under the BSD, MIT, and GPL (your choice!) Licenses:
*  http://code.google.com/p/cookies/wiki/License
*
*/
var jaaulde = window.jaaulde || {};
jaaulde.utils = jaaulde.utils || {};
jaaulde.utils.cookies = (function () {
	var resolveOptions, assembleOptionsString, parseCookies, constructor, defaultOptions = {
		expiresAt: null,
		path: '/',
		domain: null,
		secure: false
	};
	/**
	* resolveOptions - receive an options object and ensure all options are present and valid, replacing with defaults where necessary
	*
	* @access private
	* @static
	* @parameter Object options - optional options to start with
	* @return Object complete and valid options object
	*/
	resolveOptions = function (options) {
		var returnValue, expireDate;

		if (typeof options !== 'object' || options === null) {
			returnValue = defaultOptions;
		}
		else {
			returnValue = {
				expiresAt: defaultOptions.expiresAt,
				path: defaultOptions.path,
				domain: defaultOptions.domain,
				secure: defaultOptions.secure
			};

			if (typeof options.expiresAt === 'object' && options.expiresAt instanceof Date) {
				returnValue.expiresAt = options.expiresAt;
			}
			else if (typeof options.hoursToLive === 'number' && options.hoursToLive !== 0) {
				expireDate = new Date();
				expireDate.setTime(expireDate.getTime() + (options.hoursToLive * 60 * 60 * 1000));
				returnValue.expiresAt = expireDate;
			}

			if (typeof options.path === 'string' && options.path !== '') {
				returnValue.path = options.path;
			}

			if (typeof options.domain === 'string' && options.domain !== '') {
				returnValue.domain = options.domain;
			}

			if (options.secure === true) {
				returnValue.secure = options.secure;
			}
		}

		return returnValue;
	};
	/**
	* assembleOptionsString - analyze options and assemble appropriate string for setting a cookie with those options
	*
	* @access private
	* @static
	* @parameter options OBJECT - optional options to start with
	* @return STRING - complete and valid cookie setting options
	*/
	assembleOptionsString = function (options) {
		options = resolveOptions(options);

		return (
			(typeof options.expiresAt === 'object' && options.expiresAt instanceof Date ? '; expires=' + options.expiresAt.toGMTString() : '') +
			'; path=' + options.path +
			(typeof options.domain === 'string' ? '; domain=' + options.domain : '') +
			(options.secure === true ? '; secure' : '')
		);
	};
	/**
	* parseCookies - retrieve document.cookie string and break it into a hash with values decoded and unserialized
	*
	* @access private
	* @static
	* @return OBJECT - hash of cookies from document.cookie
	*/
	parseCookies = function () {
		var cookies = {}, i, pair, name, value, separated = document.cookie.split(';'), unparsedValue;
		for (i = 0; i < separated.length; i = i + 1) {
			pair = separated[i].split('=');
			name = pair[0].replace(/^\s*/, '').replace(/\s*$/, '');

			try {
				value = decodeURIComponent(pair[1]);
			}
			catch (e1) {
				value = pair[1];
			}

			if (typeof JSON === 'object' && JSON !== null && typeof JSON.parse === 'function') {
				try {
					unparsedValue = value;
					value = JSON.parse(value);
				}
				catch (e2) {
					value = unparsedValue;
				}
			}

			cookies[name] = value;
		}
		return cookies;
	};

	constructor = function () { };

	/**
	* get - get one, several, or all cookies
	*
	* @access public
	* @paramater Mixed cookieName - String:name of single cookie; Array:list of multiple cookie names; Void (no param):if you want all cookies
	* @return Mixed - Value of cookie as set; Null:if only one cookie is requested and is not found; Object:hash of multiple or all cookies (if multiple or all requested);
	*/
	constructor.prototype.get = function (cookieName) {
		var returnValue, item, cookies = parseCookies();

		if (typeof cookieName === 'string') {
			returnValue = (typeof cookies[cookieName] !== 'undefined') ? cookies[cookieName] : null;
		}
		else if (typeof cookieName === 'object' && cookieName !== null) {
			returnValue = {};
			for (item in cookieName) {
				if (typeof cookies[cookieName[item]] !== 'undefined') {
					returnValue[cookieName[item]] = cookies[cookieName[item]];
				}
				else {
					returnValue[cookieName[item]] = null;
				}
			}
		}
		else {
			returnValue = cookies;
		}

		return returnValue;
	};
	/**
	* filter - get array of cookies whose names match the provided RegExp
	*
	* @access public
	* @paramater Object RegExp - The regular expression to match against cookie names
	* @return Mixed - Object:hash of cookies whose names match the RegExp
	*/
	constructor.prototype.filter = function (cookieNameRegExp) {
		var cookieName, returnValue = {}, cookies = parseCookies();

		if (typeof cookieNameRegExp === 'string') {
			cookieNameRegExp = new RegExp(cookieNameRegExp);
		}

		for (cookieName in cookies) {
			if (cookieName.match(cookieNameRegExp)) {
				returnValue[cookieName] = cookies[cookieName];
			}
		}

		return returnValue;
	};
	/**
	* set - set or delete a cookie with desired options
	*
	* @access public
	* @paramater String cookieName - name of cookie to set
	* @paramater Mixed value - Any JS value. If not a string, will be JSON encoded; NULL to delete
	* @paramater Object options - optional list of cookie options to specify
	* @return void
	*/
	constructor.prototype.set = function (cookieName, value, options) {
		if (typeof options !== 'object' || options === null) {
			options = {};
		}

		if (typeof value === 'undefined' || value === null) {
			value = '';
			options.hoursToLive = -8760;
		}

		else if (typeof value !== 'string') {
			if (typeof JSON === 'object' && JSON !== null && typeof JSON.stringify === 'function') {
				value = JSON.stringify(value);
			}
			else {
				throw new Error('cookies.set() received non-string value and could not serialize.');
			}
		}


		var optionsString = assembleOptionsString(options);

		document.cookie = cookieName + '=' + encodeURIComponent(value) + optionsString;
	};
	/**
	* del - delete a cookie (domain and path options must match those with which the cookie was set; this is really an alias for set() with parameters simplified for this use)
	*
	* @access public
	* @paramater MIxed cookieName - String name of cookie to delete, or Bool true to delete all
	* @paramater Object options - optional list of cookie options to specify ( path, domain )
	* @return void
	*/
	constructor.prototype.del = function (cookieName, options) {
		var allCookies = {}, name;

		if (typeof options !== 'object' || options === null) {
			options = {};
		}

		if (typeof cookieName === 'boolean' && cookieName === true) {
			allCookies = this.get();
		}
		else if (typeof cookieName === 'string') {
			allCookies[cookieName] = true;
		}

		for (name in allCookies) {
			if (typeof name === 'string' && name !== '') {
				this.set(name, null, options);
			}
		}
	};
	/**
	* test - test whether the browser is accepting cookies
	*
	* @access public
	* @return Boolean
	*/
	constructor.prototype.test = function () {
		var returnValue = false, testName = 'cT', testValue = 'data';

		this.set(testName, testValue);

		if (this.get(testName) === testValue) {
			this.del(testName);
			returnValue = true;
		}

		return returnValue;
	};
	/**
	* setOptions - set default options for calls to cookie methods
	*
	* @access public
	* @param Object options - list of cookie options to specify
	* @return void
	*/
	constructor.prototype.setOptions = function (options) {
		if (typeof options !== 'object') {
			options = null;
		}

		defaultOptions = resolveOptions(options);
	};

	return new constructor();
})();

(function () {
	if (window.jQuery) {
		(function ($) {
			$.cookies = jaaulde.utils.cookies;

			var extensions = {
				/**
				* $( 'selector' ).cookify - set the value of an input field, or the innerHTML of an element, to a cookie by the name or id of the field or element
				*                           (field or element MUST have name or id attribute)
				*
				* @access public
				* @param options OBJECT - list of cookie options to specify
				* @return jQuery
				*/
				cookify: function (options) {
					return this.each(function () {
						var i, nameAttrs = ['name', 'id'], name, $this = $(this), value;

						for (i in nameAttrs) {
							if (!isNaN(i)) {
								name = $this.attr(nameAttrs[i]);
								if (typeof name === 'string' && name !== '') {
									if ($this.is(':checkbox, :radio')) {
										if ($this.attr('checked')) {
											value = $this.val();
										}
									}
									else if ($this.is(':input')) {
										value = $this.val();
									}
									else {
										value = $this.html();
									}

									if (typeof value !== 'string' || value === '') {
										value = null;
									}

									$.cookies.set(name, value, options);

									break;
								}
							}
						}
					});
				},
				/**
				* $( 'selector' ).cookieFill - set the value of an input field or the innerHTML of an element from a cookie by the name or id of the field or element
				*
				* @access public
				* @return jQuery
				*/
				cookieFill: function () {
					return this.each(function () {
						var n, getN, nameAttrs = ['name', 'id'], name, $this = $(this), value;

						getN = function () {
							n = nameAttrs.pop();
							return !!n;
						};

						while (getN()) {
							name = $this.attr(n);
							if (typeof name === 'string' && name !== '') {
								value = $.cookies.get(name);
								if (value !== null) {
									if ($this.is(':checkbox, :radio')) {
										if ($this.val() === value) {
											$this.attr('checked', 'checked');
										}
										else {
											$this.removeAttr('checked');
										}
									}
									else if ($this.is(':input')) {
										$this.val(value);
									}
									else {
										$this.html(value);
									}
								}

								break;
							}
						}
					});
				},
				/**
				* $( 'selector' ).cookieBind - call cookie fill on matching elements, and bind their change events to cookify()
				*
				* @access public
				* @param options OBJECT - list of cookie options to specify
				* @return jQuery
				*/
				cookieBind: function (options) {
					return this.each(function () {
						var $this = $(this);
						$this.cookieFill().change(function () {
							$this.cookify(options);
						});
					});
				}
			};

			$.each(extensions, function (i) {
				$.fn[i] = this;
			});

		})(window.jQuery);
	}
})();
