var csdversion = "3,6,5011,0";
csdversion = csdversion.replace(/,/g, '.');
var iStatus = 0;
var funcFinish = null;
var timeWaitStart;
var agt = navigator.userAgent.toLowerCase();
var IsLinux32 = ( ( agt.indexOf("linux i686") != -1) );
var IsLinux64 = ( ( agt.indexOf("linux x86_64") != -1) );
var IsPowerPcMacOsX = ( ( agt.indexOf("ppc mac os x") != -1) ||
                        ( agt.indexOf("mac_powerpc") != -1) );
var IsIntelMacOsX = ( ( agt.indexOf("intel mac os x") != -1) );
var IsWinCE = ( ( agt.indexOf("windows ce") != -1) ||
                ( agt.indexOf("windows phone") != -1) );
var IsWin2kXpVista = ( (agt.indexOf( "windows nt 5") != -1) ||
                       (agt.indexOf( "windows nt 6") != -1) ||
                       (agt.indexOf( "windows nt 10") != -1) );
var IsIE = ( ( agt.indexOf( "msie" ) != -1 || ( agt.indexOf( "trident" ) != -1 )) && ( agt.indexOf( "opera" ) == -1 ) );
var IsIEandNot2k = ( IsIE && ( agt.indexOf( "windows nt 5.0") == -1 )
                     && !IsPowerPcMacOsX && !IsIntelMacOsX );
var IsIE64 = ( ( agt.indexOf( "win64" ) != -1 ) && ( agt.indexOf( "x64" ) != -1 ) );
var bLoop = false;
var language = 0;

var stToken = "";
var stTicket = "";
var stCertHash = "";
var tGroup = "";

var bLoop = false;
var isAppletRunning = false;
var isJavaInstalled = false;
var appletCookieName = "hsJavaApplet";
var appletCookieValue = "61560";

// 0 = initial value
// 1 = ActiveX/Java has started to run
// 2 = CSD stub launched
// 3 = CSD stub terminated and reported success
// Any new status codes used just between the JavaScript and ActiveX/Java
// must be positive values defined in both the ActiveX/Java and Javascript.
//
var STATUS_INITIAL_VALUE         = 0;
var STATUS_STARTED               = 1;
var STATUS_STUB_IN_PROGRESS      = 2;
var STATUS_STUB_SUCCESS          = 3;

var str_STATUS_INITIAL_VALUE     = "0";
var str_STATUS_STARTED           = "1";
var str_STATUS_STUB_IN_PROGRESS  = "2";
var str_STATUS_STUB_SUCCESS      = "3";

// All negative values are a 1 to 1 match to CSD stub exit codes where only
// The downloader exit codes are defined in main.c.
//
var STATUS_STUB_FAILURE                = -1;
var STATUS_STUB_REBOOT_REQUIRED        = -2;
var STATUS_STUB_PRELOGIN_FAILURE       = -3;

var str_STATUS_STUB_FAILURE            = "-1";
var str_STATUS_STUB_REBOOT_REQUIRED    = "-2";
var str_STATUS_STUB_PRELOGIN_FAILURE   = "-3";

// errorCodes to translated and reported on STATUS_STUB_FAILURE
var ERROR_UNKNOWN                          = 0;
var ERROR_CODING_ERROR                     = -1;
var ERROR_RELAUNCH_FAILED                  = -2;
var ERROR_RELAUNCH_AS_ADMIN_FAILED         = -3;
var ERROR_PARAMETER_CONVERSION_FAILED      = -4;
var ERROR_CURR_WORKING_DIR_INIT_FAILED     = -5;
var ERROR_HOSTSCAN_PATH_INIT_FAILED        = -6;
var ERROR_LOG_INIT_FAILED                  = -7;
var ERROR_TRANSPORT_INIT_FAILED            = -8;
var ERROR_UPDATE_INIT_FAILED               = -9;
var ERROR_PEER_DETERMINATION_FAILED        = -10;
var ERROR_LOCATING_LIBXML_FAILED           = -11;
var ERROR_LOCATING_LIBCSD_FAILED           = -12;
var ERROR_INITIALIZING_LIBCSD_FAILED       = -13;
var ERROR_PRELOGIN_FAILED                  = -14;
var ERROR_RUN_FAILED                       = -15;
var ERROR_DETACH_FAILED                    = -16;
var ERROR_TIMEOUT                          = -20;
var ERROR_DENY_ACCESS                      = -21;

var str_ERROR_UNKNOWN                          = "0";
var str_ERROR_CODING_ERROR                     = "-1";
var str_ERROR_RELAUNCH_FAILED                  = "-2";
var str_ERROR_RELAUNCH_AS_ADMIN_FAILED         = "-3";
var str_ERROR_PARAMETER_CONVERSION_FAILED      = "-4";
var str_ERROR_CURR_WORKING_DIR_INIT_FAILED     = "-5";
var str_ERROR_HOSTSCAN_PATH_INIT_FAILED        = "-6";
var str_ERROR_LOG_INIT_FAILED                  = "-7";
var str_ERROR_TRANSPORT_INIT_FAILED            = "-8";
var str_ERROR_UPDATE_INIT_FAILED               = "-9";
var str_ERROR_PEER_DETERMINATION_FAILED        = "-10";
var str_ERROR_LOCATING_LIBXML_FAILED           = "-11";
var str_ERROR_LOCATING_LIBCSD_FAILED           = "-12";
var str_ERROR_INITIALIZING_LIBCSD_FAILED       = "-13";
var str_ERROR_PRELOGIN_FAILED                  = "-14";
var str_ERROR_RUN_FAILED                       = "-15";
var str_ERROR_DETACH_FAILED                    = "-16";
var str_ERROR_TIMEOUT                          = "-20";
var str_ERROR_DENY_ACCESS                      = "-21";

var errorCode;

// Number of times to wait in prompt states before attempting next
// installation mechanism.  State is evaluated every 500 milliseconds,
var timeout_count = 120;

var stDownloadURL = window.location.href;

var http_request = false;

var using_hs_applet     = false;
// These two variables are updated by HS applet 
var hs_js_var_errorcode = "";
var hs_js_var_status    = "";


function getStubStatus() 
{
    if( using_hs_applet && !( IsIE64 || IsIE ) && undefined != document.applets['idJavaSun'] )
    {
        if ( undefined != document.applets['idJavaSun'].status )
        {
            return document.applets['idJavaSun'].status;
        }

        if( "" != hs_js_var_status )
        {
            return hs_js_var_status;
        }
    }
    //if function doesn't return anything, undefined would be returned by default.
    //Even then be explicit
    return undefined;
}

function getStubErrorCode() 
{
    if( using_hs_applet && !( IsIE64 || IsIE )  && undefined != document.applets['idJavaSun'] )
    {
        if ( undefined != document.applets['idJavaSun'].errorcode )
        {
           return document.applets['idJavaSun'].errorcode;
        }

        if( "" != hs_js_var_errorcode )
        {
           return hs_js_var_errorcode;
        }
    }
    //if function doesn't return anything, undefined would be returned by default.
    //Even then be explicit
    return undefined;
}

/**** xmlextras.js - taken from http://webfx.eae.net/dhtml/xmlextras/xmlextras.html ****/

function getXmlHttpPrefix() 
{
    if (getXmlHttpPrefix.prefix)
        return getXmlHttpPrefix.prefix;

    var prefixes = ["Microsoft", "MSXML", "MSXML2", "MSXML3"];
    var o;
    for (var i = 0; i < prefixes.length; i++) 
    {
        try 
        {
            // try to create the objects
            o = new ActiveXObject(prefixes[i] + ".XmlHttp");
            return getXmlHttpPrefix.prefix = prefixes[i];
        }
        catch (ex)
        {
            // move on to next parser
        }
    }
    throw new Error("Could not find an installed XML parser");
}

function XmlHttp() 
{
}

XmlHttp.create = function ()
{
    var req = null;
    try 
    {
        if (window.XMLHttpRequest) 
        {
            // code for IE7, Firefox, Opera, etc.
            req = new window.XMLHttpRequest();

            // some versions of Moz do not support the readyState property
            // and the onreadystate event so we patch it!
            if (req.readyState == null) 
            {
                req.readyState = 1;
                req.addEventListener("load", function () 
                {
                    req.readyState = 4;
                    if (typeof req.onreadystatechange == "function")
                        req.onreadystatechange();
                }, false);
            }

            return req;
        } 
        else if (window.ActiveXObject) 
        {
            // code for IE6, IE5
            return new ActiveXObject(getXmlHttpPrefix() + ".XMLHTTP");
        }

        if (req == null)
        {
            alert("Your browser does not support XMLHTTP.");
        }
    }
    catch (ex)
    {
        alert("Your browser does not support XMLHTTP.");
    }
    // fell through
    return null;
};


function CsdLogout (reason)
{
    // goto <prefix>/logout
    if ( reason == null || reason == "" )
    {
        reason = "1";
    }

    top.location.href = "/+CSCOE+/logout.html?reason=" + reason;
}


function HelpButtonHide(helpButtonState)
{
    if (helpButtonState)
    {
        GetElement("helpButton").style.visibility = "hidden";
    }
}

function DownloadButtonDisable(downloadButtonState)
{
    GetElement("manualInstallButton").disabled = downloadButtonState;
}

function DownloadButtonHide(downloadButtonState)
{
    if (downloadButtonState)
    {
        GetElement("helpButton").style.visibility = "hidden";
    }
}

//-----------------------------------------




function ReconnectBrowser()
{
    //TODO: CE?
    //if ( IsLinux || IsPowerPcMacOsX || IsIntelMacOsX || IsWin2kXpVista || IsWinCE )
    if ( IsLinux32 || IsLinux64 || IsPowerPcMacOsX || IsIntelMacOsX || IsWin2kXpVista )
    {
        //For supported platforms.
        setTimeout ("CsdLogout(11)", 180 * 60 * 1000);    // 180 minutes timeout to be in sync with everything else
        if( checkStatus () == false)
        {
            CsdLogout(1);
        }
    }
    //TODO: CHECK on all platforms
    else
    {
        //Unsupported environment for CSD launch, but supports XMLHTTP.
        setCookie ("sdesktop", stToken);
        //TODO: Check if ce required
        //document.location = "/+CSCOE+/sdesktop/wait.html?group=" + tGroup + "&firstinstance=1&ce=1";
        document.location = "/+CSCOE+/sdesktop/wait.html?group=" + tGroup + "&firstinstance=1";
    }
}


function waitNotify ()
{
    if (http_request.readyState == 4) 
    {
        if (http_request.status == 200 ) 
        {
            try 
            {
                switch(http_request.getResponseHeader("csdgo")) 
                {
                    case "1":
                        CsdLogout(8);
                    break;
                    case "2":
                    if ((tGroup) && (tGroup != "")) 
                    {
                        top.location.href =  "/+CSCOE+/logon.html?tg=" + tGroup + "&token=" + stToken;
                    } 
                    else 
                    {
                        top.location.href =  "/+CSCOE+/logon.html?token=" + stToken;
                    }
                    break;
                    case "3":
                        top.location.href = "/+webvpn+/index.html"
                    break;
                    case "4":
                        CsdLogout(9);
                    break;
                    case "5":
                        // error handling
                        err = http_request.getResponseHeader("csderror");
                        switch (err) 
                        {
                            case "1":
                                // CacheCleaner already running
                                CsdLogout(15);
                            break;
                            case "2":
                                // SecureDesktop already running
                                CsdLogout(16);
                            break;
                            case "3":
                                // Keystroke logger found
                                CsdLogout(17);
                            break;
                            case "4":
                                // Emulation logger found
                                CsdLogout(19);
                            break;
                            default:
                                // Unknown error
                                CsdLogout(14);
                        }
                    break;
                    default:
                        setTimeout("checkStatus()", 1000);
                    break;
                }
            } 
            catch (e) 
            {
               setTimeout("checkStatus()", 1000);
            }
        } 
        else 
        {
           setTimeout("checkStatus()", 1000);
        }
    }
}

function checkStatus ()
{
    if (window.XMLHttpRequest)
    {
        // code for all new browsers
        http_request = new window.XMLHttpRequest();
        
        // some versions of Moz do not support the readyState property
        // and the onreadystate event so we patch it!
        if (http_request.readyState == null) 
        {
            http_request.readyState = 1;
            http_request.addEventListener("load", 
                function () 
                {
                    http_request.readyState = 4;
                    if (typeof http_request.onreadystatechange == "function")
                        http_request.onreadystatechange();
                }, 
                false);
        }
        
        if (http_request.overrideMimeType)
        {
            http_request.overrideMimeType('text/plain');
        }
    } 
    else if (window.ActiveXObject)
    {
        // code for IE5 and IE6
        var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
        for (var i = 0; i < prefixes.length; i++) 
        {
            try 
            {
                // try to create an object
                http_request = new ActiveXObject(prefixes[i] + ".XMLHTTP");
                // will hit break only if above line succeeds.
                break;
            }
            catch (ex)
            {
                // move on to next parser
            }
        }
    }

    var path = "/+CSCOE+/sdesktop/wait.html?group=" + tGroup + "&firstinstance=1&token=" + stToken;

    if (!http_request) 
    {
        alert("Your browser does not support XMLHTTP.");
        return false;
    }
    http_request.open('GET', path, true);
    http_request.onreadystatechange = waitNotify;
    http_request.send(null);
}

function suspicious_url()
{
    
    susp_str_arr = new Array("<", ">", "(", ")");
    
    url = window.location.href.toLowerCase();
    decoded_url = decodeURIComponent(url);
    
    for (i = 0; i < susp_str_arr.length; i++)
    {
        if ( url.indexOf(susp_str_arr[i].toLowerCase()) >= 0 || 
                decoded_url.indexOf(susp_str_arr[i].toLowerCase()) >= 0 )
        {
            return true;
        }
    }
    
    return false;
}


//0 Wait for start
//1 Let's start
//10 Download OCX
//11 OCX Security
//12 Check OCX status + setup OCX
//13 OCX started. OCX success?
//14 OCX launched CSD stub
//15 OCX failed
//16 Second-stage ActiveX notification and timeout
//20 Try detecting Java (or launch applet directly for IE)
//22 Java not present or detected ... show message and wait 10 seconds before manual page
//41 Launch Java (VM Sun/Oracle) success?
//42 Launching install from Java (VM Sun/Oracle)
//43 Install launched from Java (VM Sun/Oracle).
//44 Java (VM Sun/Oracle) failed
//55 IE 64 bit detected.
//-70 Manual Download
//-80 Disallow Access (prelogin failure only)
//-81 Reboot required
//-90 Can't parse XML. Critical failure
//-100 Connection Established
//-101 Unsupported platform. CSD bypass
// -111 Suspiscious URL

function Start( iStatusf )
{
    // Check if the url has aspects that are expected not to be present
    if ( suspicious_url() == true )
    {
        iStatus = -111;
    }
    else
    {
        iStatus = iStatusf;
        bLoop = true;
        language = 0;

        var group;
        if (group = getCookie('tg')) 
        {
            tGroup = escape(group.substring(1));
        }

        if (!load_token_xml()) 
        {
            iStatus = -90;
        }
    }
    
    Launch();
}

function GetElement (idTag)
{
    var elem;
    if ( document.all )
    {
        elem = eval("document.all." + idTag);
    }
    else
    {
        elem = document.getElementById(idTag);
    }
    return elem;
}

var oldPhaseState = "1";
function AdvancePhase (description)
{
    var state = Math.abs(iStatus);
    CompletePhase(oldPhaseState);

    GetElement("state" + state + "no").className = "cuesWizardStepSelectedNo";
    GetElement("state" + state + "dash").className = "cuesWizardStepSelectedDash";
    GetElement("state" + state + "phase").className = "cuesWizardStepSelected";
    
    oldPhaseState = state;

    GetElement("cuesWizardStepTitle").innerHTML = description;
}


function CompletePhase (phaseState)
{
    if (typeof phaseState != "undefined")
    {
        GetElement("state" + phaseState + "check").checked = "true";
        GetElement("state" + phaseState + "no").className = "cuesWizardStepCompletedNo";
        GetElement("state" + phaseState + "dash").className = "cuesWizardStepCompletedDash";
        GetElement("state" + phaseState + "phase").className = "cuesWizardStepCompleted";
    }
}


function updateMessage()
{
    if ( document.all )
        document.all.idDivMessage.innerHTML = aszMessage[language][ Math.abs( iStatus ) ];
    else
        document.getElementById( "idDivMessage" ).innerHTML = aszMessage[language][ Math.abs( iStatus ) ];
}


function DeleteCookie (name) 
{
	/*All cookies from the applet(s) are set with path=/
	 * if for some reason we need to change the path, 
	 * make sure it is changed in this function as well
	 * or, set it as a parameter */
	if (getCookie(name)) 
	{
		document.cookie = name + "=" +
						"; path=/" + 
						"" +
						"; expires=Thu, 01-Jan-70 00:00:01 GMT";
	}
}


function getCookie(name) 
{
    var dc = document.cookie;
    var prefix = name + "=";
    var begin = dc.indexOf("; " + prefix);
    if (begin == -1) 
    {
        begin = dc.indexOf(prefix);
        if (begin != 0) return null;
    } else {
        begin += 2;
    }
    var end = document.cookie.indexOf(";", begin);
    if (end == -1) 
    {
        end = dc.length;
    }
    return unescape(dc.substring(begin + prefix.length, end));
}

function getLangsel() 
{
    var langsel = getCookie("webvpnLang");
    if ((langsel == null) || (langsel == ""))
    {
        langsel = "en-us";
    }
    return langsel;
}

function translatemessages()
{
    var e;
    try 
    {
        var msgs = "";
        for (var i = 0; i < aszMessage[language].length; i++) 
        {
            if (typeof aszMessage[language][i] != 'undefined') 
            {
                msgs += aszMessage[language][i] + "\n";
            }
        }
        
        if (window.XMLHttpRequest)
        {
            // code for all new browsers
            http_request = new window.XMLHttpRequest();
            
            // some versions of Moz do not support the readyState property
            // and the onreadystate event so we patch it!
            if (http_request.readyState == null) 
            {
                http_request.readyState = 1;
                http_request.addEventListener("load", 
                    function () 
                    {
                        http_request.readyState = 4;
                        if (typeof http_request.onreadystatechange == "function")
                            http_request.onreadystatechange();
                    }, 
                    false);
            }
            
            if (http_request.overrideMimeType)
            {
                http_request.overrideMimeType('text/plain');
            }
        } 
        else if (window.ActiveXObject)
        {
            // code for IE5 and IE6
            var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
            for (var i = 0; i < prefixes.length; i++) 
            {
                try 
                {
                    // try to create an object
                    http_request = new ActiveXObject(prefixes[i] + ".XMLHTTP");
                    // will hit break only if above line succeeds.
                    break;
                }
                catch (ex)
                {
                    // move on to next parser
                }
            }
        }
        
        var path = "/+CSCOT+/translation?textdomain=csd&prefix=trans&lang=" + getLangsel();
        if (http_request)
        {
            http_request.open('POST', path, false);
            http_request.send(msgs);
            var trans = new Array();
            try 
            {
                eval(http_request.responseText);
            } 
            catch (e) 
            {
            }
        }
        else
        {
            //Browser does not support XMLHTTP, but we move on.
        }
    }
    catch (e) 
    {
    }
    
    for (var i = 0; i < aszMessage[language].length; i++) 
    {
        if (typeof aszMessage[language][i] != 'undefined')
        {
            try 
            {
                if (typeof trans[aszMessage[language][i]] != 'undefined') 
                {
                    aszMessage[language][i] = trans[aszMessage[language][i]];
                }
            } 
            catch (e) 
            {
            }
        }
    }
    
    e = null;
    
    try 
    {
        var msgs = "";
        for (var i = 0; i < errorMessage[language].length; i++) 
        {
            if (typeof errorMessage[language][i] != 'undefined') 
            {
                msgs += errorMessage[language][i] + "\n";
            }
        }
        
        if (window.XMLHttpRequest)
        {
            // code for all new browsers
            http_request = new window.XMLHttpRequest();
            
            // some versions of Moz do not support the readyState property
            // and the onreadystate event so we patch it!
            if (http_request.readyState == null) 
            {
                http_request.readyState = 1;
                http_request.addEventListener("load", 
                    function () 
                    {
                        http_request.readyState = 4;
                        if (typeof http_request.onreadystatechange == "function")
                            http_request.onreadystatechange();
                    }, 
                    false);
            }
            
            if (http_request.overrideMimeType)
            {
                http_request.overrideMimeType('text/plain');
            }
        } 
        else if (window.ActiveXObject)
        {
            // code for IE5 and IE6
            var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
            for (var i = 0; i < prefixes.length; i++) 
            {
                try 
                {
                    // try to create an object
                    http_request = new ActiveXObject(prefixes[i] + ".XMLHTTP");
                    // will hit break only if above line succeeds.
                    break;
                }
                catch (ex)
                {
                    // move on to next parser
                }
            }
        }
        
        var path = "/+CSCOT+/translation?textdomain=csd&prefix=trans&lang=" + getLangsel();
        if (http_request)
        {
            http_request.open('POST', path, false);
            http_request.send(msgs);
            var trans = new Array();
            try 
            {
                eval(http_request.responseText);
            } 
            catch (e) 
            {
            }
        }
        else
        {
            //Browser does not support XMLHTTP, but we move on.
        }
    }
    catch (e) 
    {
    }
    
    for (var i = 0; i < errorMessage[language].length; i++) 
    {
        if (typeof errorMessage[language][i] != 'undefined')
        {
            try 
            {
                if (typeof trans[errorMessage[language][i]] != 'undefined') 
                {
                    errorMessage[language][i] = trans[errorMessage[language][i]];
                }
            } 
            catch (e) 
            {
            }
        }
    }
}

function addCmdLineArg(str, name, val, space)
{
  if (val != "")
  {
      if (space == true)
      {
        return str + name + " \"" + val + "\"";
      }
      else
      {
        return str + name + val;
      }
  }
  else
  {
      return str;
  }
}

function Launch()
{
    updateMessage();
    switch ( iStatus )
    {
    case 0:
        bLoop = false;
        break;
    case 1:
        if ( IsWin2kXpVista )
        {
            if ( IsIE64 )
                iStatus = 55;
            else if ( IsIE )
                iStatus = 20;
            else
                iStatus = 22;
        }
        else
        {
            // Should never come here, but to be safe
            iStatus = -70;
        }
        break;
    case 20:
        timeout_count = 120; // Increasing timeout from 60 to 120 as JRE8 latest takes more time(>=60secs) to verify HS Applet signature and launch it.
        AdvancePhase("Attempting to use Java for Installation");
        using_hs_applet = false;
        
        DownloadButtonDisable(false);
        if ( ! navigator.javaEnabled() )
            iStatus = 22;
        else
		{ 
        	DownloadButtonDisable(true);
			//As a security, delete the cookie before starting the applet
			DeleteCookie (appletCookieName);
            if( true == suspicious_url() )
            {
                iStatus = -111; /*wrong malicious url */
                break;
            }
            var stDownloadURL = window.location.href;
        	var stContent;
        	if ( IsIE )
        	{
            		stContent = '<html><body><applet id="idJavaSun" name="idJavaSun" width="0" height="0" code="InstallerJava.InstallerJava" archive="binaries/instjava.jar"><param name="url" value="' + stDownloadURL + '"><param name="ticket" value="' + stTicket + '"><param name="stub" value="0"><param name="certhash" value="' + stCertHash + '"><param name="group" value="' + tGroup + '"><param name="version" value="' + csdversion +'" MAYSCRIPT></applet></body></html>';
            document.frames["idiFrameMain"].document.write( stContent );
        	}
        	else
        	{
            		stContent = '<applet id="idJavaSun" name="idJavaSun" width="0" height="0" code="InstallerJava.InstallerJava" archive="binaries/instjava.jar"><param name="url" value="' + stDownloadURL + '"><param name="ticket" value="' + stTicket + '"><param name="stub" value="0"><param name="certhash" value="' + stCertHash + '"><param name="group" value="' + tGroup + '"><param name="version" value="' + csdversion +'" MAYSCRIPT></applet>';
            document.getElementById( "idDivMain" ).innerHTML = stContent;
                using_hs_applet = true;
        	}
        	timeWaitStart = new Date();
        	iStatus = 41;
		}
        break;
    case 22:
        // ActiveX failed, and we have no java :(. Try manual install.
        var timeout_message = "<br/><br/>Continuing in <b>" + Math.ceil(timeout_count / 6) + '</b> seconds [<a href="javascript:Start(-70);">skip</a>].';

        if ( document.all )
            document.all.idDivMessage.innerHTML += timeout_message;
        else
            document.getElementById( "idDivMessage" ).innerHTML += timeout_message;

        timeout_count--;
        if (0 == timeout_count)
        {
            iStatus = -70;
        }
        break;
    case 41:
        try
        {
            var timeWaitNow = new Date();
            if ( timeWaitNow.getTime() - timeWaitStart.getTime() > 120000 )
	    	{
                iStatus = 22;
	    	}
	    	else
	    	{
        		if ( IsIE )
        		{
		    		if(!isAppletRunning)
		    		{
			    		if(getCookie(appletCookieName) == appletCookieValue)
			    		{
			    			isAppletRunning = true;
			    		}
		    		}
		    		else
		    		{
			    		if ( document.frames["idiFrameMain"].document.idJavaSun.status == str_STATUS_STARTED )
				    		iStatus = 42;
			    		else if ( document.frames["idiFrameMain"].document.idJavaSun.status == str_STATUS_STUB_IN_PROGRESS )
				    		iStatus = 43;
			    		else if ( document.frames["idiFrameMain"].document.idJavaSun.status == str_STATUS_STUB_SUCCESS )
				    		iStatus = -100;
			    		else if ( document.frames["idiFrameMain"].document.idJavaSun.status == str_STATUS_STUB_FAILURE )
				    		iStatus = 44;
		
			    		//Delete Cookie once we know that the applet has 'started'
			    		DeleteCookie (appletCookieName);
		    		}
        		}
        		else
        		{
            		// check for applet being loaded and wait for started status
            		// Note: we are not checking explicitly for STATUS_STARTED but checking for undefined in the next state
            		if ( document.applets['idJavaSun'] )
                		iStatus = 42;
            		else
               			iStatus = 44;
        		}
	    	}
		}
        catch(e)
        {
            var timeWaitNow = new Date();
            if ( timeWaitNow.getTime() - timeWaitStart.getTime() > 20000 )
                iStatus = 22;
        }
        break;
    case 42:
        if ( IsIE )
        {
            if ( document.frames["idiFrameMain"].document.idJavaSun.status == str_STATUS_STUB_FAILURE )
                iStatus = 44;
            else if ( document.frames["idiFrameMain"].document.idJavaSun.status == str_STATUS_STUB_IN_PROGRESS )
            {
                //Reset timer start
                timeWaitStart = new Date();
                iStatus = 43;
            }
            else if ( document.frames["idiFrameMain"].document.idJavaSun.status == str_STATUS_STUB_SUCCESS )
                iStatus = -100;
        }
        else
        {
            if ( getStubStatus() == str_STATUS_STUB_FAILURE )
                iStatus = 44;
            else if ( getStubStatus() == str_STATUS_STUB_IN_PROGRESS )
            {
                //Reset timer start
                timeWaitStart = new Date();
                iStatus = 43;
            }
            else if ( getStubStatus() == str_STATUS_STUB_SUCCESS)
                iStatus = -100;
            else if ( String( getStubStatus() ) == 'undefined')
            {
                // will get here if JVM detects a cert validation problem
                // and pops up a dialog asking the user if they want to
                // continue - give them 120 seconds to respond then bail out.
                // Upon timeout, the web page will indicate a failure.  If
                // the security pop-up is still open and then the user allows
                // the Java to run, the Downloader will still run.  If the
                // install and tunnel succeed then there may be some confusion
                // since the web page displays a failure message but the
                // install weas successful and the tunnel is up.  The solution
                // is for the head-end admin to get a real cert!
                var timeWaitNow = new Date();                
                if ( timeWaitNow.getTime() - timeWaitStart.getTime() > 120000 )
                {
                    errorCode = ERROR_DENY_ACCESS;
                    iStatus = 44;
                }
            }
        }
        break;

    case 43:
        if ( IsIE )
        {
            if ( document.frames["idiFrameMain"].document.idJavaSun.status == str_STATUS_STUB_FAILURE )
                iStatus = 44;
            else if ( document.frames["idiFrameMain"].document.idJavaSun.status == str_STATUS_STUB_SUCCESS )
                iStatus = -100;
            else if ( document.frames["idiFrameMain"].document.idJavaSun.status == str_STATUS_STUB_IN_PROGRESS )
            {
                // Can get here cause CSD needs to download on the fly (1st time) and may not be done
                // Give it upto 35 seconds. 
                // Note: This time may have to increase based on download speed and size of CSD stub and library.
                // Also, if we do a native launch in Java, we wait for 30 seconds there. 
                // 5 seconds is a buffer to overcome race issues. In best case, we'll never wait this long.
                var timeWaitNow = new Date();                
                if ( timeWaitNow.getTime() - timeWaitStart.getTime() > 300000 )
                {
                    errorCode = ERROR_TIMEOUT;
                    iStatus = 44;                
                }
            }
        }
        else
        {
            if ( getStubStatus() == str_STATUS_STUB_FAILURE)
                iStatus = 44;
            else if ( getStubStatus() == str_STATUS_STUB_SUCCESS)
                iStatus = -100;
            else if ( String( getStubStatus() ) == 'undefined')
                iStatus = 44;
            else if (  getStubStatus() == str_STATUS_STUB_IN_PROGRESS )
            {
                // Can get here cause CSD needs to download on the fly (1st time) and may not be done
                // Give it upto 35 seconds. 
                // Note: This time may have to increase based on download speed and size of CSD stub and library.
                // Also, if we do a native launch in Java, we wait for 30 seconds there. 
                // 5 seconds is a buffer to overcome race issues. In best case, we'll never wait this long.
                var timeWaitNow = new Date();                
                if ( timeWaitNow.getTime() - timeWaitStart.getTime() > 300000 )
                {
                    errorCode = ERROR_TIMEOUT;
                    iStatus = 44;
                }
            }
        }
        break;

    case 44:
        // Sun Java failed.
        send_hostscan_info('endpoint.os.version="' + packagePlatform + '";\nendpoint.feature="failure";');
        
        //Take care of JavaScript denials
        if ( errorCode == ERROR_DENY_ACCESS )
        {
            iStatus = -80;
            break;            
        }
        
        //Populate error code from the applet.
        if ( IsIE )
        {
            if ( String(document.frames["idiFrameMain"].document.idJavaSun.errorcode) != 'undefined')
            {
                errorCode = parseInt(document.frames["idiFrameMain"].document.idJavaSun.errorcode);
            }
            else if ( errorCode != ERROR_TIMEOUT )
            {
                errorCode = ERROR_UNKNOWN;                
            }
        }
        else
        {
            if ( String( getStubErrorCode() ) != 'undefined')
            {
                errorCode = parseInt( getStubErrorCode() );
            }
            else if ( errorCode != ERROR_TIMEOUT )
            {
                errorCode = ERROR_UNKNOWN;
            }
        }
        
        // Any codes to deny login for from CSD?
        // Right now this is only prelogin failure!
        if( errorCode == ERROR_PRELOGIN_FAILED || errorCode == ERROR_DETACH_FAILED )
        {
            iStatus = -80;
        }
        else //give the user an option to login manually
        {
            var timeout_message = "<br/><br/><b>Critical failure.</b><br/><br/>";
            timeout_message += errorMessage[language][Math.abs( errorCode )];
            timeout_message += "<br/><br/>Continuing in <b>" + Math.ceil(timeout_count / 2) + '</b> seconds [<a href="javascript:Start(-70);">skip</a>].';
    
            if ( document.all )
                document.all.idDivMessage.innerHTML += timeout_message;
            else
                document.getElementById( "idDivMessage" ).innerHTML += timeout_message;
    
            timeout_count--;
            if (0 == timeout_count)
            {
                iStatus = -70;
            }
        }
        break;

    case 55:
        DownloadButtonDisable(false);
        // Notify the user they need to use the 32bit IE.
        // Use countdown timer before heading to WebVPN
        var timeout_message = "<br/>Continuing in <b>" + Math.ceil(timeout_count / 2) + "</b> seconds.";

        if ( document.all )
            document.all.idDivMessage.innerHTML += timeout_message;
        else
            document.getElementById( "idDivMessage" ).innerHTML += timeout_message;

        timeout_count--;
        if (0 == timeout_count)
        {
            iStatus = -70;
        }
        break;

    case -70:
        // Terminal state displaying download option.  Do not go to portal.
        // HostScan failed or was aborted
        send_hostscan_info('endpoint.os.version="' + packagePlatform + '";\nendpoint.feature="failure";');
        
        AdvancePhase("WebLaunch");

        var linkText = "";
        
        linkText += "<br/><br/>To proceed, you can use the link below to login. However, your system will not be checked for required policies. As such:";
        linkText += "<ul><li>Corporate policy may prevent or restrict access.</li>";
        linkText += "<li>Some resources may be unavailable.</li></ul>";
        linkText += '<a href="/+CSCOE+/logout.html?reason=12">' + "Log In" + '</a>';

        GetElement("idDivMessage").innerHTML += linkText;
        DownloadButtonDisable(true);
        bLoop = false;
        break;

    case -80:
        //Disallow access.
        AdvancePhase("Access Denied");
        
        var showMessage = "<br/><br/><b>Critical failure.</b><br/><br/>";
        showMessage += errorMessage[language][Math.abs( errorCode )];
        
        if ( document.all )
            document.all.idDivMessage.innerHTML += showMessage;
        else
            document.getElementById( "idDivMessage" ).innerHTML += showMessage;
        
        DownloadButtonHide(true);        
        bLoop = false;
        break;

    case -81:
        //Reboot required
        bLoop = false;
        break;

    case -90:
        /* Critical failure. Cannot parse xml.
         * Cannot proceed!
         */
        AdvancePhase("Critical Error");
        
        DownloadButtonHide(true);
        bloop = false;
        break;

    case -100:
        // Success
        AdvancePhase("System Validated");
        
        var msg = "<br/><br/>" + "Success. Reloading. Please wait..." + "<br/>";
        if ( document.all )
            document.all.idDivMessage.innerHTML += msg;
        else
            document.getElementById( "idDivMessage" ).innerHTML += msg;

        bLoop = false;
        ReconnectBrowser();
        break;


    case -101:
        //Bypass CSD. Reaches here only if XMLHTTP is supported.
        bLoop = false;
        send_hostscan_info('endpoint.os.version="' + packagePlatform + '";\nendpoint.feature="failure";');
        //TODO: Check if ce reqd
        //var stResultURL = "/+CSCOE+/sdesktop/wait.html?ticket=" + stTicket + "&stub=0&ce=1&group=" + tGroup;
        var stResultURL = "/+CSCOE+/sdesktop/wait.html?ticket=" + stTicket + "&stub=0&group=" + tGroup;
        location.href = stResultURL;
        break;
        
    case -111:
        /* 
        ** Suspiscious URL! 
         */
        AdvancePhase("Access Denied");
        
        var showMessage = "<br/><br/>";
        showMessage += errorMessage[language][47];
        
        if ( document.all )
            document.all.idDivMessage.innerHTML += showMessage;
        else
            document.getElementById( "idDivMessage" ).innerHTML += showMessage;
        
        DownloadButtonHide(true);
        bloop = false;
        break;
    }

    if ( bLoop )
        window.setTimeout( 'Launch();', 500 );
}

function get_xml_doc(path) 
{
    for (var retry=0; retry < 3; retry++)
    {
        var xmlhttp = XmlHttp.create();
        if (xmlhttp!=null)
        {
            xmlhttp.open("GET", path, false);
            xmlhttp.send(null);

            if (xmlhttp.status == 200)
            {
                return xmlhttp.responseXML.documentElement;
            }
        }
    }
    return null;
}

function load_token_xml() 
{
    var ex;
    var xmlDoc = get_xml_doc('/+CSCOE+/sdesktop/token.xml');
    if (xmlDoc != null) 
    {
        try 
        {
            stToken = xmlDoc.getElementsByTagName("token")[0].childNodes[0].nodeValue;
            stTicket = xmlDoc.getElementsByTagName("ticket")[0].childNodes[0].nodeValue;
            stCertHash = xmlDoc.getElementsByTagName("server")[0].childNodes[0].nodeValue;
            var stClientCert = xmlDoc.getElementsByTagName("client")[0].childNodes[0].nodeValue;
            if (stClientCert != "") 
            {
                stCertHash = stCertHash + ":" + stClientCert;
            }
        } 
        catch (ex) 
        {
        }
        
        return true;
    }
    return false;
}



function setCookie(name, value) 
{ // use: setCookie("name", value);
    var today = new Date();
    // var expire_date = new Date(today.getTime() + 2 * 24 * 60 * 60 * 1000); // plus 2 days

    if (value != null && value != "")
        document.cookie = name + "=" + escape(value) + "; path=/"; //; expires=" + expire_date.toGMTString();
}

function send_hostscan_info(scaninfo) 
{
    setCookie('sdesktop', stToken);

    var xmlhttp = XmlHttp.create();
    xmlhttp.open("POST", '/+CSCOE+/sdesktop/scan.xml',false);
    xmlhttp.send(scaninfo);
    if (xmlhttp.status == 200) 
    {
        var response = xmlhttp.responseText;
        //doc = xmlhttp.responseXML;
    } else {
        iStatus = 81;
        Launch();
    }
}


