/******************************************************************************
 *                                                                         
 *               Copyright 2004-2006 Agilent Technologies
 *               All rights reserved.
 *
 *****************************************************************************/
 
#include "stdafx.h"
#include "CoAgilent34980A.h"

/// <summary>
/// Clears the specified alarm output lines.  If ClearAll is TRUE, all four alarm output lines are cleared.
/// </summary>
/// <remarks>
/// 
/// </remarks>
/// <returns>
///	
/// </returns>
/// <param name="ClearAll">
///	If TRUE, all alarm output lines are cleared
/// </param>
/// <param name="Index">
///	Specifies which alarm output line is to be cleared. Ignored if clearAll is TRUE.
/// </param>
HRESULT Agilent34980A::IAgilent34980AAlarm_Clear(VARIANT_BOOL ClearAll, long Index)
{
	HRESULT hr = S_OK;
	if( VARIANT_TRUE==ClearAll )
	{ // this requires change in the SCPI format
		PopInstrCommand();
		PushInstrCommand( "OUTP:ALAR:CLE:ALL" );
	}
	hr = InstrPrintCommand();

	return hr;
}

/// <summary>
/// Configures the instrument to scan when an alarm occurs.  If ChannelList is empty,
/// the existing scan list is used.
/// </summary>
/// <remarks>
/// 
/// </remarks>
/// <returns>
///	
/// </returns>
/// <param name="ChannelList">
///	One or more channels in the form sccc.
/// </param>
/// <param name="Channel">
///	Determines which channel will alarm.
/// </param>
/// <param name="AlarmIndex">
///	Index of the alarm output line, values range from 1 to 4.
/// </param>
/// <param name="NumSweeps">
///	Number of triggers (scans) to be taken..
/// </param>
/// <param name="UpperLimit">
///	Multiplexers: Any value between -120% and +120% of the highest range, for the
/// present function. Totalizer Channels:	Any value between 0 and 4,294,967,296
/// (32-bit totalizers).
/// </param>
HRESULT Agilent34980A::IAgilent34980AAlarm_AlarmScanSetup(BSTR ChannelList, long Channel, long AlarmIndex, long NumSweeps, double UpperLimit )
{
	//Configures the instrument to scan when an alarm occurs.  If Chan_list is empty, the existing scan list is used.
	HRESULT hr = S_OK;

	CString sList( ChannelList );
	sList.Replace( '-', ':' );

	hr = InstrPrintf( "ROUT:SCAN (@%s)", sList );
	if( FAILED(hr)) return hr;
	// TRIGger:SOURce ALAR{1|2|3|4}
	hr = InstrPrintf( "TRIG:SOUR ALARM%d", AlarmIndex );
	if( FAILED(hr)) return hr;
	// TRIGger:COUNt <NumSweeps>
	hr = InstrPrintf( "TRIG:COUN %d", NumSweeps );
	if( FAILED(hr) ) return hr;
	// CALCulate:LIMit2:UPPer <UpperLimit>, (@<ChannelNum>)
	hr = InstrPrintf( "CALC:LIM:UPP %.15g,(@%s)", UpperLimit, sList );
	if( FAILED(hr) ) return hr;
	// CALCulate:LIMit:UPPer:STATe ON, (@<ChannelNum>)
	hr = InstrPrintf( "CALC:LIM:UPP:STAT ON,(@%s)", sList );
	if( FAILED(hr) ) return hr;
	// OUTPut:ALAR{1|2|3|4}:SOURce (@<ChannelNum>)
	hr = InstrPrintf( "OUTP:ALAR%d:SOUR (@%s)", AlarmIndex, sList );
	if( FAILED(hr) ) return hr;

	hr = IAgilent34980ADisplay_MonitorChannel( ChannelList );
	if( FAILED(hr) ) return hr;
	//hr = InstrWrite(  "ROUT:MON:STAT ON;:INIT\n" );
	hr = InstrWrite(  ":INIT" );

	return hr;
}

/// <summary>
///	Sets or gets the lower limit for alarms on the specified channel.  You can set the value
/// to any number between -120% and +120% of the highest range, for the present
/// function.  The lower limit MUST ALWAYS be less than or equal to the upper
/// limit.
/// </summary>
/// <remarks>
///	
/// </remarks>
/// <param name="ChannelList">
///	One or more channels in the form sccc. Must contain only 1 entry for the getter.
/// </param>
HRESULT Agilent34980A::IAgilent34980AAlarm_get_LowerLimit(BSTR ChannelList, double* Val)
{
	HRESULT hr = S_OK;

	CString sList(ChannelList);
	if( -1 != sList.Find( ',' ) || -1!=sList.Find( ':' ) || -1 != sList.Find( '-' ) )
	{
		return ReportError( E_AGILENT34980A_MULTIPLE_CHANNELS_IN_GET, _T("IAgilent34980AAlarm_get_LowerLimit"), _T("ChannelList"));
	}
	CorrectChannelList( ChannelList, false );
	hr = InstrQueryCommand(Val);

	return hr;
}

/// <summary>
///	Sets or gets the lower limit for alarms on the specified channel.  You can set the value
/// to any number between -120% and +120% of the highest range, for the present
/// function.  The lower limit MUST ALWAYS be less than or equal to the upper
/// limit.
/// </summary>
/// <remarks>
///	
/// </remarks>
/// <param name="ChannelList">
///	One or more channels in the form sccc. Must contain only 1 entry for the getter.
/// </param>
HRESULT Agilent34980A::IAgilent34980AAlarm_put_LowerLimit(BSTR ChannelList, double Val)
{
	HRESULT hr = S_OK;

	CorrectChannelList( ChannelList );
	hr = InstrPrintCommand();

	return hr;
}

/// <summary>
///	Enables/Disables the lower alarm limit on the specified channel.
/// </summary>
/// <remarks>
///	
/// </remarks>
/// <param name="ChannelList">
///	One or more channels in the form sccc. Must contain only 1 entry for the getter.
/// </param>
HRESULT Agilent34980A::IAgilent34980AAlarm_get_LowerLimitEnable(BSTR ChannelList, VARIANT_BOOL* Val)
{
	HRESULT hr = S_OK;

	CString sList(ChannelList);
	if( -1 != sList.Find( ',' ) || -1!=sList.Find( ':' ) || -1 != sList.Find( '-' ) )
	{
		return ReportError( E_AGILENT34980A_MULTIPLE_CHANNELS_IN_GET, _T("IAgilent34980AAlarm_get_LowerLimitEnable"), _T("ChannelList"));
	}
	CorrectChannelList( ChannelList, false );
	CString sResp;
	hr = InstrQueryCommand(sResp, DEFAULT_STRING_LENGTH );
	sResp.Remove( '+' );
	sResp.Remove( '\n' );
	if( sResp=="1" )
		*Val = VARIANT_TRUE;
	else if( sResp=="0" )
		*Val = VARIANT_FALSE;
	else return ReportError( IDS_E_IVI_UNEXPECTED_RESPONSE );
	return hr;
}

/// <summary>
///	Enables/Disables the lower alarm limit on the specified channel.
/// </summary>
/// <remarks>
///	
/// </remarks>
/// <param name="ChannelList">
///	Specifies the list of channels in interest. Must contain only 1 entry for the getter.
/// </param>
HRESULT Agilent34980A::IAgilent34980AAlarm_put_LowerLimitEnable(BSTR ChannelList, VARIANT_BOOL Val)
{
	HRESULT hr = S_OK;

	CorrectChannelList( ChannelList );
	hr = InstrPrintCommand();

	return hr;
}

/// <summary>
///	Sets or gets the configuration of the four alarm output lines.  Applies to all
/// four alarm output lines.
/// </summary>
/// <remarks>
///	
/// </remarks>
HRESULT Agilent34980A::IAgilent34980AAlarm_get_Mode(Agilent34980AAlarmModeEnum* Val)
{
	HRESULT hr = S_OK;

	hr = InstrQueryCommandEnum(Val);

	return hr;
}

/// <summary>
///	Sets or gets the configuration of the four alarm output lines.  Applies to all
/// four alarm output lines.
/// </summary>
/// <remarks>
///	
/// </remarks>
HRESULT Agilent34980A::IAgilent34980AAlarm_put_Mode(Agilent34980AAlarmModeEnum Val)
{
	HRESULT hr = S_OK;

	hr = InstrPrintCommand();

	return hr;
}

/// <summary>
///	Read the alarm data from the output queue.
/// </summary>
/// <remarks>
///	One alarm message is read and deleted from the queue each time this method is
/// executed.
/// </remarks>
HRESULT Agilent34980A::IAgilent34980AAlarm_get_QueryAlarmQueue(BSTR* Val)
{
	HRESULT hr = S_OK;

	hr = InstrQueryCommand(Val);

	return hr;
}

/// <summary>
///	Sets or gets the slope of the pulse from the alarm outputs.  !!! Note that changing the
/// slope of the output lines may cause the lines to change state.
/// </summary>
/// <remarks>
///	
/// </remarks>
HRESULT Agilent34980A::IAgilent34980AAlarm_get_Slope(Agilent34980ASlopeEnum* Val)
{
	HRESULT hr = S_OK;

	hr = InstrQueryCommandEnum(Val);

	return hr;
}

/// <summary>
///	Sets or gets the slope of the pulse from the alarm outputs.  !!! Note that changing the
/// slope of the output lines may cause the lines to change state.
/// </summary>
/// <remarks>
///	
/// </remarks>
HRESULT Agilent34980A::IAgilent34980AAlarm_put_Slope(Agilent34980ASlopeEnum Val)
{
	HRESULT hr = S_OK;

	hr = InstrPrintCommand();

	return hr;
}

/// <summary>
///	Sets or gets the Alarm source currently used by the specified channel.
/// </summary>
/// <remarks>
///	This is the alarm output line that will be driven when an alarm occurs on that
/// channel.  By default, all channels that may alarm are assigned to Alarm 1 at
/// reset and power on.
/// </remarks>
/// <param name="Index">
///	Index of the alarm line; value is one of [1|2|3|4]
/// </param>
HRESULT Agilent34980A::IAgilent34980AAlarm_get_Source(long Index, BSTR* Val)
{
	HRESULT hr = S_OK;

	hr = InstrQueryCommand(Val);

	return hr;
}

/// <summary>
///	Sets or gets the Alarm source currently used by the specified channel.
/// </summary>
/// <remarks>
///	This is the alarm output line that will be driven when an alarm occurs on that
/// channel.  By default, all channels that may alarm are assigned to Alarm 1 at
/// reset and power on.
/// </remarks>
/// <param name="Index">
///	Index of the alarm line; value is one of [1|2|3|4]
/// </param>
HRESULT Agilent34980A::IAgilent34980AAlarm_put_Source(long Index, BSTR Val)
{
	HRESULT hr = S_OK;

	hr = InstrPrintCommand();

	return hr;
}

/// <summary>
///	Sets or gets the upper limit for alarms on the specified channels.
/// </summary>
/// <remarks>
///	You can set the value to any number between -120% and +120% of the highest range,
/// for the present function.  The lower limit MUST ALWAYS be less than or equal
/// to the upper
/// </remarks>
/// <param name="ChannelList">
///	Specifies the list of channels in interest. Must contain only 1 entry for the
/// getter.
/// </param>
HRESULT Agilent34980A::IAgilent34980AAlarm_get_UpperLimit(BSTR ChannelList, double* Val)
{
	HRESULT hr = S_OK;

	CString sList(ChannelList);
	if( -1 != sList.Find( ',' ) || -1!=sList.Find( ':' ) || -1 != sList.Find( '-' ) )
	{
		return ReportError( E_AGILENT34980A_MULTIPLE_CHANNELS_IN_GET, _T("IAgilent34980AAlarm_get_UpperLimit"), _T("ChannelList"));
	}
	CorrectChannelList( ChannelList, false );
	hr = InstrQueryCommand( Val );
	return hr;
}

/// <summary>
///	Sets or gets the upper limit for alarms on the specified channels.
/// </summary>
/// <remarks>
///	You can set the value to any number between -120% and +120% of the highest range,
/// for the present function.  The lower limit MUST ALWAYS be less than or equal
/// to the upper
/// </remarks>
/// <param name="ChannelList">
///	Specifies the list of channels in interest. Must contain only 1 entry for the
/// getter.
/// </param>
HRESULT Agilent34980A::IAgilent34980AAlarm_put_UpperLimit(BSTR ChannelList, double Val)
{
	HRESULT hr = S_OK;

	CorrectChannelList( ChannelList );

	hr = InstrPrintCommand();

	return hr;
}

/// <summary>
///	Enables/Disables the upper alarm limit on the specified channel.
/// </summary>
/// <remarks>
///	
/// </remarks>
/// <param name="ChannelList">
///	Specifies the list of channels in interest. Must contain only 1 entry for the getter.
/// </param>
HRESULT Agilent34980A::IAgilent34980AAlarm_get_UpperLimitEnable(BSTR ChannelList, VARIANT_BOOL* Val)
{
	HRESULT hr = S_OK;

	CString sList(ChannelList);
	if( -1 != sList.Find( ',' ) || -1!=sList.Find( ':' ) || -1 != sList.Find( '-' ) )
	{
		return ReportError( E_AGILENT34980A_MULTIPLE_CHANNELS_IN_GET, _T("IAgilent34980AAlarm_get_UpperLimitEnable"), _T("ChannelList"));
	}
	CorrectChannelList( ChannelList, false );
	CString sResp;
	hr = InstrQueryCommand(sResp, DEFAULT_STRING_LENGTH );
	sResp.Remove( '+' );
	sResp.Remove( '\n' );
	if( sResp=="1" )
		*Val = VARIANT_TRUE;
	else if( sResp=="0" )
		*Val = VARIANT_FALSE;
	else return ReportError( IDS_E_IVI_UNEXPECTED_RESPONSE );

	return hr;
}

/// <summary>
///	Enables/Disables the upper alarm limit on the specified channel.
/// </summary>
/// <remarks>
///	Enables/Disables the upper alarm limit on the specified channel.
/// </remarks>
/// <param name="ChannelList">
///	One or more channels in the form sccc. 
/// </param>
HRESULT Agilent34980A::IAgilent34980AAlarm_put_UpperLimitEnable(BSTR ChannelList, VARIANT_BOOL Val)
{
	HRESULT hr = S_OK;

	CorrectChannelList( ChannelList );

	hr = InstrPrintCommand();

	return hr;
}


