ClientBrowser = function(userAgent, appVersion)
{
	if (!(this instanceof ClientBrowser)) { return new ClientBrowser(userAgent); }
	if (!userAgent || 0 == userAgent.length) { userAgent = navigator.userAgent; }
	if (!appVersion || 0 == appVersion.length) { appVersion = navigator.appVersion; }
	
	this.userAgent = userAgent;
	this.appVersion = appVersion;
	
	this.major = parseInt(appVersion);
	this.minor = parseFloat(appVersion);
	
	// Script engine:
	this.scriptEngineVersion = ("function" === typeof(ScriptEngineMajorVersion) ? ScriptEngineMajorVersion() : 0);
	
	// Screen:
	this.screenWidth = window.screen.width;
	this.screenHeight = window.screen.height;
	this.fontSmoothing = window.screen.fontSmoothingEnabled;
	
	if ("Netscape" !== navigator.appName)
	{
		this.colorDepth = window.screen.colorDepth;
	}
	else
	{
		this.colorDepth = window.screen.pixelDepth;
	}
	
	userAgent = userAgent.toLowerCase();
	
	// Browser
	this.isNAV = (-1 != userAgent.indexOf("mozilla"))
		&& (-1 == userAgent.indexOf("spoofer"))
		&& (-1 == userAgent.indexOf("compatible"))
		&& (-1 == userAgent.indexOf("opera"))
		&& (-1 == userAgent.indexOf("webtv"));
	
	this.isIE = (-1 != userAgent.indexOf("msie"));
	this.isFirefox = (-1 != userAgent.indexOf("firefox"));
	this.isAOL = (-1 != userAgent.indexOf("aol"));
	this.isOpera = (-1 != userAgent.indexOf("opera"));
	this.isWebTV = (-1 != userAgent.indexOf("webtv"));
	
	// Platform
	this.isWindows = (-1 != userAgent.indexOf("win"))
		|| (-1 != userAgent.indexOf("16bit"));
	
	this.isWin16 = (-1 != userAgent.indexOf("win16"))
		|| (-1 != userAgent.indexOf("16bit"))
		|| (-1 != userAgent.indexOf("windows 3.1"))
		|| (-1 != userAgent.indexOf("windows 16-bit"));
	
	this.isWin31 = (-1 != userAgent.indexOf("windows 3.1"))
		|| (-1 != userAgent.indexOf("win16"))
		|| (-1 != userAgent.indexOf("windows 16-bit"));
	
	this.isWin95 = (-1 != userAgent.indexOf("win95"))
		|| (-1 != userAgent.indexOf("windows 95"));
	
	this.isWin98 = (-1 != userAgent.indexOf("win98"))
		|| (-1 != userAgent.indexOf("windows 98"));
	
	this.isWinNT = (-1 != userAgent.indexOf("winnt"))
		|| (-1 != userAgent.indexOf("windows nt"));
	
	this.isWin2K = this.isWinNT && (-1 != userAgent.indexOf("windows nt 5.0"));
	this.isWinXP = this.isWinNT && (-1 != userAgent.indexOf("windows nt 5.1"));
	this.isWin2003 = this.isWinNT && (-1 != userAgent.indexOf("windows nt 5.2"));
	this.isWinVista = this.isWinNT && (-1 != userAgent.indexOf("windows nt 6.0"));
	this.isWin7 = this.isWinNT && (-1 != userAgent.indexOf("windows nt 6.1"));
	
	this.isWin32 = this.isWin95 || this.isWin98 || this.isWinNT || this.isWin2K || this.isWinXP || this.isWin2003
		|| (4 <= this.major && "Win32" == navigator.platform)
		|| (-1 != userAgent.indexOf("win32"))
		|| (-1 != userAgent.indexOf("32bit"));
	
	this.isOS2 = (-1 != userAgent.indexOf("os/2"))
		|| (-1 != appVersion.indexOf("OS/2"))
		|| (-1 != userAgent.indexOf("ibm-webexplorer"));
	
	this.isMac = (-1 != userAgent.indexOf("mac"));
	this.isMac68K = this.isMac && ((-1 != userAgent.indexOf("68k")) || (-1 != userAgent.indexOf("68000")));
	this.isMacPPC = this.isMac && ((-1 != userAgent.indexOf("ppc")) || (-1 != userAgent.indexOf("powerpc")));
	
	this.isSun = (-1 != userAgent.indexOf("sunos"));
	this.isSun4 = this.isSun && (-1 != userAgent.indexOf("sunos 4"));
	this.isSun5 = this.isSun && (-1 != userAgent.indexOf("sunos 5"));
	this.isSuni86 = this.isSun && (-1 != userAgent.indexOf("i86"));
	
	this.isIRIX = (-1 != userAgent.indexOf("irix"));
	this.isIRIX5 = this.isIRIX && (-1 != userAgent.indexOf("irix 5"));
	this.isIRIX6 = this.isIRIX && (-1 != userAgent.indexOf("irix 6"));
	
	this.isHPUX = (-1 != userAgent.indexOf("hp-ux"));
	this.isHPUX9 = this.isHPUX && (-1 != userAgent.indexOf("09."));
	this.isHPUX10 = this.isHPUX && (-1 != userAgent.indexOf("10."));
	
	this.isAIX = (-1 != userAgent.indexOf("aix"));
	this.isAIX1 = this.isAIX && (-1 != userAgent.indexOf("aix 1"));
	this.isAIX2 = this.isAIX && (-1 != userAgent.indexOf("aix 2"));
	this.isAIX3 = this.isAIX && (-1 != userAgent.indexOf("aix 3"));
	this.isAIX4 = this.isAIX && (-1 != userAgent.indexOf("aix 4"));
	
	this.isLinux = (-1 != userAgent.indexOf("inux"));
	this.isSCO = (-1 != userAgent.indexOf("sco"))
		|| (-1 != userAgent.indexOf("unix_sv"));
	
	this.isUNIXWare = (-1 != userAgent.indexOf("unix_system_v"));
	this.isMPRAS = (-1 != userAgent.indexOf("ncr"));
	this.isReliant = (-1 != userAgent.indexOf("reliantunix"));
	
	this.isDEC = (-1 != userAgent.indexOf("dec"))
		|| (-1 != userAgent.indexOf("osf1"))
		|| (-1 != userAgent.indexOf("dec_alpha"))
		|| (-1 != userAgent.indexOf("alphaserver"))
		|| (-1 != userAgent.indexOf("ultrix"))
		|| (-1 != userAgent.indexOf("alphastation"));
	
	this.isSINIX = (-1 != userAgent.indexOf("sinix"));
	this.isFreeBSD = (-1 != userAgent.indexOf("freebsd"));
	this.isBSD = (-1 != userAgent.indexOf("bsd"));
	
	this.isUNIX = (-1 != userAgent.indexOf("x11"))
		|| this.isSun || this.isIRIX || this.isHPUX || this.isSCO
		|| this.isUNIXWare || this.isMPRAS || this.isReliant
		|| this.isDEC || this.isSINIX || this.isAIX || this.isLinux
		|| this.isBSD || this.isFreeBSD;
	
	this.isVMS = (-1 != userAgent.indexOf("vax")) 
		|| (-1 != userAgent.indexOf("openvms"));
	
	return this;
};

ClientBrowser.prototype =
{
	get_name: function()
	{
		if (this.isIE)
		{
			var version = parseFloat(this.appVersion);
			
			var reVersion = /MSIE (\d+(\.\d+)?)/i;
			var match = reVersion.exec(this.userAgent);
			if (null != match)
			{
				version = parseFloat(match[1]);
			}
			if (6 <= version && /SV1/i.test(this.userAgent))
			{
				version += " SP2";
			}
			
			return "Internet Explorer " + version;
		}
		
		if (this.isFirefox)
		{
			var version = parseFloat(this.appVersion);
			
			var reVersion = /Firefox\/(\d+(\.\d+(\.\d+)?)?)/i;
			var match = reVersion.exec(this.userAgent);
			if (null != match) { version = match[1]; }
			
			return "Firefox " + version;
		}
		
		if (this.isNAV) 
		{
			return "Netscape Navigator " + parseFloat(this.appVersion);
		}
		
		if (this.isAOL) { return "AOL " + parseFloat(this.appVersion); }
		if (this.isOpera) { return "Opera"; }
		if (this.isWebTV) { return "WebTV"; }
		return "Unknown";
	},
	
	get_platform: function()
	{
		if (this.isWindows)
		{
			if (this.isWin7) { return "Windows 7"; }
			if (this.isWinVista) { return "Windows Vista"; }
			if (this.isWin2003) { return "Windows 2003"; }
			if (this.isWinXP) { return "Windows XP"; }
			if (this.isWin2K) { return "Windows 2000"; }
			if (this.isWinNT) { return "Windows NT"; }
			if (this.isWin98) { return "Windows 98"; }
			if (this.isWin95) { return "Windows 95"; }
			if (this.isWin31) { return "Windows 3.1"; }
			if (this.isWin16) { return "Windows 16-bit"; }
			if (this.isWin32) { return "Windows 32-bit"; }
			return "Windows";
		}
		
		if (this.isMac)
		{
			if (this.isMacPPC) { return "Mac PowerPC"; }
			if (this.isMac68K) { return "Mac 68K"; }
			return "Mac";
		}
		
		if (this.isSun)
		{
			if (this.isSun5) { return "SunOS 5"; }
			if (this.isSun4) { return "SunOS 4"; }
			if (this.isSuni86) { return "SunOS i86"; }
			return "SunOS";
		}
		
		if (this.isIRIX)
		{
			if (this.isIRIX6) { return "IRIX 6"; }
			if (this.isIRIX5) { return "IRIX 5"; }
			return "IRIX";
		}
		
		if (this.isHPUX)
		{
			if (this.isHPUX10) { return "HP-UX 10"; }
			if (this.isHPUX9) { return "HP-UX 9"; }
			return "HP-UX";
		}
		
		if (this.isAIX)
		{
			if (this.isAIX4) { return "AIX 4"; }
			if (this.isAIX3) { return "AIX 3"; }
			if (this.isAIX2) { return "AIX 2"; }
			if (this.isAIX1) { return "AIX 1"; }
			return "AIX";
		}
		
		if (this.isOS2) { return "OS/2"; }
		if (this.isLinux) { return "Linux"; }
		if (this.isSCO) { return "SCO UNIX"; }
		if (this.isUNIXWare) { return "UNIX System V"; }
		if (this.isMPRAS) { return "MPRAS"; }
		if (this.isReliant) { return "Reliant UNIX"; }
		if (this.isDEC) { return "DEC"; }
		if (this.isSinix) { return "Sinix"; }
		
		if (this.isBSD)
		{
			if (this.isFreeBSD) { return "FreeBSD"; }
			return "BSD";
		}
		
		if (this.isUNIX) { return "UNIX"; }
		if (this.isVMS) { return "VMS"; }
		return "Unknown";
	},
	
	get_vbScriptEnabled: function()
	{
		if ("undefined" === typeof(window.VBScriptEnabled))
		{
			window.VBScriptEnabled = false;
			if ("undefined" !== typeof(window.execScript))
			{
				try
				{
					window.execScript("window.VBScriptEnabled = True", "vbscript");
				}
				catch (ex)
				{
				}
			}
		}
		
		return window.VBScriptEnabled;
	},
	
	get_xmlVersion: function()
	{
		if ("undefined" === typeof(this._xmlVersion))
		{
			if ("undefined" !== typeof(XMLHttpRequest))
			{
				this._xmlVersion = "Native";
			}
			else
			{
				this._xmlVersion = "None";
				
				var data = "<imr>My XML</imr>";
				var versions = 
				[
					{ ProgID: "Msxml2.DOMDocument.4.0", Version: "MSXML 4.0" },
					{ ProgID: "Msxml2.DOMDocument.3.0", Version: "MSXML 3.0" },
					{ ProgID: "Msxml2.DOMDocument.2.6", Version: "MSXML 2.6" },
					{ ProgID: "Msxml2.DOMDocument", Version: "MSXML 2.0" },
					{ ProgID: "Microsoft.XMLDOM", Version: "MSXML 1.0" }
				];
				
				for (var i = 0; i < versions.length; i++)
				{
					try
					{
						var domDoc = new ActiveXObject(versions[i].ProgID);
						domDoc.async = false;
						if (domDoc.loadXML(data))
						{
							this._xmlVersion = versions[i].Version;
							break;
						}
					}
					catch (e)
					{
					}
				}
			}
		}
		
		return this._xmlVersion;
	}
};