// #defines
// Netscape 4.X does not support switch statements with non-constants
// so, please excuse the if else structures that use the "#defines" below

var BROWSER_TYPE_UNKNOWN = 0;
var BROWSER_TYPE_IE = 1;
var BROWSER_TYPE_NN = 2;
var BROWSER_TYPE_FF = 3;

var SOFTPHONE_NP_INSTALLED_NO = 0;
var SOFTPHONE_NP_INSTALLED_YES = 1;
var SOFTPHONE_NP_INSTALLED_NEED_PERMISSION = 2;

var ERROR_SOFTPHONE_NOT_LOADED = 1;
var ERROR_SOFTPHONE_SCRIPT_VERSION_MISMATCH = 2;
var ERROR_SOFTPHONE_ABORTED = 3;
var ERROR_SOFTPHONE_FAILED = 4;

var ERROR_CODE_FAILED_LOAD_INI = 1;
var ERROR_CODE_FAILED_TO_CONNECT = 2;
var ERROR_CODE_CANNOT_RUN = 3;
var ERROR_CODE_PORT_IN_USE = 4;
var ERROR_CODE_PROXY = 5;
var ERROR_CODE_VERSION_NOT_COMPAT = 6;
var ERROR_CODE_FAILED_LOAD_AUDIO_INI = 7;
var ERROR_CODE_FAILED_AUDIO_TEST = 8;
var ERROR_CODE_PHONE_NAME_NOT_FOUND = 9;
var ERROR_CODE_NUMBER_NOT_FOUND = 10;
var ERROR_CODE_IVX_OFFLINE = 11;
var ERROR_CODE_IVX_BUSY = 12;
var ERROR_CODE_NOT_LICENSED = 13;
var ERROR_CODE_PRIORITY_TOO_LOW = 14;
var ERROR_CODE_RATE_NOT_FOUND = 15;
var ERROR_CODE_NUMBER_BLOCKED = 16;
var ERROR_CODE_NOT_BILLABLE_ACCOUNT = 17;
var ERROR_CODE_SERVER_ERROR = 18;
var ERROR_CODE_INSUFFICIENT_FUNDS = 19;
var ERROR_CODE_RSV_NOT_ALLOWED = 20;
var ERROR_CODE_RSV_REQUIRED = 21;
var ERROR_CODE_UNASSIGNED_NUMBER = 22;
var ERROR_CODE_BUSY = 23;
var ERROR_CODE_NO_CONNECT = 24;
var ERROR_CODE_NO_ANSWER = 25;
var ERROR_CODE_UNAVAILABLE = 26;
var ERROR_CODE_UNKNOWN_FAILURE = 27;
var ERROR_CODE_NEED_PSWD = 28;
var ERROR_CODE_NEED_PSWD_DOMAIN = 29;
var ERROR_CODE_INVALID_LOGIN = 30;
var ERROR_CODE_CANNOT_XFER = 31;
var ERROR_CODE_CANNOT_CONF = 32;
var ERROR_CODE_LOGIN_EXPIRED = 33;
var ERROR_CODE_LOGIN_BLOCKED = 34;
var ERROR_CODE_LOGIN_LICENSE = 35;
var ERROR_CODE_LOGIN_COUNT = 36;
var ERROR_CODE_CRYPTO = 37;
var ERROR_CODE_AW_NO_SOUND_CARD = 1001;
var ERROR_CODE_AW_NO_SUCH_SOUND_CARD = 1002;
var ERROR_CODE_AW_USB_DEVICE_NOT_FOUND = 1003;
var ERROR_CODE_AW_FAILED_LOAD_STRING_FILE = 1004;
var ERROR_CODE_AW_TEST_RESULT_NO_SOUND = 1005;
var ERROR_CODE_AW_TEST_RESULT_NO_OUTPUT = 1006;
var ERROR_CODE_AW_TEST_RESULT_NO_INPUT = 1007;
var ERROR_CODE_AW_TEST_RESULT_OUTPUT_BUSY = 1008;
var ERROR_CODE_AW_TEST_RESULT_INPUT_BUSY = 1009;
var ERROR_CODE_AW_TEST_RESULT_NO_FULL_DUPLEX = 1010;
var ERROR_CODE_AW_TEST_RESULT_UNKNOWN = 1011;
var ERROR_CODE_AW_CHECKCAPS_FAILED = 1012;
var ERROR_CODE_AW_COULD_NOT_HEAR_USER = 1013;
var ERROR_CODE_AW_CANCELED = 1014;

var CV_LINE_STATUS_END = 0;
var CV_LINE_STATUS_INIT = 1;
var CV_LINE_STATUS_CONNECTED = 2;
var CV_LINE_STATUS_DIALING = 3;
var CV_LINE_STATUS_OUTBOUND = 4;
var CV_LINE_STATUS_READY = 5;
var CV_LINE_STATUS_NOT_READY = 6;
var CV_LINE_STATUS_INBOUND = 7;
var CV_LINE_STATUS_MUTE = 8;
var CV_LINE_STATUS_HOLD = 9;
var CV_LINE_STATUS_BAD_NUMBER = 10;
var CV_LINE_STATUS_BUSY = 11;
var CV_LINE_STATUS_NO_CONNECT = 12;
var CV_LINE_STATUS_NO_ANSWER = 13;
var CV_LINE_STATUS_FAILED = 14;
var CV_LINE_STATUS_DEFERRED = 15;
var CV_LINE_STATUS_NOTHING = 16;
var CV_LINE_STATUS_NO_RESERVATION = 17;
var CV_LINE_STATUS_CANCELED = 18;
var CV_LINE_STATUS_DEST_OFFLINE = 19;
var CV_LINE_STATUS_TRANSFER = 20;
var CV_LINE_STATUS_TRANSFER_DONE = 21;
var CV_LINE_STATUS_INSUFFICENT_FUNDS = 22;
var CV_LINE_STATUS_CONSULT_DIALING = 23;
var CV_LINE_STATUS_CONSULT_CONNECTED = 24;
var CV_LINE_STATUS_CONSULT_BUSY = 25;
var CV_LINE_STATUS_CONSULT_FAILED = 26;
var CV_LINE_STATUS_CONSULT_OUTBOUND = 27;
var CV_LINE_STATUS_CONSULT_HUNG_UP = 28;
var CV_LINE_STATUS_CONSULT_MAX_CAPACITY = 29;
var CV_LINE_STATUS_CONSULT_UNSUPPORTED = 30;
var CV_LINE_STATUS_IN_USE = 31;
var CV_LINE_STATUS_OUT_OF_SERVICE = 32;
var CV_LINE_STATUS_CURRENT = 33;

var CV_LINE_BOTH = -1;
var CV_LINE_CONFERENCE = 0;

var CV_CALL_QUALITY_NONE = -1;
var CV_CALL_QUALITY_MAX = 7;

var CV_AUDIO_WIZARD_FULL = 0;
var CV_AUDIO_WIZARD_SIMPLE = 1;
var CV_AUDIO_WIZARD_SIMPLE_NO_RETRY = 2;

var CV_END_CAUSE_NORMAL = 0;
var CV_END_CAUSE_REJECTED = 1;
var CV_END_CAUSE_BLOCKED = 2;

// globals

var gBrowserType = BROWSER_TYPE_UNKNOWN;
var gBrowserVersion = 0;
var gTrigger = null;
var gAppDownloadPath = "";
var gSoftphoneVersion = "";
var gSoftphoneVersionPeriod = "";
var gSoftphoneObject = null;
var gScriptVersion = "4.2.3.1";

function GetNetscapeCompatibleVersion( userAgent )
{
    var version = userAgent.substring( 8 );
    var pos = version.indexOf( ' ' );
    version = version.substring( 0, pos );
        
    if ( parseInt(navigator.appVersion) >= 5 )
    {
        var pos = userAgent.lastIndexOf( '/' );
        version = userAgent.substring( pos + 1 );
    }

    return parseFloat( version );
}

function DetectBrowser()
{
    // check the OS first
    
        var appName = navigator.appName.toUpperCase();
        var userAgent = navigator.userAgent.toUpperCase();
        var platform = GetPlatform( userAgent );
        if ( platform != 'win' && platform != 'unknown' )
        {
			// Do not redirect since this is being used on the JAC login page.
//            document.location = "OSNotSupported.htm";
            return;
        }
        
    // get the browser type and version

        if ( userAgent.indexOf('MSIE') != -1 )
        {
            gBrowserType = BROWSER_TYPE_IE;
            gBrowserVersion = parseInt( navigator.appVersion.substring(0,10) );
        }
        else if ( userAgent.indexOf('FIREFOX') != -1 )
        {
            gBrowserType = BROWSER_TYPE_FF;
            gBrowserVersion = GetNetscapeCompatibleVersion( userAgent );
            gTrigger = InstallTrigger;
        }
        else if ( appName.indexOf('NETSCAPE') != -1 )
        {
            gBrowserType = BROWSER_TYPE_NN;
            gBrowserVersion = GetNetscapeCompatibleVersion( userAgent );
            if ( gBrowserVersion >= 6.0 )
            {
                gTrigger = InstallTrigger;
            }
            else
            {
                if ( IsJavaEnabled() )
                {
                    gTrigger = netscape.softupdate.Trigger;
                }
            }
        }
        else if ( userAgent.indexOf('OPERA') != -1 )
        {
            gBrowserType = BROWSER_TYPE_OP;
            gBrowserVersion = GetNetscapeCompatibleVersion( userAgent );
        }
        
    // check the browser type and version

        if ( gBrowserType == BROWSER_TYPE_IE )
        {
            if ( gBrowserVersion >= 4.0 )
            {
                return;
            }
        }
        else if ( gBrowserType == BROWSER_TYPE_NN )
        {
            if ( gBrowserVersion >= 4.0 &&
                 ( gBrowserVersion < 6.0 || gBrowserVersion >= 6.2 ) )
            {
                return;
            }
        }
        else if ( gBrowserType == BROWSER_TYPE_FF )
        {
            if ( gBrowserVersion >= 1.0 )
            {
                return;
            }
        }

    // if you got here, you don't have a supported browser
    
        document.location = "BrowserNotSupported.htm";
}

function GetPlatform(agent)
{
    var platform = 'unknown'
    if (agent.indexOf('WIN') != -1) { platform = 'win'; }
    else if (agent.indexOf('MAC') != -1) { platform = 'mac'; }
    else if (agent.indexOf('IRIX') != -1) { platform = 'irix'; }
    else if (agent.indexOf('LINUX') != -1) { platform = 'linux'; }
    else if (agent.indexOf('BSD') != -1) { platform = 'bsd'; }
    return platform;
}

function CvSetElementHtml( id, html )
{
    if (document.getElementById)
    {
        x = document.getElementById(id);
        x.innerHTML = '';
        x.innerHTML = html;
    }
    else if (document.all)
    {
        x = document.all[id];
        x.innerHTML = html;
    }
    else if (document.layers)
    {
        x = eval( "document." + id + "ILayer.document." + id + "Layer;" );
        x.document.open();
        x.document.write( html );
        x.document.close();
    }
}

//
// Parse the query string and return the value of the named
// parameter.
//
function CvGetQueryStringValue( name )
{
    var queryString = window.location.search.substring(1);
    queryString = queryString.toLowerCase();
    var vars = queryString.split("&");
    for ( var i = 0; i < vars.length; i++ )
    {
        var pair = vars[i].split("=");
        if ( pair[0] == name.toLowerCase() )
        {
            return pair[1];
        }
    }
    return null;
}

function IsSmartUpdateEnabled()
{
    return gTrigger.UpdateEnabled();
}

function WaitForSmartUpdateEnabled()
{
    if ( IsSmartUpdateEnabled() )
    {
        CvReloadPage();
        return;
    }

    setTimeout( 'WaitForSmartUpdateEnabled();',1000 );
}

function IsJavaEnabled()
{
    return navigator.javaEnabled();
}

function WaitForJavaEnabled()
{
    if ( IsJavaEnabled() )
    {
        CvReloadPage();
        return;
    }

    setTimeout( 'WaitForJavaEnabled();',1000 );
}

function CompareVersion( v1, v2 )
{
    // Netscape 6.0 version comparison doesn't work
    // so I had to write my own
        
    // split up the version number
    
        v1Arr = v1.split( "." );
        v2Arr = v2.split( "." );

    // v1 and v2 must be strings of the format x.x.x.x

        if ( v1Arr.length < 4 || v2Arr.length < 4 )
        {
            return -4;
        }

    // compare each piece of the version
    // from major to minor
    // return +/- 4 if major number if different 
    // return +/- 3 if minor number if different
    // return +/- 2 if release number if different
    // return +/- 1 if build number if different

        for ( var i = 0; i < 4; i++ )
        {
            if ( Number( v1Arr[i] ) < Number( v2Arr[i] ) )
            {
                return -( 4 - i );
            }

            if ( Number( v1Arr[i] ) > Number( v2Arr[i] ) )
            {
                return ( 4 - i );
            }
        }

    // they are the same
    
        return 0;
}

function IsSoftphoneNpInstalled()
{
    // look for the plugin

        navigator.plugins.refresh( false );
        if ( !navigator.plugins["CrystalVoice Softphone"] )
        {
            return SOFTPHONE_NP_INSTALLED_NO;
        }

    // get the version

        var version;
        if ( gBrowserType == BROWSER_TYPE_FF ||
             ( gBrowserType == BROWSER_TYPE_NN && gBrowserVersion >= 6.0 ) )
        {
            // get the version of the plugin

                version = gTrigger.getVersion( "/Plugins/NPSoftphoneNp" );

            // if the version is null, then we are not on the list of sites allowed to install software

                if ( version == null )
                {
                    return SOFTPHONE_NP_INSTALLED_NEED_PERMISSION;
                }
        }
        else
        {
            version = gTrigger.GetVersionInfo( "plugins/SoftphoneNp" );
        }

    // compare the version

        var versionCompare = -4;
        eval( "versionCompare = CompareVersion( '" + version.toString() + "', '" + gSoftphoneVersionPeriod + "' );" );
        if ( versionCompare >= 0 )
        {
            return SOFTPHONE_NP_INSTALLED_YES;
        }

    return SOFTPHONE_NP_INSTALLED_NO;
}

function WaitForSoftphoneNpInstall()
{
    if ( IsSoftphoneNpInstalled() == SOFTPHONE_NP_INSTALLED_YES )
    {
        CvReloadPage();
        return;
    }

    setTimeout( 'WaitForSoftphoneNpInstall();',1000 );
}

function InstallXpiPlugin( callBack )
{
    var xpi = new Array();
    xpi[ "CrystalVoice Softphone" ] = { URL : gAppDownloadPath + "SoftphoneMp.xpi" };
    gTrigger.install( xpi, callBack );
}

function InstallXpiCallBack( url, status )
{
    if ( status == 0 )
    {
        CvReloadPage();
    }
    else
    {
        CvOnError( status );
    }
}

function NoOpInstallXpiCallBack( url, status )
{
    // ignore
}

function CvReloadPage()
{
    if ( gBrowserType == BROWSER_TYPE_IE ||
         ( gBrowserType == BROWSER_TYPE_NN &&
           gBrowserVersion < 6.0 ) )
    {
        // Netscape 4.X and Internet Explorer
        window.location.reload( true );
    }
    else
    {
        // Netscape 6.X, 7.X, 8.X and Firefox
        location.reload( true );
    }   
}

function WaitForPermissionToCheckVersion()
{
    // IMPORTANT: This method is for Netscape 6/7 and FireFox ONLY

    version = gTrigger.getVersion( "/Plugins/NPSoftphoneNp" );

    if ( version != null )
    {
        CvReloadPage();
        return;
    }

    setTimeout( 'WaitForPermissionToCheckVersion();',1000 );
}

function ShowDiv( divName )
{
    if ( gBrowserType == BROWSER_TYPE_IE )
    {
        if ( gBrowserVersion < 5.0 )
        {
            eval( "document.all." + divName + ".style.visibility = 'visible';" );
        }
        else
        {
            document.getElementById( divName ).style.visibility = 'visible';
        }
        return;
    }
    else if ( gBrowserType == BROWSER_TYPE_NN )
    {
        if ( gBrowserVersion < 6.0 )
        {
            document.layers[ divName ].visibility = "show";
        }
        else
        {
            document.getElementById( divName ).style.visibility = 'visible';
        }
        return;
    }
    else if ( gBrowserType == BROWSER_TYPE_FF )
    {
        document.getElementById( divName ).style.visibility = 'visible';
        return;
    }
    else
    {
        alert( "Invalid browser type: " + gBrowserType );
        return;
    }
}

function LoadInternetExplorer()
{
    document.write("<OBJECT ID='Softphone' NAME='Softphone' HIDDEN \
                    CLASSID='CLSID:D77AA282-C977-42ca-9E63-E7D9B4C53BEA' width='0' height='0' \
                       codebase='" + gAppDownloadPath + "Softphone.cab#version=" + gSoftphoneVersion + "'> \
                    The Softphone failed to load.<BR> \
                    <A HREF='http://www.microsoft.com/windows/ie/using/howto/security/setup.mspx' TARGET='_blank'> \
                    Click here for instructions on enabling ActiveX.</A></OBJECT> \
                    <scr" + "ipt language='JavaScript' for='Softphone' event='EvalJavaScript(text)'>eval(text);</scr" + "ipt>" );

    return true;
}

function LoadNetscape()
{
    if ( !IsJavaEnabled() )
    {
        ShowDiv( "InstructionJavaNetscape4X" );
                        
        WaitForJavaEnabled();
        return false;
    }
    
    if ( !IsSmartUpdateEnabled() )
    {
        if ( gBrowserVersion >= 6.0 )
        {
            ShowDiv( "InstructionSmartUpdateNetscape6X" );
        }
        else
        {
            ShowDiv( "InstructionSmartUpdateNetscape4X" );
        }

        WaitForSmartUpdateEnabled();
        return false;
    }
    
    var installed = IsSoftphoneNpInstalled();
    
    if ( installed == SOFTPHONE_NP_INSTALLED_YES )
    {
        // start it up!
        
            document.write("<EMBED ID='Softphone' NAME='Softphone' TYPE='application/x-crystalvoice-softphone' width='2' height='2'>");
            return true;
    }
    else if ( installed == SOFTPHONE_NP_INSTALLED_NEED_PERMISSION )
    {
        // We are not in the allowed sites list
        // show instructions
            
            ShowDiv( "InstructionAllowListNetscape7X" );

        // wait for the user to add us to their list
                
            WaitForPermissionToCheckVersion()
                
        // try to perform an installation, this will prompt the user to
        // add us to the list of sites allowed to install software
                
            gTrigger.install();
            return true;
    }
    else if ( installed == SOFTPHONE_NP_INSTALLED_NO )
    {
        if ( gBrowserVersion >= 6.0 && gBrowserVersion < 7.2 )
        {
            var xpi = { 'CrystalVoice Softphone' : gAppDownloadPath + 'SoftphoneMp.xpi' };
            if ( !gTrigger.install( xpi ) )
            {
                return false;
            }

            // detection of successful installation does not work
            // in Netscape 7.1 or higher
            if ( gBrowserVersion >= 7.1 )
            {
                document.write("Click <A HREF='javascript:CvReloadPage();''>here</A> to continue...<BR>");
                return true;
            }
            else
            {
                document.write("Loading...<BR>");
                WaitForSoftphoneNpInstall();
                return true;
            }
        }
        else if ( gBrowserVersion >= 7.2 )
        {
            // start a no-op install, this will cause the security
            // bar to be displayed to the user
        
                InstallXpiPlugin( NoOpInstallXpiCallBack );
                
            // show instructions
        
                ShowDiv( "InstructionsInstallNetscape7X" );
                return true;
        }
        else
        {
            document.write("Loading...<BR>");
            gTrigger.StartSoftwareUpdate( gAppDownloadPath + 'SoftphoneNp.jar', gTrigger.FORCE_MODE ); 
            WaitForSoftphoneNpInstall();
            return true;
        }
    }
    else
    {
        alert( "Invalid IsSoftphoneNpInstalled return value: " + installed );
        return false;
    }
}

function LoadFirefox()
{
    /* Skip this check. In many Firefox browsers this test returns a false negative.
    if ( !IsJavaEnabled() )
    {
        ShowDiv( "InstructionJavaFirefox" );
                        
        WaitForJavaEnabled();
        return false;
    }
    */
    if ( !IsSmartUpdateEnabled() )
    {
        ShowDiv( "InstructionSmartUpdateFirefox" );

        WaitForSmartUpdateEnabled();
        return false;
    }
    
    var installed = IsSoftphoneNpInstalled();
    if ( installed == SOFTPHONE_NP_INSTALLED_YES )
    {
        // start it up!
        
            document.write("<EMBED ID='Softphone' NAME='Softphone' TYPE='application/x-crystalvoice-softphone' width='0' height='0'>");
            return true;
    }
    else if ( installed == SOFTPHONE_NP_INSTALLED_NEED_PERMISSION )
    {                   
        // We are not in the allowed sites list
        // show instructions
            
            ShowDiv( "InstructionAllowListFirefox" );

        // wait for the user to add us to their list

            WaitForPermissionToCheckVersion();
                
        // start a no-op install, this will cause the security
        // bar to be displayed to the user
        
            InstallXpiPlugin( NoOpInstallXpiCallBack );
            return true;
    }
    else if ( installed == SOFTPHONE_NP_INSTALLED_NO )
    {
        // start a no-op install, this will cause the security
        // bar to be displayed to the user
        
            InstallXpiPlugin( NoOpInstallXpiCallBack );
            
        // show instructions
        
            ShowDiv( "InstructionsInstallFirefox" );
            return true;
    }
    else
    {
        alert( "Invalid IsSoftphoneNpInstalled return value: " + installed );
        return false;
    }
}

//
// CvLoadSoftphone
//
function CvLoadSoftphone( version )
{
    // set the version strings

        if ( version.indexOf( '.' ) > 0 )
        {
            gSoftphoneVersionPeriod = version;
            gSoftphoneVersion = version.replace( /\./g, ',' );
        }
        else if ( version.indexOf( ',' ) > 0 )
        {
            gSoftphoneVersion = version;
            gSoftphoneVersionPeriod = version.replace( /,/g, '.' );
        }
        else
        {
            alert( "Bad version string: " + version );
            return false;
        }

    // detect the browser type
        
        DetectBrowser();
    
    // take different action for each browser type
    
        if ( gBrowserType == BROWSER_TYPE_IE )
        {
            installed = LoadInternetExplorer();
        }
        else if ( gBrowserType == BROWSER_TYPE_NN )
        {
            installed = LoadNetscape();
        }
        else if ( gBrowserType == BROWSER_TYPE_FF )
        {
            installed = LoadFirefox();
        }
        else
        {
            alert( "Invalid browser type: " + gBrowserType );
            return false;
        }
        
    // if we we're successful, start monitoring the exit and status codes
    
        if ( !installed )
        {
            document.write("Failed to install CrystalVoice Softphone");
        }

        return installed;
}

//
// Called by the plug-in when Softphone is loaded
// 
function OnSoftphoneLoaded()
{
    if ( CvInitalizeGlobals() )
    {
        CvOnSoftphoneLoadSuccess();
    }
    else
    {
        CvOnSoftphoneLoadFailure();
    }
}

function CvInitalizeGlobals()
{
    // get the object
    
        if ( gBrowserType == BROWSER_TYPE_IE )
        {
            if ( document.all.Softphone != undefined )
            {
                gSoftphoneObject = document.all.Softphone;
            }
        }
        else
        {
            if ( document.embeds.length > 0 &&
                 document.embeds[0] != undefined )
            {
                gSoftphoneObject = document.embeds[0];
            }
        }
        
    // is this script compatible with this version of Softphone?
    // must construct string to work in Netscape 4.X

        var versionCompare = CompareVersion( gScriptVersion, new String ( CvGetProperty( "OldestCompatibleVersion" ) ) );
        if ( versionCompare < 0 )
        {
            CvOnError( ERROR_SOFTPHONE_SCRIPT_VERSION_MISMATCH );
            return false;
        }
        
        if ( !gSoftphoneObject )
        {
            CvOnError( ERROR_SOFTPHONE_NOT_LOADED );
            return false;
        }
        
    // check to see if the object loaded successfully
    
        if ( CvGetProperty( "LastErrorCode" ) != 0 )
        {
            CvOnError( ERROR_SOFTPHONE_ABORTED );
            return false;
        }

    // all appears to be well
    
        return true;
}

function CvGetLineProperty( line, name )
{
    if ( gSoftphoneObject == null )
    {
        CvOnError( ERROR_SOFTPHONE_NOT_LOADED );
        return null;
    }

    if ( gBrowserType == BROWSER_TYPE_NN &&
         gBrowserVersion < 6.0 )
    {
        return eval( "gSoftphoneObject.Get" + name + "( line );" );
    }
    else
    {
        return eval( "gSoftphoneObject." + name + "(" + line + ");" );
    }
}

function CvSetLineProperty( line, name, value )
{
    if ( gSoftphoneObject == null )
    {
        CvOnError( ERROR_SOFTPHONE_NOT_LOADED );
        return null;
    }

    if ( gBrowserType == BROWSER_TYPE_NN &&
         gBrowserVersion < 6.0 )
    {
        return eval( "gSoftphoneObject.Set" + name + "( line, value );" );
    }
    else
    {
        return eval( "gSoftphoneObject." + name + "(line) = value;" );
    }
}

function CvGetProperty( name )
{
    if ( gSoftphoneObject == null )
    {
        CvOnError( ERROR_SOFTPHONE_NOT_LOADED );
        return null;
    }

    if ( gBrowserType == BROWSER_TYPE_NN &&
         gBrowserVersion < 6.0 )
    {
        return eval( "gSoftphoneObject.Get" + name + "();" );
    }
    else
    {
        return eval( "gSoftphoneObject." + name + ";" );
    }
}

function CvSetProperty( name, value )
{
    if ( gSoftphoneObject == null )
    {
        CvOnError( ERROR_SOFTPHONE_NOT_LOADED );
        return false;
    }
    
    if ( gBrowserType == BROWSER_TYPE_NN &&
         gBrowserVersion < 6.0 )
    {
        return eval( "gSoftphoneObject.Set" + name + "( value );" );
    }
    else
    {
        return eval( "gSoftphoneObject." + name + " = value;" );
    }
}

function CvSendDtmf( line, dtmf )
{
    if ( gSoftphoneObject == null )
    {
        CvOnError( ERROR_SOFTPHONE_NOT_LOADED );
        return false;
    }
    
    gSoftphoneObject.SendDtmf( line, dtmf );

    // check for errors

        if ( CvGetProperty( "LastErrorCode" ) != 0 )
        {
            CvOnError( ERROR_SOFTPHONE_FAILED );
            return false;
        }

    return true;
}

function CvLogin( phoneName, pswd, saveFlag )
{
    if ( gSoftphoneObject == null )
    {
        CvOnError( ERROR_SOFTPHONE_NOT_LOADED );
        return false;
    }

    gSoftphoneObject.LogIn( phoneName, pswd, saveFlag );

    // check for errors

        if ( CvGetProperty( "LastErrorCode" ) != 0 )
        {
            CvOnError( ERROR_SOFTPHONE_FAILED );
            return false;
        }

    return true;
}

/*
 *  CvPlaceCall
 *
 *  Parameters:
 *      line              - line on which to place the call.
 *      phoneNumberToCall - string representing phone number to call.
 */
function CvPlaceCall( line, phoneNumberToCall )
{
    if ( gSoftphoneObject == null )
    {
        CvOnError( ERROR_SOFTPHONE_NOT_LOADED );
        return false;
    }

    gSoftphoneObject.PlaceCall( line,
                                phoneNumberToCall );
    return true;
}

function CvAnswerCall( line )
{
    if ( gSoftphoneObject == null )
    {
        CvOnError( ERROR_SOFTPHONE_NOT_LOADED );
        return false;
    }

    gSoftphoneObject.AnswerCall( line );
    return true;
}

function CvConferenceCall()
{
    if ( gSoftphoneObject == null )
    {
        CvOnError( ERROR_SOFTPHONE_NOT_LOADED );
        return false;
    }

    var csvLines = "";
    for ( i = 0; i < arguments.length; i++ )
    {
        csvLines = csvLines + arguments[i];
        if ( i < arguments.length - 1 )
        {
            csvLines = csvLines + ",";
        }
    }
    gSoftphoneObject.Conference( csvLines );

    // check for errors
    
        if ( CvGetProperty( "LastErrorCode" ) != 0 )
        {
            CvOnError( ERROR_SOFTPHONE_FAILED );
            return false;
        }

    return true;
}

function CvEndConference()
{
    gSoftphoneObject.EndConference();

    // check for errors
    
        if ( CvGetProperty( "LastErrorCode" ) != 0 )
        {
            CvOnError( ERROR_SOFTPHONE_FAILED );
            return false;
        }

    return true;
}

function CvTransferCall( line, destination )
{
    if ( gSoftphoneObject == null )
    {
        CvOnError( ERROR_SOFTPHONE_NOT_LOADED );
        return false;
    }

    gSoftphoneObject.TransferCall( line, destination );

    // check for errors
    
        if ( CvGetProperty( "LastErrorCode" ) != 0 )
        {
            CvOnError( ERROR_SOFTPHONE_FAILED );
            return false;
        }

        return true;
}

function CvEndCall( line )
{
    if ( gSoftphoneObject == null )
    {
        CvOnError( ERROR_SOFTPHONE_NOT_LOADED );
        return false;
    }

    var reason = CV_END_CAUSE_NORMAL;
    if ( arguments.length > 1 )
    {
        reason = arguments[1];
    }
    
    gSoftphoneObject.EndCall( line, reason );
    return true;
}

function CvLoadAudioSettings()
{
    if ( gSoftphoneObject == null )
    {
        CvOnError( ERROR_SOFTPHONE_NOT_LOADED );
        return false;
    }

    gSoftphoneObject.LoadAudioSettings();

    // check for errors

        if ( CvGetProperty( "LastErrorCode" ) != 0 )
        {
            CvOnError( ERROR_SOFTPHONE_FAILED );
            return false;
        }

  return true;
}

function CvSaveAudioSettings()
{
    if ( gSoftphoneObject == null )
    {
        CvOnError( ERROR_SOFTPHONE_NOT_LOADED );
        return false;
    }

    gSoftphoneObject.SaveAudioSettings();

    // check for errors

        if ( CvGetProperty( "LastErrorCode" ) != 0 )
        {
            CvOnError( ERROR_SOFTPHONE_FAILED );
            return false;
        }

  return true;
}

function CvLoadSoftphoneSettings()
{
    if ( gSoftphoneObject == null )
    {
        CvOnError( ERROR_SOFTPHONE_NOT_LOADED );
        return false;
    }

    gSoftphoneObject.LoadApplicationSettings();

    // check for errors

        if ( CvGetProperty( "LastErrorCode" ) != 0 )
        {
            CvOnError( ERROR_SOFTPHONE_FAILED );
            return false;
        }

  return true;
}

function CvSaveSoftphoneSettings()
{
    if ( gSoftphoneObject == null )
    {
        CvOnError( ERROR_SOFTPHONE_NOT_LOADED );
        return false;
    }

    gSoftphoneObject.SaveApplicationSettings();

    // check for errors

        if ( CvGetProperty( "LastErrorCode" ) != 0 )
        {
            CvOnError( ERROR_SOFTPHONE_FAILED );
            return false;
        }

  return true;
}

function CvShowAudioWizard()
{
    if ( gSoftphoneObject == null )
    {
        CvOnError( ERROR_SOFTPHONE_NOT_LOADED );
        return false;
    }

    var awType;
    if ( arguments.length > 0 )
    {
        awType = arguments[0];
    }
    else
    {
        awType = CV_AUDIO_WIZARD_FULL;
    }

    gSoftphoneObject.ShowAudioWizard( awType );

    // check for errors

        if ( CvGetProperty( "LastErrorCode" ) != 0 )
        {
            CvOnError( ERROR_SOFTPHONE_FAILED );
            return false;
        }

    return true;
}

function CvSaveProxyAuth()
{
    if ( gSoftphoneObject == null )
    {
        CvOnError( ERROR_SOFTPHONE_NOT_LOADED );
        return false;
    }

    gSoftphoneObject.SaveProxyAuth();

    return true;
}

function CvDeleteSavedPassword()
{
    if ( gSoftphoneObject == null )
    {
        CvOnError( ERROR_SOFTPHONE_NOT_LOADED );
        return false;
    }

    gSoftphoneObject.DeleteSavedPassword();

    return true;
}

// Simple debugging aids

var _console = null;

function CvEnableDebug( flag )
{
    if ( flag )
    {
        if ( (_console == null) || (_console.closed) )
        {
            _console = window.open( "", "console", "width=500,height=300,resizable=yes,scrollbars=yes" );
            _console.document.open( "text/plain" );
        }
    }
    else if ( _console != null )
    {
        _console.close()
        _console = null;
    }
}

function CvDebug( msg )
{
    if ( _console != null )
    {
        _console.focus();
        _console.document.writeln( msg );
    }
}

