/* 	DEVICE_DETECTION2.JS
	$Id: device_detection2.js,v 1.4 2010/08/05 16:04:15 dgasior Exp $

	This library is designed to give you three pieces of information:

	a. info.device -- the name/ID of the specific device: e.g. "Motorola Droid"
	b. info.os -- the name/ID of the operating system, e.g. "Android"
	c. info.category -- what class of device this is (mobile, tablet, desktop, appliance, etc.)
*/

/* version 0.9
   4/16/2010 - ABE
   added winOSFamily to desktopDeviceCategory
   changed categories sequence to detect desktops first -- and will set deviceCategory=unknownDeviceCategory.id if no match can be found.
*/

/* TODO: incorporate all known desktop OS's  --> good resource is http://www.geekpedia.com/code47_Detect-operating-system-from-user-agent-string.html */
/*
        'Windows 3.11' => 'Win16',
        'Windows 95' => '(Windows 95)|(Win95)|(Windows_95)',
        'Windows 98' => '(Windows 98)|(Win98)',
        'Windows 2000' => '(Windows NT 5.0)|(Windows 2000)',
        'Windows XP' => '(Windows NT 5.1)|(Windows XP)',
        'Windows Server 2003' => '(Windows NT 5.2)',
        'Windows Vista' => '(Windows NT 6.0)',
        'Windows 7' => '(Windows NT 7.0)',
        'Windows NT 4.0' => '(Windows NT 4.0)|(WinNT4.0)|(WinNT)|(Windows NT)',
        'Windows ME' => 'Windows ME',
        'Open BSD' => 'OpenBSD',
        'Sun OS' => 'SunOS',
        'Linux' => '(Linux)|(X11)',
        'Mac OS' => '(Mac_PowerPC)|(Macintosh)',
        'QNX' => 'QNX',
        'BeOS' => 'BeOS',
        'OS/2' => 'OS/2',
*/

/* Copyright (c) 2010 Adobe Systems Incorporated. * All rights reserved. * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */

	var droidDeviceProfile = {id:"Motorola Droid",frag:/droid build/};
	var nexusDeviceProfile =  {id:"Google Nexus One",frag:/Android 2/i};
	var palmPreDeviceProfile = {id:"Palm Pre", frag:/525.27.1 pre/i};
	var genericAndroid2DeviceProfile = {id:"Generic Android 2 device", frag:/Android 2/i}; 
	var genericAndroid1DeviceProfile = {id:"Generic Android 1 device", frag:/Android 1/i}; 
	var genericWebOSDeviceProfile = {id:"genericWebOS Device", frag:/webos/i}; 
	
	var win311DeviceProfile = {id:"Windows 3.11",frag:/win16/i};
	var win95ADeviceProfile = {id:"Windows 95",frag:/windows 95/i};
	var win95BDeviceProfile = {id:"Windows 95",frag:/win95/i};
	var win95CDeviceProfile = {id:"Windows 95",frag:/win_95/i};
	var win2000ADeviceProfile = {id:"Windows 2000",frag:/windows 2000/i};
	var win2000BDeviceProfile = {id:"Windows 2000",frag:/windows nt 5.0/i};

	var winServer2003DeviceProfile = {id:"Windows Server 2003",frag:/windows nt 5.2/i};
	
	var winNT40ADeviceProfile = {id:"Windows NT 4.0",frag:/windows nt 4.0/i};
	var winNT40BDeviceProfile = {id:"Windows NT 4.0",frag:/winnt/i};
	var winNT40CDeviceProfile = {id:"Windows NT 4.0",frag:/windows nt/i}; // need to make sure this gets processed last as it would otherwise prevent correct id
	// of windows 2000 for example or replace with regular expression that is more strict.

	var winmeDeviceProfile = {id:"Windows ME",frag:/windows me/i};

	var openBSDDeviceProfile = {id:"OpenBSD",frag:/openbsd/i};
	var sunOSDeviceProfile = {id:"Sun OS",frag:/sunos/i};
	var linuxADeviceProfile = {id:"Linux",frag:/linux/i};
	var linuxBDeviceProfile = {id:"Linux",frag:/x11/i};
	var QNXDeviceProfile = {id:"QNX",frag:/qnx/i};
	var beosDeviceProfile = {id:"BeOS",frag:/beos/i};
	var os2DeviceProfile = {id:"OS2",frag:/OS\/2/i};

	var winxpDeviceProfile = {id:"Windows XP",frag:/windows xp/i};
	var winxp2DeviceProfile = {id:"Windows XP",frag:/windows nt 5.1/i};
	var win7ADeviceProfile = {id:"Windows 7",frag:/windows nt 6.1/i};
	var win7BDeviceProfile = {id:"Windows 7",frag:/windows nt 7.01/i};
	var winvistaDeviceProfile = {id:"Windows Vista",frag:/windows nt 6.0/i};
	
	var macosx106DeviceProfile =  {id:"Snow Leopard",frag:/mac os x 10.6/i};
	var macosx105DeviceProfile =  {id:"Leopard",frag:/mac os x 10.5/i};
	var macosA = {id:"Mac OS",frag:/mac_powerpc/i};
	var macosB = {id:"Mac OS",frag:/macintosh/i};

/* OPERATING SYSTEMS */
	
	var androidOSFamily = {id:"Android OS",frag:/android /i,devices:[droidDeviceProfile,nexusDeviceProfile,genericAndroid1DeviceProfile,genericAndroid2DeviceProfile]};
	
	var webOSFamily = {id:"webOS",frag:/webOS\/1.3.5/i,devices:[palmPreDeviceProfile, genericWebOSDeviceProfile]};
	
	var macOSFamily = {id:"Mac OS",frag:/mac os/i,devices:[macosx105DeviceProfile,macosx106DeviceProfile,macosA, macosB]};

	var winOSFamily = {id:"Windows",frag:/windows/i,devices:[winxpDeviceProfile,winxp2DeviceProfile,win7ADeviceProfile,win7BDeviceProfile,winvistaDeviceProfile,win311DeviceProfile,win95ADeviceProfile,win95BDeviceProfile,win95CDeviceProfile,winServer2003DeviceProfile,winNT40ADeviceProfile,winNT40BDeviceProfile,winNT40CDeviceProfile,winmeDeviceProfile]};

	var linuxOSFamily = {id:"Linux",frag:/linux/i,devices:[openBSDDeviceProfile,sunOSDeviceProfile,linuxADeviceProfile, linuxBDeviceProfile, QNXDeviceProfile,beosDeviceProfile,os2DeviceProfile]};

/* CATEGORIES */

	var desktopDeviceCategory = {id:"Desktop",osFamilies:[macOSFamily,winOSFamily,linuxOSFamily]};
	
	var mobileDeviceCategory = {id:"Mobile",osFamilies:[androidOSFamily,webOSFamily]};
	
	var unknownDeviceCategory = {id:"Unidentified Platform"};
	
	var categories = [mobileDeviceCategory,desktopDeviceCategory /*,mobileDeviceCategory*/];

/*
	function StringBuffer() {
		this.__strings__ = new Array;
	}
	
	StringBuffer.prototype.append = function (str) {
		this.__strings__.push(str);
	};
	
	StringBuffer.prototype.toString = function () {
		return this.__strings__.join("");
	};


	function isdefined( variable)
	{
		return (typeof(window[variable]) == "undefined")?  false: true;
	}

	function displayOrientation() {
		var err = "";
		try {
			var c = context;
	
	
			if(isDefined(context)) {
				if(isDefined(context.getResources())) {
					if(isDefined(context.getResources().getConfiguration())) {
						var orientation= context.getResources().getConfiguration();
						if(isdefined(orientation)) {
							
							document.write("orientation: "+orientation);
						} else {
							err = "no orientation";
						}
					} else {
						err = "no configuration";
					}
				} else {
					err = "no resources";
				} 
			} else {
				err = "no context";
			}
			mylog("err: "+err);
		} catch (e) {
		  mylog("no display orientation data available");
  		  return;
		}


	}
	
	function mylog(s) {
		document.write('<div style="color:grey">'+s+'</div>');
	}

	function dumpDeviceInfo() {
		var buf;
// 	document.write('<div style="color:white">checkpoint dump1</div>');
		try {
			var Build = android.os.Build;
			if(isdefined(Build)) {
// 	document.write('<div style="color:white">checkpoint dump2</div>');
				buf = new StringBuffer();
				buf.append("VERSION.RELEASE {"+Build.VERSION.RELEASE+"}");
				buf.append("\nVERSION.INCREMENTAL {"+Build.VERSION.INCREMENTAL
				+"}");
				buf.append("\nVERSION.SDK {"+Build.VERSION.SDK+"}");
				buf.append("\nBOARD {"+Build.BOARD+"}");
				buf.append("\nBRAND {"+Build.BRAND+"}");
				buf.append("\nDEVICE {"+Build.DEVICE+"}");
				buf.append("\nFINGERPRINT {"+Build.FINGERPRINT+"}");
				buf.append("\nHOST {"+Build.HOST+"}");
				buf.append("\nID {"+Build.ID+"}");
				
				mylog("build:"+buf);
			}
		} catch(e) {
//			document.write('<div style="color:white">checkpoint dump3</div>');
			mylog("no device info available");
			return;
		}
	}
	
*/

	function identifyDevice(d,ua) {
//		document.write('<div style="color:white">'+d.frag+' =? '+ua+'</div>');
  		if (ua.search(d.frag) > -1) {
//			document.write('<div style="color:white">MATCH!</div>');
		  	return {device:d.id};
		} else
		  return null;
	}

	function identifyOS(os,ua) {
		var deviceInfo=null;
		var olen = os.devices.length;
		for(var k=0;k<olen;k++) {
			deviceInfo = identifyDevice(os.devices[k],ua);
			if(deviceInfo!=null) break;
		}
		if(deviceInfo!=null) deviceInfo.os = os.id;
		return deviceInfo;
	}

	function identifyCategory(cat,ua) {
		var osInfo=null;
		var jlen = cat.osFamilies.length;
		for(var j=0;j<jlen;j++) {
			osInfo = identifyOS(cat.osFamilies[j],ua);
			if(osInfo!=null) break;
		}
		if(osInfo!=null) osInfo.category = cat.id;
		return osInfo;
	}

	function identifyCategories(cats,ua) {
		var categoryInfo=null;
		var clen = cats.length;
		for(var i=0;i<clen;i++) {
			categoryInfo = identifyCategory(cats[i],ua);
			if(categoryInfo!=null) break;
		}
		
		if(!categoryInfo) categoryInfo = {};
		if(!categoryInfo.device) categoryInfo.device='unknown';
		if(!categoryInfo.os) categoryInfo.os = 'unknown';
		if(!categoryInfo.category) categoryInfo.category = unknownDeviceCategory.id;
		return categoryInfo;
	}
	
	
	// external method
	// returns an object that should contain
	//		category (such as 'Desktop' or 'Mobile'
	//		os			(such as 'Windows', 'Mac OS', 'Android', etc.
	//		device		(such as 'Windows XP','Android', etc.
	
	// TBD:
	//		osversion
	//		carrier
	//		deviceregion
	
	function getCategoriesInfo() {
		return identifyCategories(categories, navigator.userAgent.toLowerCase());
	}
	
	function displayCategoriesInfo() {
		alert('isDesktop:'+isDesktop()  + ', os:' + info.os + ', device:' + info.device);
	} 
	
	function isDroid() {
		return (info.device==droidDeviceProfile.id);
	}
	
	function isNexus() {
		return(info.device==nexusDeviceProfile.id);
	}
	
	function isDesktop() {
		return(info.category==desktopDeviceCategory.id);
	}
	
	function isLinuxDesktop() {
		return(info.os==linuxOSFamily.id);
	}
			
	
	function isWinDesktop() {
		return(info.os==winOSFamily.id);
	}
	
	function isMacDesktop() {
		return(info.os==macOSFamily.id);
	}
	
	function simulateDroid() {
		info.device = droidDeviceProfile.id;
		info.category = mobileDeviceCategory.id;
		info.os = androidOSFamily.id;
	}
