/*
AppWorld plugin javascript library
*/
var awp_global_object;
var rebootTime=10000;
	function _awp_global_object(plugin){
		this.plugin=plugin;
		this.javaLoader=false;
		this.rebooting=false;
		this.expectingReboot=false;
		this.reconnectPin="";
		this.reconnectPass="";
		this.asyncMsgInProg=false;
		this.asyncCompleteCallback=null;
		this.forceUpg=false;
		
		//methods
		
		this.isForceUpgradeActive = function(){
			return this.forceUpg;
		}

		this.activateForcedUpgrade = function(){
			this.forceUpg=true;
		}
		
		this.isAsyncMsgInProg = function(){
			return this.asyncMsgInProg;
		}
		
		this.clearAsyncState = function(){
			this.asyncMsgInProg=false;
			this.asyncCompleteCallback=null;
		}
		
		this.getAsyncCallback = function(){
			return this.asyncCompleteCallback;
		}
		
		this.sendAsyncMessage = function(message, asyncCompleteCallback){
			if(this.getState() !== AWP_CONNECTED){
				return false;
			}
			this.asyncMsgInProg=true;
			this.asyncCompleteCallback=asyncCompleteCallback;
			var results = this.plugin.sendAsyncMessage(message);
			if (results.errorCode != AWP_ERROR_NONE){
				notifyListeners(DEVICE_ASYNCE_MESSAGE_FAILURE);
			}
		}
		
		this.setExpectingReboot = function(){
			this.expectingReboot=true;
		}
		
		this.isRebooting = function(){
			return (this.rebooting || isDeviceRebootingFromCookie())
		}
		
		this.setRebooting = function(rebooting,rebootPin){
			this.rebooting=rebooting
			if (rebooting){				
				setRebootingInCookie();
				if (rebootPin != undefined){
					persistRebootPin(rebootPin);
				}
			}else{
				clearRebootingInCookie();
			}
		}
		
		this.isDeviceAttached = function(device){
			var ndevice=parseInt(device, 16);
			var devices = this.getConnectedDevices();
			var i=0;
			for (i; i<devices.length; i++){
				if (ndevice == devices[i]){
					return true;
				}				
			}
			return false;
		}
		
		
		this.getConnectedDevices = function(){
			var results = this.plugin.getDeviceData();
		    devices = new Array();
		    deviceCount = results.deviceCount;
		    if( results.errorCode === 0 )
		    {
		    	var i=0;
		  
		    	for( i; i < deviceCount; i++ )
		    	{
		    		devices[i]= results.getDevice( i ) ;
		    	} 
		    }	    
		    return devices;
		}
		
		this.getState = function(){
			return this.plugin.getState().state;			
		}
		
		this.getDeviceInfo = function(){
		    var results;
		    var response;
		    results = this.plugin.sendMessage( AWM_DEVICE_INFO );
		    if( results.errorCode == AWP_ERROR_NONE){
		    	response = parseDeviceInfo(results.response);
		    }else{
		    	peEvent(PE_CONN_ERR_UNKNOWN);
		    }
		    return response;	    
		}
		
		this.getDeviceInfoRaw = function(){
		    var results;
		    var response;
		    results = this.plugin.sendMessage( AWM_DEVICE_INFO );
		    if( results.errorCode == AWP_ERROR_NONE){
		    	return results.response;
		    }else{
		    	peEvent(PE_CONN_ERR_UNKNOWN);
		    }
		   return null;	    
		}
		
		this.getDeviceContent = function (){ 
		    var results;
		    var response;
		    var resultsObj;
		    results = this.plugin.sendMessage( AWM_DEVICE_CONTENT );
		    if( results.errorCode == AWP_ERROR_NONE){
		    	resultsObj = parseDeviceContent(results.response);
		    }else{
		    	//call error event
		    	peEvent(PE_CONN_ERR_UNKNOWN);
		    }
		    return resultsObj;	    
		}
		
		this.isDeviceAuthenticated = function () {
	  		results = this.plugin.getState();
	  		if(results.errorCode === 0) {
	  	  		if(results.state === AWP_CONNECTED || results.state === AWP_LEGACY_CONNECTED) {
	  				return true;
	  			}
	  		} else{
	  			peEvent(PE_CONN_ERR_UNKNOWN);
	  		}
	  		
	  		return false;
	  	}
		
		this.disconnect = function(){
			this.plugin.disconnect();
		}
		
		this.reconnect = function(javaLoader){
			this.connect(this.reconnectPin, this.reconnectPass, javaLoader);			
		}
		
		this.connect = function(con_pin, password, javaLoader){	
			if (con_pin != undefined && con_pin != ""){
				this.reconnectPin = con_pin;
				this.reconnectPass = password;
			}
			if (this.isRebooting()){
				this.reconnectPin=getRebootPin();
				con_pin=this.reconnectPin;
			}
			
			this.javaLoader=javaLoader;					
			if (this.isDeviceAuthenticated()){
				if (javaLoader && this.getState() !== AWP_LEGACY_CONNECTED){
					this.disconnect();
				}else if(!javaLoader && this.getState() === AWP_LEGACY_CONNECTED){
					this.disconnect();
				}else {
					return;
				}			
			}
			var results;
			if (javaLoader){
				 results = this.plugin.legacyConnect(parseInt(con_pin, 16), password );
			}else{ 
				 results = this.plugin.connect(parseInt(con_pin, 16), password );
			}
		    if(results.errorCode == AWP_ERROR_INVALID_PASSWORD) {
		    	lockReconnect();
		    	 if (password == '' && results.passwordRetries == 1){	
		    		 peEvent(PE_CONN_ERR_MIN_RETRIES_EMPTY_PASSWORD);
			    	 return;	
				 } else if (password == '' || results.passwordRetries == -1){
		    		 peEvent(PE_CONN_ERR_REQUIRES_PASSWORD);	
		    		 return;
		         } else if (password == '' && results.passwordRetries == 1){	
			    	 return;	
				 } else if(results.passwordRetries == 1 || results.passwordRetries == 0 ){
					 peEvent(PE_CONN_ERR_MIN_RETRIES_REACHED);
					 return;
				 }
		    	 peEvent(PE_CONN_ERR_INVALID_PASSWORD);
		    } else if (results.errorCode == AWP_ERROR_NONE){
		    	unlockReconnect();
				this.setRebooting(false);
		    	if (this.javaLoader){
		    		peEvent(PE_CONN_OK_LEGACY);
				}else {
					clearRebootingInCookie();
					peEvent(PE_CONN_OK);
				}
		    }else if (results.errorCode == AWP_ERROR_APP_WORLD_NOT_RUNNING) {
		    	unlockReconnect();
		    	if (!this.isRebooting()){
		    		peEvent(PE_CONN_ERR_APP_WORLD_NOT_RUNNING);
		    		return;
		    	}else if (this.rebooting && this.getState() != AWP_DISCONNECTED){
		    		this.disconnect()
		    	}
		    	setTimeout('haltForReboot()', rebootTime);
		    }else if(results.errorCode == AWP_ERROR_BB_NOT_CONNECTED){
		    	unlockReconnect();
		    	if (!this.isRebooting()){
		    		peEvent(PE_CONN_ERR_NO_DEVICE_CONNECTED);
		    		return;
		    	}else if (this.isRebooting()){
		    		this.disconnect()
		    	}
		    	setTimeout('haltForReboot()', rebootTime);
		    }else if (results.errorCode == AWP_ERROR_USB_TIMEOUT){
		    	
		    	if (this.isRebooting()){
		    		unlockReconnect();
		    		setTimeout('haltForReboot()', rebootTime);
		    		return;
			    }		
		    	peEvent(PE_CONN_ERR_USB_TIMEOUT);
		    }else if (results.errorCode == AWP_ERROR_DEVICE_ALREADY_CONNECTED){
		    	
		    	if (this.isRebooting()){
		    		unlockReconnect();
		    		setTimeout('haltForReboot()', rebootTime);
		    		return;
			    }		
		    	peEvent(PE_CONN_ERR_DEVICE_CHANNEL_CONSUMED);
		    }else if (results.errorCode == AWP_ERROR_HTTP_NOT_WORKING){
		    	
		    	if (this.isRebooting()){
		    		unlockReconnect();
		    		setTimeout('haltForReboot()', rebootTime);
		    		return;
			    }		
		    	peEvent(PE_CONN_ERR_HTTP_UNAVAILABLE);
		    }else if (results.errorCode == AWP_ERROR_FATAL){
		    	
		    	if (this.isRebooting()){
		    		unlockReconnect();
		    		setTimeout('haltForReboot()', rebootTime);
		    		return;
			    }			    
		    	peEvent(PE_CONN_ERR_FATAL);
		    }
		    else{
		    	if (this.isRebooting()){
		    		unlockReconnect();
		    		setTimeout('haltForReboot()', rebootTime);
		    		return;
			    }		
		   		peEvent(PE_CONN_ERR_UNKNOWN);
		    }
		 
		}
		
	}
	
	function getConnectedDevicePin(){
		var results = getAwpGlobalObject().getDeviceInfo();
		return results['pin'];
	}
	
	function getConnectedHomemnc(){
		var results = getAwpGlobalObject().getDeviceInfo();
		return results['homemnc'];
	}
	
	function getConnectedHomemcc(){
		var results = getAwpGlobalObject().getDeviceInfo();
		return results['homemcc'];
	}
	
	var mutex;
	function lockReconnect(){
		mutex=1;
	}
	function unlockReconnect(){
		mutex=0;
	}
	function isReconnectLocked(){
		if (mutex==1){
			return true;
		}
		return false;
	}
	function haltForReboot(){
		if (isReconnectLocked()){
			return;
		}
		if (getAwpGlobalObject().getState() === AWP_LEGACY_CONNECTED){
			getAwpGlobalObject().disconnect();
		}
		if (getAwpGlobalObject().getState() === AWP_DISCONNECTED){
			getAwpGlobalObject().reconnect(false);
		}
	}
	
	function setAwpGlobalObject(awpgo){
		awp_global_object=awpgo;
	}
	
	function getAwpGlobalObject(){
		return awp_global_object;
	}
	
	var event_cb_array = new Array();
	
	function registerForPEEvent(event, method){
		event_cb_array[event]=method;
	}
	
	function peEvent(event){
		if (event_cb_array[event] != undefined){
			event_cb_array[event]();
		}
	}
	
	
	//plugin api
	
	
	//cookie operations
	function persistRebootPin(pin){
		addToCookie("rebootPin",pin);
	}
	function getRebootPin(){
		return getValue('rebootPin');
	}
	
	function setRebootingInCookie(){
		addToCookie("deviceRebooting","yes");
	}
	function clearRebootingInCookie(){
		addToCookie("deviceRebooting","no");
		addToCookie("rebootPin","");
	}
	
	function isDeviceRebootingFromCookie(){
		if (getValue('deviceRebooting') === "yes"){
			return true;
		}
		return false;
	}
	
	function confirmDeviceConnected(userPin){
		addToCookie("deviceConnected",userPin);
	}
	
	function getConfirmedDevice(){
		return getValue('deviceConnected');		
	}
	
	function getUserPinFromCookie(){
		return getValue('userPin');
	}
	
	function getIgnoreListFromCookie(){
		return getValue('deviceIgnoreList');
	}
	
	function setDeviceIgnoreList(){
		var ignoreList = getIgnoreListFromCookie();
		var connectedDevices = getAwpGlobalObject().getConnectedDevices();
		for (i=0; i<connectedDevices.length; i++){
			if(ignoreList.indexOf('#'+connectedDevices[i]+'#')=== -1){
				if(ignoreList.length > 0) {
					ignoreList +=",";
				}
				ignoreList+='#'+connectedDevices[i] + '#';
			}
		}
		addToCookie('deviceIgnoreList', ignoreList);
	}





    var password = '';
    var debugAW = false;
    
    function error(code, errorSpan){
			var errorMsg;
			
			switch(code){
			case 1001:
				errorMsg=error1001;
				break;
			case 1002:
				errorMsg=error1002;
				break;
			case 1003:
				errorMsg=error1003;
				break;
			case 2001:
				errorMsg=error2001;
				break;
			case 2002:
				errorMsg=error2002;
				break;
			case 2003:
				errorMsg=error2003;
				break;
			case 2004:
				errorMsg=error2004;
				break;
			}
			 errorSpan.innerHTML=errorMsg;
			 showModalPanel('syncErrorPanel');
		}
    
	function isDeviceConnected(pin) {
		var results = awp_ds.getDeviceData();
	    if( results.errorCode === 0 )
	    {
	        var i;
	        for( i = 0; i < results.deviceCount; i++ )
	        {
		  		if(debugAW) alert('isDeviceConnected: check pin ' + pin);
	            if(pin === results.getDevice( i )) {
	            	return true;
	            }
	        }
	    } else {
	  		if(debugAW) alert('isDeviceConnected: error');
            var errorText = verboseError( results.errorCode );
	    }
	    
	    return false;
	}
	//message factories
    function parseDeviceInfo(results){
    	var response = new Array();
        var mySplitResult = results.split("&");
        for(i = 0; i < mySplitResult.length; i++){
              try{
                    var keyval = mySplitResult[i].split("="); 
                    response[keyval[0]] = keyval[1];
              }catch(err){
              }
        }
        return response;
    }
    
    function parseDeviceContent(results){
    	if (results==undefined){
    		return null;
    	}
    	var infoMessage2Obj = new Object();
    	var ids=new Array();
    	var state=new Array();
    	var installedFileBundle=new Array();
    	var fileBundleType=new Array();
    	var numApps=0;
        var mySplitResult = results.split("&");
        
        for(i = 0; i < mySplitResult.length; i++){
              try{
                    var keyval = mySplitResult[i].split("="); 
                    if (keyval[0] === 'flashtotal'){
                    	infoMessage2Obj.flashTotal = keyval[1];
                    }else if (keyval[0] === 'flashfree'){
                    	infoMessage2Obj.flashFree = keyval[1];
                    }else{
                    	ids[numApps]=keyval[0];
                    	var decodedString = unescape(keyval[1]);
                    	var states = decodedString.split(":");
                    	state[numApps]=states[0];
                    	installedFileBundle[numApps]=states[1];
                    	fileBundleType[numApps]=states[2];
                    	numApps++;
                    }                    
              }catch(err){
            	  continue;
              }
        }
        infoMessage2Obj.idArray=ids;
        infoMessage2Obj.state=state;
        infoMessage2Obj.installedFileBundle=installedFileBundle;
        infoMessage2Obj.fileBundleType=fileBundleType;
        infoMessage2Obj.originalMessage=results;
        return infoMessage2Obj;
    }
    
    function writeDeviceContentToCookie(infoMessage2Obj){
    	addToCookie('infoMessage2', infoMessage2Obj.originalMessage);
    }
    
    function getDeviceContentFromCookie(){
    	var originalMessage = getValue('infoMessage2');
    	var infoMessage2Obj = parseDeviceContent(originalMessage);
    	return infoMessage2Obj;
    }
    
    function getDeviceContentFromCookieById(contentId) {
    	var infoMessage2Obj = getDeviceContentFromCookie();
    	if(infoMessage2Obj == null) return null;
    	for(var i = 0; i < infoMessage2Obj.idArray.length; i++) {
    		if (infoMessage2Obj.idArray[i] == contentId) {
    			var retObj = new Object();
    			retObj.id = infoMessage2Obj.idArray[i];
    			retObj.state = infoMessage2Obj.state[i];
    			retObj.installedFileBundle = infoMessage2Obj.installedFileBundle[i];
    			retObj.fileBundleType = infoMessage2Obj.fileBundleType[i];
    			
    			return retObj;
    		}
    	}
    	
    	return null;
    }
    
    function isContentInstalledOnTheDevice(contentId) {
    	var deviceContent = getDeviceContentFromCookieById(contentId);
    	var installed = false;
    	if(deviceContent == null) {
	    	return installed;
    	}
    	
        switch(deviceContent.state){
            case STATE_DISCOVERED:
            case STATE_PURCHASING:
            case STATE_DOWNLOADING:
            case STATE_INSTALLING:
            case STATE_INSTALLED:
            case STATE_PURCHASE_ERROR:
            case STATE_UPDATE_AVAILABLE:
            case STATE_DOWNLOADED:
            case STATE_PAID_UPGRADE_REQUIRED:
	            installed = true;
                break;
            default:
	            installed = false;
        }

        return installed;

    }

    function isFilebundleInstalledOnTheDevice(contentId, filebundleId) {
    	var deviceContent = getDeviceContentFromCookieById(contentId);
    	if(deviceContent == null) {
	    	return false;
    	}
    	
    	var contentInstalled = false;
        switch(deviceContent.state){
            case STATE_DISCOVERED:
            case STATE_PURCHASING:
            case STATE_DOWNLOADING:
            case STATE_INSTALLING:
            case STATE_INSTALLED:
            case STATE_PURCHASE_ERROR:
            case STATE_UPDATE_AVAILABLE:
            case STATE_DOWNLOADED:
            case STATE_PAID_UPGRADE_REQUIRED:
            	contentInstalled = true;
                break;
            default:
            	contentInstalled = false;
        } 

        if(!contentInstalled) {
        	return false;
        }
        
        if(deviceContent.installedFileBundle == filebundleId) {
        	return true;
        } else {
        	return false;
        }
    }

    var connectionListeners=new Array();
    var disconnectionListeners=new Array();
    var stateListeners=new Array();
    var javaloaderConnectionListeners=new Array();
    var rebootingListeners=new Array();
    var clientinstallListeners=new Array();
    var deviceUpdateListeners=new Array();
    var asyncErrorListeners=new Array();
    var asyncMsgFailListeners=new Array();
    var deviceUpdateFailListeners=new Array();
    var deviceChangeListeners=new Array();
    var deviceUpdateFailMCCListeners=new Array();
    var uiDeviceSwitchListeners=new Array();
    var subCancelOk=new Array();
    var subCancelFail=new Array();
    var clientUpdateAvail=new Array();
    
    function registerForConnectionEvent(method, event){
    	//connection event
    	if (event === DEVICE_CONNECTION_EVENT){
    		connectionListeners[connectionListeners.length]=method;
    	}
    	//disconnection event
    	else if(event === DEVICE_DISCONNECTION_EVENT){
    		disconnectionListeners[disconnectionListeners.length]=method;
    	}
    	//state change event
    	else if(event === DEVICE_STATE_CHANGE_EVENT){
    		stateListeners[stateListeners.length]=method;
    	}
    	else if(event === DEVICE_JAVALOADER_CONNECTION_EVENT){
    		javaloaderConnectionListeners[javaloaderConnectionListeners.length]=method;
    	}
    	else if(event === DEVICE_REBOOT_DETECTED){
    		rebootingListeners[rebootingListeners.length]=method;
    	}
    	else if(event === DEVICE_CLIENT_INSTALL_REQUESTED){
    		clientinstallListeners[clientinstallListeners.length]=method;
    	}
    	else if(event === DEVICE_UPDATE_COMPLETE){
    		deviceUpdateListeners[deviceUpdateListeners.length]=method;
    	}   
    	else if(event === DEVICE_UPDATE_FAIL){
    		deviceUpdateFailListeners[deviceUpdateFailListeners.length]=method;
    	}
    	else if(event === DEVICE_CHANGE_COMPLETE){
    		deviceChangeListeners[deviceChangeListeners.length]=method;
    	}
    	else if(event === DEVICE_DISCONNECTED_DURING_ASYNC_MESSAGE){
    		asyncErrorListeners[asyncErrorListeners.length]=method;
    	}
    	else if(event === DEVICE_ASYNCE_MESSAGE_FAILURE){
    		asyncMsgFailListeners[asyncMsgFailListeners.length]=method;
    	}
    	else if(event === DEVICE_UPDATE_FAIL_MCC){
    		deviceUpdateFailMCCListeners[deviceUpdateFailMCCListeners.length]=method;
    	}
    	else if(event === UI_DEVICE_SWITCH){
    		uiDeviceSwitchListeners[uiDeviceSwitchListeners.length]=method;
    	}else if(event === SUBSCRIPTION_CANCEL_OK){
    		subCancelOk[subCancelOk.length]=method;
    	}
    	else if(event === SUBSCRIPTION_CANCEL_FAIL){
    		subCancelFail[subCancelFail.length]=method;
    	}
    	else if(event === DEVICE_CLIENT_UPDATE_AVAILABLE){
    		clientUpdateAvail[clientUpdateAvail.length]=method;
    	}
    }
    
    function notifyListeners(event){
    	//connection event
    	if (event === DEVICE_CONNECTION_EVENT){
    		var ita=0;
    		for (ita=0; ita<connectionListeners.length; ita++){
    			if(connectionListeners[ita]())
    				return true;
    		}
    	}
    	//disconnection event
    	else if(event === DEVICE_DISCONNECTION_EVENT){
    		var itb=0;
    		for (itb=0; itb<disconnectionListeners.length; itb++){
    			if(disconnectionListeners[itb]())
    				return true;
    		}
    	} else if(event === DEVICE_STATE_CHANGE_EVENT){
    		var itc=0;
    		for (itc=0; itc<stateListeners.length; itc++){
    			if(stateListeners[itc]())
    				return true;
    		}
    	}else if(event === DEVICE_JAVALOADER_CONNECTION_EVENT){
    		var itd=0;
    		for (itd=0; itd<javaloaderConnectionListeners.length; itd++){
    			if(javaloaderConnectionListeners[itd]())
    				return true;
    		}
    	}
    	else if(event === DEVICE_REBOOT_DETECTED){
    		var ite=0;
    		for (ite=0; ite<rebootingListeners.length; ite++){
    			if(rebootingListeners[ite]())
    				return true;
    		}
    	}
    	else if(event === DEVICE_CLIENT_INSTALL_REQUESTED){
    		var itf=0;
    		for (itf=0; itf<clientinstallListeners.length; itf++){
    			if(clientinstallListeners[itf]())
    				return true;
    		}
    	}
    	else if(event === DEVICE_UPDATE_COMPLETE){
    		var ija=0;
    		for (ija=0; ija<deviceUpdateListeners.length; ija++){
    			if(deviceUpdateListeners[ija]())
    				return true;
    		}
    	}
    	else if(event === DEVICE_UPDATE_FAIL){
    		var itg=0;
    		for (itg=0; itg<deviceUpdateFailListeners.length; itg++){
    			if(deviceUpdateFailListeners[itg]())
    				return true;
    		}
    	}
    	else if(event === DEVICE_CHANGE_COMPLETE){
    		var ith=0;
    		for (ith=0; ith<deviceChangeListeners.length; ith++){
    			if(deviceChangeListeners[ith]())
    				return true;
    		}
    	}
    	else if(event === DEVICE_DISCONNECTED_DURING_ASYNC_MESSAGE){
    		var iti=0;
    		for (iti=0; iti<asyncErrorListeners.length; iti++){
    			if(asyncErrorListeners[iti]())
    				return true;
    		}
    	}
    	else if(event === DEVICE_ASYNCE_MESSAGE_FAILURE){
    		var itj=0;
    		for (itj=0; itj<asyncMsgFailListeners.length; itj++){
    			if(asyncMsgFailListeners[itj]())
    				return true;
    		}
    	}
    	else if(event === DEVICE_UPDATE_FAIL_MCC){
    		var itk=0;
    		for (itk=0; itk<deviceUpdateFailMCCListeners.length; itk++){
    			if(deviceUpdateFailMCCListeners[itk]())
    				return true;
    		}
    	}else if(event === UI_DEVICE_SWITCH){
    		var itl=0;
    		for (itl=0; itl<uiDeviceSwitchListeners.length; itl++){
    			if(uiDeviceSwitchListeners[itl]())
    				return true;
    		}
    	}else if(event === SUBSCRIPTION_CANCEL_OK){
    		var sco=0;
    		for (sco=0; sco<subCancelOk.length; sco++){
    			if(subCancelOk[sco]())
    				return true;
    		}
    	}else if(event === SUBSCRIPTION_CANCEL_FAIL){
    		var scf=0;
    		for (scf=0; scf<subCancelFail.length; scf++){
    			if(subCancelFail[scf]())
    				return true;
    		}
    	}else if(event === DEVICE_CLIENT_UPDATE_AVAILABLE){
    		var cua=0;
    		for (cua=0; cua<clientUpdateAvail.length;cua++){
    			if(clientUpdateAvail[cua]())
    				return true;
    		}
    	}
    }
    
    
    


	function verifyVersion(clientVersionString, minClientVersionString, falseifequal){
		var clientDelimiter = ".";
		var minDelimiter = ".";
		
		if(clientVersionString.indexOf(".") < 0){
			clientDelimiter = ",";
		}
		
		if(minClientVersionString.indexOf(".") < 0){
			minDelimiter = ",";
		}
		
		if(minClientVersionString.split(minDelimiter).length == 3){
			minClientVersionString += minDelimiter + "0";
		}
		
		if (minClientVersionString.split(minDelimiter).length != 4){
			return true;
		}
		if (clientVersionString.split(clientDelimiter).length == 3){
			clientVersionString += clientDelimiter + "0";
		}
		
		var clientVersion =new VersionContainer(clientVersionString, clientDelimiter);
		var minClientVersion = new VersionContainer(minClientVersionString, minDelimiter);
		
		if (clientVersion.major != minClientVersion.major){
			return (clientVersion.major > minClientVersion.major);
		}else {
			if (clientVersion.minor != minClientVersion.minor){
				return (clientVersion.minor > minClientVersion.minor);
			}else {
				if (clientVersion.patch != minClientVersion.patch){
					return (clientVersion.patch > minClientVersion.patch);
				}else {
					if (falseifequal === true){
						return (clientVersion.bundle > minClientVersion.bundle);
					}else{
						return (clientVersion.bundle >= minClientVersion.bundle);
					}
					
				}
			}
		}	
	}
	
	function VersionContainer(version, delimiter){
		if(delimiter == null || delimiter == undefined){
				delimiter = ".";
		}
		var versionArray = version.split(delimiter);
		
		this.major=parseInt(versionArray[0]);
		this.minor=parseInt(versionArray[1]);
		this.patch=parseInt(versionArray[2]);
		this.bundle=parseInt(versionArray[3]);
	}

	
	function getITPolicyObject(awp){
		 var infoRequest = "1;";
		 var results;
		 var response;
		 results = awp.sendMessage( infoRequest );
		 if( results.errorCode == AWP_ERROR_NONE){
		  	response = parseInfoMessage1(results.response);
		 }else{
	    	return null;
		 }
		 var itp = new IT_Policy(response['itp_aw_allowed'], response['itp_third_party_apps_allowed'], response['itp_no_purchasing'],response['itp_carrier_billing'],
	     response['itp_app_restriction_rule'],response['itp_app_restriction_list'], 
		 response['itp_cat_restriction_rule'],response['itp_cat_restriction_list'] );
		 return itp;
	}
	var RESTRICTION_TYPE_DENY="2";
	RESTRICTION_TYPE_ALLOW="1";
	RESTRICTION_TYPE_NONE="0";
	//IT Policy object creation
	
	function IT_Policy(use_AW, thirdPartAppsAllowed, usePurchasing, useCarrierBilling,
			appRestrictionRule, appRestrictionList, catRestrictionRule, catRestrictionList){
		if (use_AW === "true"){
			this.useAW=true;
		}else{
			this.useAW=false;
		}
		
		if (thirdPartAppsAllowed === "true"){
			this.thirdPartAppsAllowed=true;
		}else{
			this.thirdPartAppsAllowed=false;
		}
		
		//usePurchasing param comming in is actually "no_purchasing" so true means cannot purchase...i convert so it makes sense
		if (usePurchasing === "true"){
			this.usePurchasing=false;
		}else{
			this.usePurchasing=true;
		}
		
		if (useCarrierBilling === "true"){
			this.useCarrierBilling=true;
		}else{
			this.useCarrierBilling=false;
		}
		
		this.appRestrictionRule=appRestrictionRule;
		if (this.appRestrictionRule != "0" && appRestrictionRule != undefined){
			this.appRestrictionList=appRestrictionList.split(",");
		}
		this.catRestrictionRule=catRestrictionRule;
		if (this.catRestrictionRule != "0" && catRestrictionRule != undefined){
			this.catRestrictionList=catRestrictionList.split(",");
		}
	}
	
	function validateSubscribeVersion(){
		if (!getAwpGlobalObject().isDeviceAuthenticated()){
			return SUB_DEVICE_NOT_CONNECTED;
		}		
		var minSubscribeVersion='3.0.0.0';
		var response=getAwpGlobalObject().getDeviceInfo();
		//if (!verifyVersion(response['appworld_version'], minSubscribeVersion, false)){
		if (!verifyVersion(response['appworld_version'], minSubscribeVersion, false)){
			 return SUB_UPGRADE_REQUIRED;
		}	
		return SUB_SUBSCRIBE_SUPPORTED;
	}
	
	function isAppDownloadable(awp, contentid, categoryTreeArray){
		var itp = getITPolicyObject(awp);
		
		if (!itp.useAW){
			return false;
		}
		
		if (appRestrictionListContainsContentId(itp.appRestrictionList , contentid)){
			if (itp.appRestrictionRule === RESTRICTION_TYPE_DENY){
				return false;
			}
		}
		else{
			if (itp.appRestrictionRule === RESTRICTION_TYPE_ALLOW){
				return false;
			}
		}
		
		//app not restricted - check category restrictions
		var found=false;
		for (var i = 0; i<categoryTreeArray.length; i++){
			//check all ids and parent ids to see if it is blocked
			if (contains(itp.catRestrictionList, categoryTreeArray[i])){
				if (catRestrictionRule === RESTRICTION_TYPE.DENY){
					return false;
				}else{
					found=true;
				}
			}
		}
		if (itp.catRestrictionRule === RESTRICTION_TYPE_ALLOW && !found){
			return false;
		}
		
		return true;
		
	}
	
	 function parseInfoMessage1(results){

	    	var response = new Array();
	    	
	        var mySplitResult = results.split("&");

	        for(i = 0; i < mySplitResult.length; i++){
	              try{
	                    var keyval = mySplitResult[i].split("="); 
	                    response[keyval[0]] = keyval[1];
	              }catch(err){
	              }
	        }
	        return response;
	    }
	
	 function contains(a, obj) {
		 if (a == undefined || obj == undefined){
			 return false;
		 }
		  var i = a.length; 
		  while (i--) { 
		    if (a[i] === obj+"") { 
		      return true; 
		    } 
		  } 
		  return false; 
		} 

	function appRestrictionListContainsContentId(appRestrictionList, contentId) {
		if (appRestrictionList == undefined || contentId == undefined){
			return false;
		}
		var listParts = decodeURI(appRestrictionList).replace(/%2C/g, ',').split(',');
		var i = 0;
		while (i < listParts.length){
			if (listParts[i] == contentId){
				return true;
			}
			i++;
		}
		return false; 
	} 
	 
	 
	 //odds and ends helper methods
	 
	 function isPinInDeviceList(pin, devices){
			
			for (i=0; i < devices.length; i++){
				if (devices[i].toString(16).toLowerCase() === pin.toLowerCase()){
					return true;
				}
			}
			return false;
		}
	 
	 function awsleep(ms)
		{
			var startdate = new Date();
			var currDate = null;
			do { currDate = new Date(); }
			while(currDate-startdate < ms);
		}
	 
	 var pluginReloadIntervalMs = 1000;
		
	function reloadPlugin(){
		if(pluginInstalled)
		{
			return;
		}
		
		navigator.plugins.refresh();
		
		if(isExplorer)
		{
			var oldPlugin = document.getElementById("AppWorldPlugin");
	        if (null != oldPlugin) {
	            try {
	                document.body.removeChild(oldPlugin.parentElement);
	            }
	            catch (e) {
	            }
	        }
	
	        var embed = document.createElement('div');
	        embed.setAttribute('class', 'IEPluginHide');
	        embed.innerHTML = '<OBJECT ID="AppWorldPlugin" CLASSID="CLSID:DFA53383-9C58-4D19-B94E-5CC725BCEFD8"></OBJECT>';
	        document.body.appendChild(embed);
	        
	        awp_ds = document.getElementById("AppWorldPlugin");
	        
	        version = awp_ds.pluginVersion;
	        
	        if (null == version) {
	            pluginInstalled = false;
	        }
	        else {
	            pluginInstalled = true;
	            
	            window.location.reload();
	        }
		}
		else
		{
			var oldPlugin = document.getElementById("AppWorldPlugin");
			if(null != oldPlugin){
				document.body.removeChild(oldPlugin);
			}
			
			for(i=0;i<navigator.plugins.length;i++){
				if(navigator.plugins[i].name == "BlackBerry AppWorld")
				{
					pluginInstalled = true;
					
					var embed = document.createElement('embed');
					embed.setAttribute('id', 'AppWorldPlugin');
         		embed.setAttribute('type', 'application/x-blackberry-appworld');
         		embed.setAttribute('width', 0);
         		embed.setAttribute('height', 0);
         
         		document.body.appendChild(embed);
         		
         		awp_ds = document.getElementById("AppWorldPlugin");
         		awp_ds.deviceChange = deviceListChanged;
        			awp_ds.stateChange = pluginStateChanged;
        			
        			break;
        		}
        	}
		}
		
		if(pluginInstalled)
		{
			setAwpGlobalObject(new _awp_global_object(awp_ds));
			updateConnectionData();
			plugin_entry_point();
		}
		else
		{
			setTimeout("reloadPlugin()", pluginReloadIntervalMs);
		}
	}
	 

