/**
 * @class UserAgent
 * @constructor
 * @description Provides accurate user agent detection methods.
 * @return {Object} UserAgent
 */
function UserAgent()
{
	// Private
	var self = this,
		userAgent = null,
		version = null,
		platform = null,
		detectors = [];

	// Public
	this.getUserAgent = getUserAgent;
	this.getVersion = getVersion;
	this.getPlatform = getPlatform;

	/**
	 * Run All Detectors
	 */
	function runDetectors()
	{
		// Get the user agent and its version
		for (var i = 0; i < detectors.length; i++)
		{
			if (detectors[i]() == true)
			{
				break;
			}
		}

		// Get the platform
		detectPlatform();
	}


	/**
	 * Internet Explorer detector
	 * @static
	 */
	detectors.push(function()
	{
		if (
			document.body != undefined &&
			document.body.currentStyle != undefined &&
			document.body.currentStyle.hasLayout != undefined
		)
		{
			userAgent = UserAgent.UA_MSIE;
			version = String(navigator.appVersion.match(/MSIE [0-9\.]+/)).substring(5);

			return true;
		}

		return false;
	});

	/**
	 * Firefox detector
	 * @static
	 */
	detectors.push(function()
	{
		if (
			navigator.mimeTypes != undefined &&
			navigator.mimeTypes.item != undefined &&
			navigator.mimeTypes.item(0).description == "Mozilla Default Plug-in"
		)
		{
			userAgent = UserAgent.UA_FIREFOX;
			version = String(navigator.userAgent.match(/Firefox\/[0-9\.]+/)).substring(8);

			return true;
		}

		return false;
	});

	/**
	 * Opera detector
	 * @static
	 */
	detectors.push(function()
	{
		if (window.opera != undefined)
		{
			userAgent = UserAgent.UA_OPERA;
			version = navigator.appVersion.match(/^[0-9\.]+/);

			return true;
		}

		return false;
	});

	/**
	 * Safari detector
	 * @static
	 */
	detectors.push(function()
	{
		return false;
	});

	/**
	 * Chrome detector
	 * @static
	 */
	detectors.push(function()
	{
		if (
			navigator.userAgent.match(/chrome/i) != null &&
			navigator.vendor.match(/google/i) != null
		)
		{
			userAgent = UserAgent.UA_CHROME;
			version = String(navigator.userAgent.match(/Chrome\/[0-9\.]+/)).substring(7);

			return true;
		}

		return false;
	});

	/**
	 * Detect the platform (operating system)
	 */
	function detectPlatform()
	{
		switch (navigator.platform.toLowerCase())
		{
			case "win32":
				platform = UserAgent.PF_WINDOWS;
				break;
			case "mac":
				platform = UserAgent.PF_MAC;
				break;
			case "linux":
				platform = UserAgent.PF_LINUX;
				break;
		}
	}

	/**
	 * Get useragent
	 * @public
	 * @return {String} userAgent
	 */
	function getUserAgent()
	{
		return userAgent;
	}

	/**
	 * Get useragent version
	 * @public
	 * @return {String} version
	 */
	function getVersion()
	{
		return version;
	}

	/**
	 * Get useragent platform
	 * @public
	 * @return {String} platform
	 */
	function getPlatform()
	{
		return platform;
	}

	// Singleton
	runDetectors();

	return (UserAgent.instance != undefined ? UserAgent.instance : (UserAgent.instance = this));
}

// Constants
/** @constant */
UserAgent.UA_UNKNOWN = "unknown";
/** @constant */
UserAgent.UA_MSIE = "msie";
/** @constant */
UserAgent.UA_FIREFOX = "firefox";
/** @constant */
UserAgent.UA_OPERA = "opera";
/** @constant */
UserAgent.UA_SAFARI = "safari";
/** @constant */
UserAgent.UA_CHROME = "chrome";
/** @constant */
UserAgent.PF_WINDOWS = "windows";
/** @constant */
UserAgent.PF_MAC = "mac";
/** @constant */
UserAgent.PF_LINUX = "linux";