/**
* System Check
* by Gareth Farrington
* 
* Checks for the following things on a client:
*  - Cookies enabled
*  - Flash installed and current
*  - Browser version (IE >= 6, FF >= 2, Safari, Opera)
*/

var detectableWithVB = false;

// Here we write out the VBScript block for MSIE Windows
if((navigator.userAgent.indexOf('MSIE') != -1) && (navigator.userAgent.indexOf('Win') != -1)) {
	document.writeln('<script language="VBscript">');

	document.writeln('\'do a one-time test for a version of VBScript that can handle this code');
	document.writeln('detectableWithVB = False');
	document.writeln('If ScriptEngineMajorVersion >= 2 then');
	document.writeln('	detectableWithVB = True');
	document.writeln('End If');

	document.writeln('\'this next function will detect most plugins');
	document.writeln('Function detectActiveXControl(activeXControlName)');
	document.writeln('	on error resume next');
	document.writeln('	detectActiveXControl = False');
	document.writeln('	If detectableWithVB Then');
	document.writeln('		detectActiveXControl = IsObject(CreateObject(activeXControlName))');
	document.writeln('	End If');
	document.writeln('End Function');

	document.writeln('\'and the following function handles QuickTime');
	document.writeln('Function detectQuickTimeActiveXControl()');
	document.writeln('  on error resume next');
	document.writeln('  detectQuickTimeActiveXControl = False');
	document.writeln('  If detectableWithVB Then');
	document.writeln('    detectQuickTimeActiveXControl = False');
	document.writeln('    hasQuickTimeChecker = false');
	document.writeln('    Set hasQuickTimeChecker = CreateObject("QuickTimeCheckObject.QuickTimeCheck.1")');
	document.writeln('    If IsObject(hasQuickTimeChecker) Then');
	document.writeln('      If hasQuickTimeChecker.IsQuickTimeAvailable(0) Then ');
	document.writeln('        detectQuickTimeActiveXControl = True');
	document.writeln('      End If');
	document.writeln('    End If');
	document.writeln('  End If');
	document.writeln('End Function');

	document.writeln('</scr' + 'ipt>');
}

var SystemCheck = DiggClass.create({
	/*
	Makes these properties available:
		
	hasFlash        - has flash installed
	flashVersion
		
	hasCookies      - cookies are enabled
	os              - OS informations string
	ip	             - host IP of the client
		
	isFirefox
	isOpera
	isSafari
	isIe
	isOtherBrowser
		
	browser
	browserVersion
	*/
	init: function() {
		//console.time("systemCheck");
		this.resultData = {};

		// OS:
		this.detectPlatform();

		// Detailed browser detection:
		this.detectUserAgent();

		this.detectFlash();
		this.detectJava();
		this.detectSilverlight();
		this.detectQuicktime();
		this.detectWindowsMedia();
		this.detectReal();

		//console.timeEnd("systemCheck");
	},

	results: function() {
		return this.resultData;
	},

	canDetectPlugins: function() {
		if(detectableWithVB || (navigator.plugins && navigator.plugins.length > 0)) {
			return true;
		} else {
			return false;
		}
	},

	detectPlatform: function() {
		// IP address?
		this.resultData['ip'] = clientIp;

		// Host name?
		this.resultData['serverHostName'] = hostName;

		// cookies turned on?
		this.resultData['hasCookies'] = navigator.cookieEnabled;

		// blocks popups?		
		var popup = window.open("/tespopup.html", "PopupBlockerTest", "width=100,height=100,top=0,left=0");

		if(popup === null || popup === undefined) {
			this.resultData['blocks popups'] = true;
		} else {
			popup.blur();
			window.focus();
			try {
				popup.close();
				this.resultData['blocks popups'] = false;
			} catch(e) { this.resultData['blocks popups'] = true; } // this is necessary because blocked popups in opera still return a window object, but it errors on close.
		}

		// screen size:
		this.resultData['display'] = screen.height + 'x' + screen.width + ' ' + screen.colorDepth + ' bits';

		// Language
		this.resultData['language'] = navigator.language ? navigator.language : navigator.browserLanguage ? navigator.browserLanguage : 'n/a';

		// current time for converting timezone offset
		var theTime = new Date()
		this.resultData['time'] = JSON.stringify(theTime);
		this.resultData['timezoneOffset'] = theTime.getTimezoneOffset();

		// OS
		var platform = navigator.platform;
		if(platform.indexOf('Win') >= 0)
			platform += ' (Windows)';
		else if(platform.indexOf('Mac') >= 0)
			platform += ' (Mac)';
		else if(platform.indexOf('Linux') >= 0)
			platform += ' (Linux)';
		this.resultData['platform'] = platform;

	},

	detectUserAgent: function() {
		// usefull regular expressions:
		var ffVersionRegex = /Firefox[\/\s](\d+\.\d+)/; //test for Firefox/x.x or Firefox x.x (ignoring remaining digits);
		var ieVersionRegex = /MSIE (\d+\.\d+);/; //test for MSIE x.x;
		var operaVersionRegex = /Opera[\/\s](\d+\.\d+)/;
		var safariVersionRegex = /Safari[\/\s](\d+\.\d+)/;

		var userAgent = navigator.userAgent;
		var browser;
		var browserVersion;

		if(ffVersionRegex.test(navigator.userAgent)) {
			browser = "Firefox";
			browserVersion = new Number(RegExp.$1);
		}
		else if(ieVersionRegex.test(navigator.userAgent)) {
			browser = "IE";
			browserVersion = new Number(RegExp.$1);
			if(/Trident\/4\.0/.test(navigator.userAgent) && browserVersion < 8.0)
				browserVersion = 8.0;
		}
		else if(operaVersionRegex.test(navigator.userAgent)) {
			browser = "Opera";
			browserVersion = new Number(RegExp.$1);
		}
		else if(safariVersionRegex.test(navigator.userAgent)) {
			browser = "Safari";
			browserVersion = new Number(RegExp.$1);
		}
		else {
			browser = navigator.appName;
			browserVersion = navigator.appVersion;
		}

		this.resultData['userAgent'] = userAgent;
		this.resultData['browser'] = browser;
		this.resultData['browserVersion'] = browserVersion;

		// plugins:
		if(navigator.plugins && navigator.plugins.length > 0) {
			var plugins = [];
			for(var i = 0; i < navigator.plugins.length; i++) {
				plugins.push(navigator.plugins[i].name);
			}
			this.resultData['plugins'] = JSON.stringify(plugins);
		}
	},

	detectFlash: function() {
		var detectFlash = new DetectFlash();
		var hasFlash = false;
		var flashVersion = detectFlash.flashVersion();
		if(flashVersion === false)
			flashVersion = 'undetected';
		else
			hasFlash = true;

		this.resultData['hasFlash'] = hasFlash;
		this.resultData['flashVersion'] = flashVersion;

		return hasFlash;
	},

	detectJava: function(redirectURL, redirectIfFound) {
		var pluginFound = false;
		var hasJava = false;
		var javaVersion = 'undetected';

		// try for navigator and friends:
		try {
			pluginFound = navigator.javaEnabled();
		}
		catch(e) { }

		// try searching in the plugins list:
		pluginFound = this.detectPlugin('Java');

		// if not found, try to detect with VisualBasic
		if(!pluginFound && detectableWithVB) {
			pluginFound = detectActiveXControl('JavaWebStart.isInstalled');
			if(pluginFound) {
				if(detectActiveXControl('JavaWebStart.isInstalled.1.4.2.0'))
					javaVersion = '1.4.2.0';
				if(detectActiveXControl('JavaWebStart.isInstalled.1.5.0.0'))
					javaVersion = '1.5.0.0';
				if(detectActiveXControl('JavaWebStart.isInstalled.1.6.0.0'))
					javaVersion = '1.6.0.0';
			}
		}
		if(pluginFound) {
			hasJava = true;
			if(pluginFound !== true)
				javaVersion = pluginFound;
		}

		this.resultData['hasJava'] = hasJava;
		this.resultData['javaVersion'] = javaVersion;

		return hasJava;
	},

	detectSilverlight: function() {
		var version = 0;

		try {
			var control = new ActiveXObject('AgControl.AgControl');
			for(var i=1; control.IsVersionSupported(i + '.0'); i++) {
				version = i;
			}
			control = null;
		}
		catch(e) {
			try {
				var plugin = navigator.plugins["Silverlight Plug-In"];
				if(plugin) {
					version = parseFloat(plugin.description.split('.').slice(0, 2).join('.'));
				}
			}
			catch(ex) {
			}
		}

		this.resultData.hasSilverlight = version > 0;
		this.resultData.silverlightVersion = version;
	},

	detectDirector: function(redirectURL, redirectIfFound) {
		var hasDirector = false;
		var directorVersion = 'undetected';
		var pluginFound = this.detectPlugin('Shockwave', 'Director');
		// if not found, try to detect with VisualBasic
		if(!pluginFound && detectableWithVB) {
			pluginFound = detectActiveXControl('SWCtl.SWCtl.1');
		}
		if(pluginFound) {
			hasDirector = true;
			if(pluginFound !== true)
				directorVersion = pluginFound;
		}

		this.resultData['hasDirector'] = hasDirector;
		this.resultData['directorVersion'] = directorVersion;

		return hasDirector;
	},

	detectQuicktime: function(redirectURL, redirectIfFound) {
		var hasQuicktime = false;
		var quicktimeVersion = 'undetected';

		var pluginFound = this.detectPlugin('QuickTime');
		// if not found, try to detect with VisualBasic
		if(!pluginFound && detectableWithVB) {
			pluginFound = detectQuickTimeActiveXControl();
		}
		if(pluginFound) {
			hasQuicktime = true;
			if(pluginFound !== true)
				quicktimeVersion = pluginFound;
		}

		this.resultData['hasQuicktime'] = hasQuicktime;
		this.resultData['quicktimeVersion'] = quicktimeVersion;

		return hasQuicktime;
	},

	detectReal: function(redirectURL, redirectIfFound) {
		var hasReal = false;
		var realVersion = 'undetected';
		var pluginFound = this.detectPlugin('RealPlayer');
		// if not found, try to detect with VisualBasic
		if(!pluginFound && detectableWithVB) {
			pluginFound = (detectActiveXControl('rmocx.RealPlayer G2 Control') ||
			detectActiveXControl('RealPlayer.RealPlayer(tm) ActiveX Control (32-bit)') ||
			detectActiveXControl('RealVideo.RealVideo(tm) ActiveX Control (32-bit)'));
		}
		if(pluginFound) {
			hasReal = true;
			if(pluginFound !== true)
				realVersion = pluginFound;
		}

		this.resultData['hasReal'] = hasReal;
		this.resultData['realVersion'] = realVersion;

		return hasReal;
	},

	detectWindowsMedia: function(redirectURL, redirectIfFound) {
		var hasWindowsMedia = false;
		var windowsMediaVersion = 'undetected';
		var pluginFound = this.detectPlugin('Windows Media Player');
		// if not found, try to detect with VisualBasic
		if(!pluginFound && detectableWithVB) {
			pluginFound = detectActiveXControl('MediaPlayer.MediaPlayer.1');
		}
		hasWindowsMedia = pluginFound;
		if(pluginFound) {
			hasWindowsMedia = true;
			if(pluginFound !== true)
				windowsMediaVersion = pluginFound;
		}

		this.resultData['hasWindowsMedia'] = hasWindowsMedia;
		this.resultData['windowsMediaVersion'] = windowsMediaVersion;

		return hasWindowsMedia;
	},

	detectPlugin: function() {
		// allow for multiple checks in a single pass
		var pluginNames = arguments;
		// consider pluginFound to be false until proven true
		var pluginFound = false;

		// if plugins array is there and not fake
		if(navigator.plugins && navigator.plugins.length > 0) {
			var pluginsArrayLength = navigator.plugins.length;
			// for each plugin...
			for(pluginsArrayCounter = 0; pluginsArrayCounter < pluginsArrayLength; pluginsArrayCounter++) {
				// loop through all desired names and check each against the current plugin name
				var numFound = 0;
				for(namesCounter = 0; namesCounter < pluginNames.length; namesCounter++) {
					// if desired plugin name is found in either plugin name or description
					if((navigator.plugins[pluginsArrayCounter].name.indexOf(pluginNames[namesCounter]) >= 0) ||
							(navigator.plugins[pluginsArrayCounter].description.indexOf(pluginNames[namesCounter]) >= 0)) {
						// this name was found
						pluginFound = navigator.plugins[pluginsArrayCounter].name;
						numFound++;
					}
				}

				// now that we have checked all the required names against this one plugin,
				// if the number we found matches the total number provided then we were successful
				if(numFound == pluginNames.length) {
					//pluginFound = true;
					// if we've found the plugin, we can stop looking through at the rest of the plugins
					break;
				}
			}
		}
		//console.log('Search for plugin ', pluginNames, 'Plugin turned up:', pluginFound);
		return pluginFound;
	},

	// Output a template with what we know about the system:
	templateResults: function() {
		//console.log("templating system check results...");

		var dataArray = [];
		for(key in this.resultData) {
			dataArray.push({ key: key, value: this.resultData[key] });
		}

		return $j.tempest('<tr><td><h4>{{key}}</h4></td><td>{{value}}</td></tr>', dataArray);
	}
});
