/*****************************************************************************
 *
 * File:                ConnectCheck.js
 *
 * Description:
 *  Javascript library containing methods to test client connectivity. 
 *  This test is typically invoked so that recommendations regarding
 *  video playback preferences can be provided to the user. Function 
 *  calls can be made in VSS templates, leaving the developer to provide 
 *  feedback based upon the client connection speed and port availability.
 *
 *****************************************************************************/

/*****************************************************************************
 *  Variable:           vi_clientBitrate
 *
 *  Description:
 *      Client download speed in bits per second. A value of 0 indicates
 *      that the connectivity test has not completed. A value of -1 
 *      indicates that the connectivity test failed (this will occur if an
 *      error was encountered while downloading the test image). A value 
 *      greater than 0 indicates that the test has completed, and the value
 *      indicates the client download speed in bits per second. Use the method
 *      vi_getClientBitrate to obtain the value of this variable.
 *
 *****************************************************************************/
var vi_clientBitrate = 0;

/*****************************************************************************
 *  Variable:           vi_startTime
 *
 *  Description:
 *      Connectivity test start time in seconds. This variable is set to the
 *      current system clock value (in milliseconds since 1970) immediately 
 *      before download of the test image.
 *
 *****************************************************************************/
var vi_startTime = 0;

/*****************************************************************************
 *  Variable:           vi_endTime
 *
 *  Description:
 *      Connectivity test end time in seconds. This variable is set to the
 *      current system clock value (in milliseconds since 1970) immediately 
 *      after download of the test image.
 *
 *****************************************************************************/
var vi_endTime = 0;

/*****************************************************************************
 *  Variable:           vi_callbackFunction
 *
 *  Description:
 *      Callback method to invoke upon completion of the connectivity test.
 *      This method is invoked with the client download speed in bits per
 *      second (or -1 if the test failed) as an argument. If a callback is
 *      not specified, the client may invoke vi_getConnectivity to obtain
 *      the calculated client download speed.
 *
 *****************************************************************************/
var vi_callbackFunction;

/*****************************************************************************
 *  Function:           vi_checkConnectivity
 *
 *  Description:
 *      Method to initiate connectivity test. The test is performed by 
 *      timing the download of a specified image of specified size. (The
 *      image should be of sufficient size to accurately guage client 
 *      download speed, but small enough to provide timely results for 
 *      clients with a dialup connection). The start time is appended to
 *      the specified URL to prevent cacheing of the test image. The image
 *      size should be specified in bytes.
 *
 *  Arguments: 
 *      imageUrl  Complete URL of test image used for connectivity testing.
 *      imageSize  Size (bytes) of test image used for connectivity testing
 *      callbackFunction  Client callback to invoke upon test completion
 *
 *  Return value:
 *      None. The method vi_calculateConnectivity is invoked upon successful 
 *      download of the image via the onload event handler. This method 
 *      invokes the client callback function, if one is provided.
 *
 *  Side Effects: None
 *
 *****************************************************************************/
function vi_checkConnectivity( testImageUrl, testImageSize, callbackFunction  )
{
    vi_startTime = ( new Date() ).getTime();
    var testImage = new Image( 1, 1 );
    testImage.onload = vi_calculateConnectivity;
    testImage.onerror = vi_connectivityError;
    testImage.src = testImageUrl + "?start=" + vi_startTime;
    vi_testImageSize = testImageSize;
    vi_callbackFunction = callbackFunction;
}

/*****************************************************************************
 *  Function:           vi_calculateConnectivity
 *
 *  Description:
 *      Internal method to calculate client download speed upon successful
 *      download of the test image. This method should not be invoked 
 *      independently of the image event handler. The download speed is
 *      calculated by multiplying the test image size by 8 (to convert from
 *      bytes to bits), and then dividing by the end time minus the start 
 *      time, divided by 1000 (to convert from milliseconds to seconds. As
 *      indicated, this method is used as the onload event handler for the 
 *      test image.
 *
 *  Arguments: None
 *
 *  Return value:
 *      None. This method sets the client connectivity and invokes the 
 *      client callback function, if one is provided. This method also 
 *      sets the client bitrate, which may be obtained vi vi_getConnectivity
 *
 *  Side Effects: None
 *
 *****************************************************************************/
function vi_calculateConnectivity()
{
    vi_endTime = ( new Date() ).getTime();
    if( vi_startTime < vi_endTime ) 
    {
        var numImageBits = vi_testImageSize * 8; 
        var numSeconds = ( vi_endTime - vi_startTime )/1000; 
        vi_clientBitrate = Math.round( numImageBits / numSeconds );
    }
    else 
    {
        vi_clientBitrate = -1;
    }

    if( vi_callbackFunction )
    {
        vi_callbackFunction( vi_clientBitrate );
    }
}

/*****************************************************************************
 *  Function:           vi_connectivityError
 *
 *  Description:
 *      Internal method to set client download speed to -1 when an error
 *      downloadling the test image occurs. This method should not be 
 *      invoked independently of the image event handler. This method is 
 *      used as the onerror event handler for the test image.
 *
 *  Arguments: None
 *
 *  Return value:
 *      None. This method sets the client connectivity and invokes the 
 *      client callback function, if one is provided. This method also 
 *      sets the client bitrate, which may be obtained vi vi_getConnectivity
 *
 *  Side Effects: None
 *
 *****************************************************************************/
function vi_connectivityError()
{
    vi_clientBitrate = -1;

    if( vi_callbackFunction )
    {
        vi_callbackFunction( vi_clientBitrate );
    }
}

/*****************************************************************************
 *  Function:           vi_getConnectivity
 *
 *  Description:
 *      Returns the client download speed in bits per second. A value of 
 *      zero indicates the test is still in progress. A value of -1 indicates
 *      that an error occurred while attempting to download the test image.
 *
 *  Arguments: None
 *
 *  Return value:
 *      Client download speed in bits per second.
 *      0 if the test is still in progress
 *      -1 if an error occurred
 *
 *  Side Effects: None
 *
 *****************************************************************************/
function vi_getConnectivity()
{
    return vi_clientBitrate;
}

/*****************************************************************************
 *  Function:           vi_checkPortAccess
 *
 *  Description:
 *      Checks availability of a specific port via the specified URL. The
 *      test URL should correspond to a small image accessed via the port
 *      to be tested. Client callback methods are invoked to inform the 
 *      caller of the test result.
 *
 *  Arguments: 
 *      testUrl  Complete URL of test image used for firewall testing.
 *      passCallback  Method to set as image onload event callback 
 *      failCallback  Method to set as image onerror event callback
 *
 *  Return value:
 *      Client download speed in bits per second.
 *      0 if the test is still in progress
 *      -1 if an error occurred
 *
 *  Side Effects: None
 *
 *****************************************************************************/
function vi_checkPortAccess( testUrl, passCallback, failCallback ) 
{
    var image = new Image( 1, 1 );
    image.onerror = failCallback;
    image.onload = passCallback;
    image.src = testUrl;
}
