﻿// http://msdn.microsoft.com/msdnmag/code/Default.aspx?level=root%2cscripts&file=Silverlight.js&url=http%3a%2f%2fmsdn.microsoft.com%2fmsdnmag%2fissues%2f08%2f01%2fExtremeASPNET%2fdefault.aspx
var g_agVersion = null;
function detectAgControlVersion(detectionProbe)
{
    var agVersion = "-1";       
    var agCtrl = null;

    try
    {
        agCtrl = new ActiveXObject('AgControl.AgControl');
    }
    catch (e)
    {
        agCtrl = navigator.plugins["Silverlight Plug-In"];
        if ((typeof(agCtrl) != "undefined") && (agCtrl != null))
        {
            agVersion = agCtrl.description;
            if ( agVersion === "1.0.30226.2")
            {
                agVersion = "2.0.30226.2";
            }
            else if ((agVersion.split(".").length < 4) && (typeof(detectionProbe) != "undefined") && (detectionProbe != null))
            {
                // On the Mac, Gecko-based browsers return only 3 of the 4 parts of the Silverlight version
                // number found in the plug-in's "description" property. If we have one of these partial
                // version strings then we can try to probe further to get a more precise value.
                
                agVersion = ProbeSilverlightVersion(detectionProbe);
            }
        }
    }

    if ((agCtrl != null) && (agVersion == "-1"))
    {
        agVersion = ProbeSilverlightVersion(agCtrl);
    }
    agCtrl = null;

    return agVersion;
}

function ProbeSilverlightVersion(agCtrl)
{
    var agVersion = "-1";
    try
    {
        var knownVersions = new Array();

        knownVersions[0]    = "0.90.20416.10";
        knownVersions[1]    = "0.95.20416.10";

        knownVersions[2]    = "1.0.20724.0";
        knownVersions[3]    = "1.0.20730.0";
        knownVersions[4]    = "1.0.20806.0";
        knownVersions[5]    = "1.0.20813.0";
        knownVersions[6]    = "1.0.20816.0";
        knownVersions[7]    = "1.0.20926.0";
        knownVersions[8]    = "1.0.21115.0";
        knownVersions[9]    = "1.0.30109.0";
        knownVersions[10]   = "1.0.30401.0";
        knownVersions[11]   = "1.0.30715.0";
        knownVersions[12]   = "1.0.30716.0";
        
        knownVersions[13]   = "1.1.20724.0";
        knownVersions[14]   = "1.1.20730.0";
        knownVersions[15]   = "1.1.20806.0";
        knownVersions[16]   = "1.1.20813.0";
        knownVersions[17]   = "1.1.20816.0";
        knownVersions[18]   = "1.1.20926.0";
        knownVersions[19]   = "2.0.30226";
        knownVersions[20]   = "2.0.30523.2";
        knownVersions[21]   = "2.0.30523.6";
        knownVersions[22]   = "2.0.30523.8";
        knownVersions[23]   = "2.0.30523.9";

        var versionCount = knownVersions.length;
        for (var iVer = versionCount - 1; iVer >= 0; iVer--)
        {
            if (agCtrl.IsVersionSupported(knownVersions[iVer]))
            {
                agVersion = knownVersions[iVer];
                break;                
            }
        }
        
        // If the installed version of Silverlight is at least as current as version 2.0 Beta 2 (2.0.30523)
        // then we need to further test to see if has an even more recent version number. At this point
        // we are going to switch the guessing game heuristic so we walk through all of the possible
        // version numbers in turn. We do this by knowning a few things (that may need to be tweaked/changed
        // as conditions change in the future)...
        //
        // - All current releases start 2.0.3 or 2.0.4. This logic will have to be enhanced in the future as Microsoft
        //   releases versions of Silverlight in the family 2.1 or 3.5 or x.y.
        // - Version numbers are formed, in part, by using the number of the month and day when the control was
        //   was compiled/linked (built). That limits the range of possible version numbers sufficiently so we
        //   can programmatically test each one without taking too much time.
         
        if (agVersion == knownVersions[knownVersions.length - 1])
        {
            var found = false;
            var scopes = new Array();
            scopes[0]    = "4.0.4";
            scopes[1]    = "3.0.4";
            scopes[2]    = "2.0.4";
            scopes[3]    = "2.0.3";
            for (var s = 0; (s < scopes.length) && (!found); s++)
            {
                var scope = scopes[s];
                for (var iMonth = 12; (iMonth > 0) && (!found); iMonth--)
                {
                    for (var iDay = 31; (iDay > 0) && (!found); iDay--)
                    {
                        for (var iSpecies = 20; (iSpecies >= 0) && (!found); iSpecies--)
                        {
                            var possibleVersion = scope + (iMonth < 10 ? "0" : "") + iMonth.toString() + (iDay < 10 ? "0" : "") + iDay.toString() + "." + iSpecies.toString();
                            if (agCtrl.IsVersionSupported(possibleVersion))
                            {
                                if (RestartRequired(agCtrl))
                                {
                                    // We have apparently just upgraded from SL 1.0 to SL 2.0 RTW.
                                    // We ought to close and reopen the browser in order to work reliably with Silverlight.
                                    // Until then, there isn't a fully usable version of Silverlight available.
                                    agVersion = -1;
                                }
                                else
                                {
                                    agVersion = possibleVersion;
                                }
                            
                                found = true;
                                break;                
                            }
                        }
                    }
                }
            }
        }
    }
    catch(e)
    {
        // Special case for a very early version of 1.1
        if ((agCtrl != null) &&
            (typeof(agCtrl.Settings) != "undefined") && (agCtrl.Settings != null) &&
            (typeof(agCtrl.Settings.version) != "undefined") && (agCtrl.Settings.version != null) &&
            (agCtrl.Settings.version == "0.95.20416"))
        {
            agVersion = "1.1.20416.10";
        }
    }
    
    return agVersion;
}

function RestartRequired(agCtrl)
{
    // Silverlight 1.0 did not have a terribly robust way to check for its own version
    // number. As a result, when you upgrade from 1.0 to 2.0 RTW (2.0.31005.0) there is
    // a time (before you close and reopen your browser) where you are instantiating
    // Silverlight 1.0 but the in-process control reports that it is actually 2.0.31005.
    // We can detect that by asking if the control supports 2.0.31005.99 which is
    // specially distinguished as supported by the real 2.0.31005.0 control, but not
    // by Silverlight 1.0 instances.
    var retVal = false;
    var version = "2.0.31005";
    try
    {
        if (agCtrl == null)
        {
            agCtrl = new ActiveXObject('AgControl.AgControl');
        }
        
        if (!agCtrl.IsVersionSupported(version + ".99") && agCtrl.IsVersionSupported(version + ".0"))
        {
            retVal = true;
        }
    }
    catch (e)
    {
    }
    return retVal;
}

function VersionComparison(v1, v2)
{
    var v1Array = v1.split(".");
    while (v1Array.length > 4)
    {
        v1Array.pop();
    }
    var v2Array = v2.split(".");
    while (v2Array.length > 4)
    {
        v2Array.pop();
    }
    var dimensionCount = Math.min(v1Array.length, v2Array.length);

    var result = 0;    
    for (var i=0; i<dimensionCount; i++)
    {
        try
        {
            var v1Int = parseInt(v1Array[i]);
            var v2Int = parseInt(v2Array[i]);
            if (v1Int > v2Int)
            {
                result = 1;
                break;
            }
            else if (v1Int < v2Int)
            {
                result = -1;
                break;
            }
        }
        catch (e)
        {
            result = -1;
            break;
        }
    }
    
    return result;
}

function pseudoTextAlignmentCenter(xamlElement, offset)
{
    try
    {
        var deltaForCentering = (xamlElement.Width - xamlElement.ActualWidth) / 2;
        if (typeof(offset) != "undefined")
        {
            deltaForCentering += offset;
        }
        xamlElement.SetValue("Canvas.Left", deltaForCentering);
    }
    catch(e)
    {
    }
}

doAfterSilverlightJsLoads = function()
{
    if ((typeof(Silverlight) != "undefined") && (typeof(Silverlight.onSilverlightInstalled) != "undefined") && (typeof(Silverlight.isBrowserRestartRequired) != "undefined"))
    {
        Silverlight.onSilverlightInstalled = 
            function () 
            {
                if (!Silverlight.isBrowserRestartRequired)
                {
                    if ((typeof(window.__pageSpecificSilverlightStartup) != "undefined") && (window.__pageSpecificSilverlightStartup != null) &&
                        (typeof(window.useSilverlight) != 'undefined') && (window.useSilverlight != null) && useSilverlight() &&
                        (typeof(window.Silverlight) != 'undefined') && (typeof(window.Silverlight.isInstalled) != 'undefined') && (window.Silverlight.isInstalled('1.0.20816.0')))
                    {
                        window.__pageSpecificSilverlightStartup();
                    }
                    else
                    {
                        window.location.reload(false);
                    }
                }
                else
                {
                    window.location.reload(false);
                }
            };
    }
    else
    {
        // Silverlight.js probably hasn't had a chance to load yet. Give it another couple of seconds.
        setTimeout(doAfterSilverlightJsLoads, 2000);
    }
}

generalSilverlightStartup = function()
{
    doAfterSilverlightJsLoads();
    if (window.removeEventListener)
    { 
       window.removeEventListener('load', generalSilverlightStartup , false);
    }
    else
    { 
        window.detachEvent('onload', generalSilverlightStartup);
    }
}


generalSilverlightErrorHandler = function(sender, errorArgs)
{
    var domain = document.domain.toLowerCase();
	if ((domain == "localhost") || (domain == "wwwppe") || (domain == "wwwppe.dns.microsoft.com"))
	{
		// The error message to display.
		var errorMsg = "Silverlight Error: \n\n";
		
		// Error information common to all errors.
		errorMsg += "Error Type:    " + errorArgs.errorType + "\n";
		errorMsg += "Error Message: " + errorArgs.errorMessage + "\n";
		errorMsg += "Error Code:    " + errorArgs.errorCode + "\n";
		
		// Determine the type of error and add specific error information.
		switch(errorArgs.errorType)
		{
			case "RuntimeError":
				// Display properties specific to RuntimeErrorEventArgs.
				if (errorArgs.lineNumber != 0)
				{
					errorMsg += "Line: " + errorArgs.lineNumber + "\n";
					errorMsg += "Position: " +  errorArgs.charPosition + "\n";
				}
				errorMsg += "MethodName: " + errorArgs.methodName + "\n";
				break;
			case "ParserError":
				// Display properties specific to ParserErrorEventArgs.
				errorMsg += "Xaml File:      " + errorArgs.xamlFile      + "\n";
				errorMsg += "Xml Element:    " + errorArgs.xmlElement    + "\n";
				errorMsg += "Xml Attribute:  " + errorArgs.xmlAttribute  + "\n";
				errorMsg += "Line:           " + errorArgs.lineNumber    + "\n";
				errorMsg += "Position:       " + errorArgs.charPosition  + "\n";
				break;
			default:
				break;
		}
		// Display the error message.
		alert(errorMsg);
	}
}

if (window.addEventListener) 
{
    window.addEventListener('load', generalSilverlightStartup , false);
}
else 
{
    window.attachEvent('onload', generalSilverlightStartup);
}

delegate = function(target, callback)
{
    var func;
    if(arguments.length > 2)
    {
        var _params = [];
        for(var n = 2; n < arguments.length; n++) _params.push(arguments[n]);
        func = function() { 
            var params = [];
            for(var n = 0; n < arguments.length; n++) params.push(arguments[n]);
            for(var n = 0; n < _params.length; n++) params.push(_params[n]);
            callback.apply(target,params); 
        }
    }
    else 
    {
        func =  function() {  callback.apply(target,arguments); }
    }
    return func;
}
