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


/// <summary>
/// Stores (saves) the current instrument state in the specified storage location.
/// </summary>
/// <remarks>
/// Any state previously stored in the same location is overwritten (no error is
/// generated).
/// </remarks>
/// <returns>
///	
/// </returns>
/// <param name="Identifier">
///	Identifies which storage location is to be used for saving the state. Value
/// must be able to be mapped to one of the locations either by number (single character
/// 1 to 5) or there must be an empty location to store under the name supplied.
/// </param>
HRESULT Agilent34980A::IAgilent34980AMemory_SaveState(BSTR Identifier)
{
	HRESULT hr = S_OK;
	CString sID( Identifier );
	if( sID.GetLength()==1 )
	{
		if( sID[0]<'0' && sID[0]>'5' )
			return ReportInvalidValueError( _T("IAgilent34980AMemory_SaveState"), _T("Identifier"), Identifier );
		return InstrPrintCommand(); // '0' to '5' already in command
	}
	CString sResp, sToken=",";
	RETURN_IF_FAIL( InstrQueryf( "MEM:STAT:CAT?", sResp, DEFAULT_STRING_LENGTH ) );
	sResp.Remove( '\"' );
	int nPos = 0;
	bool bFound = false;
	for( int i=1; i<6 && sToken!=""; i++ )
	{
		sToken = sResp.Tokenize( ",", nPos );
		if( sToken==sID )
		{ // same name found
			hr = InstrPrintf( "*SAV %d", i );
			bFound = true;
			break;
		}
	}
	nPos = 0;
	if( !bFound )
   {
		long lPos;
		for( int i=1; i<6; i++ )
		{
			RETURN_IF_FAIL( InstrQueryf( "MEM:STAT:VALID? %d", &lPos, i ) );
			if( lPos==0 )
			{ // empty location; store the name too
				hr = InstrPrintf( "*SAV %d", i );
				hr = InstrPrintf( "MEM:STAT:NAME %d, %s", i, sID );
				bFound = true;
				break;
			}
		}
   } 
	if( !bFound )
		return ReportError( E_AGILENT34980A_LOCATIONS_BUSY );
	return hr;
}


/// <summary>
/// Recalls the instrument state stored in the specified storage location.
/// </summary>
/// <remarks>
/// You cannot recall the instrument state from a storage location that is empty
/// or was deleted.   When shipped from the factory, storage locations 1 through
/// 5 are empty (location 0 has the power-on state).
/// </remarks>
/// <returns>
///	
/// </returns>
/// <param name="Identifier">
///	Identifies which storage location is to be used for saving the state. Value
/// must be able to be mapped to one of the locations either by number (single character
/// 1 to 5) or there must be an empty location to store under the name supplied.
/// </param>
HRESULT Agilent34980A::IAgilent34980AMemory_RecallState(BSTR Identifier)
{
	HRESULT hr = S_OK;

	CString sID( Identifier );
	sID.MakeUpper();
	if( sID.GetLength()==1 && sID[0]>'0' && sID[0]<'6' )
	{
		return InstrPrintCommand(); // '1' to '5' already in command
	}
	CString sResp, sToken=",";
	RETURN_IF_FAIL( InstrQueryf( "MEM:STAT:CAT?", sResp, DEFAULT_STRING_LENGTH ) );
	sResp.Remove( '\"' );
	int nPos = 0;
	bool bFound = false;
	for( int i=1; i<6 && sToken!=""; i++ )
	{
		sToken = sResp.Tokenize( ",", nPos );
		if( sToken==sID )
		{
			hr = InstrPrintf( "*RCL %d", i );
			bFound = true;
			break;
		}
	}
	if( !bFound )
		return ReportInvalidValueError( _T("IAgilent34980AMemory_RecallState"), _T("Identifier"), Identifier);

	return hr;
}


/// <summary>
/// Deletes the contents of the specified storage location.
/// </summary>
/// <remarks>
/// If you have given a  storage location a name, this method does not remove said
/// name.
/// </remarks>
/// <returns>
///	
/// </returns>
/// <param name="LocationNum">
///	Identifies which storage location is to be deleted. Value must be one of {0|1|2|3|4|5}.
/// </param>
/// <param name="DeleteAll">
///	If TRUE, all storage locations (0 through 5) are deleted.
/// </param>
HRESULT Agilent34980A::IAgilent34980AMemory_DeleteLocation(long LocationNum, VARIANT_BOOL DeleteAll)
{
	HRESULT hr = S_OK;

	if( DeleteAll==VARIANT_FALSE )
		hr = InstrPrintCommand(); // MEMory:STATe:DELete {0|1|2|3|4|5}
	else 
		hr = InstrPrintf( "MEMory:STATe:DELete:ALL" );

	return hr;
}

/// <summary>
///	Enables/disables the automatic recall of the power-down state from storage location
/// 0 when power is turned on.  Select OFF to issue a Factory Reset.
/// </summary>
/// <remarks>
///	
/// </remarks>
HRESULT Agilent34980A::IAgilent34980AMemory_get_AutoRecall(VARIANT_BOOL* Val)
{
	HRESULT hr = S_OK;

	hr = InstrQueryCommandBool(Val);

	return hr;
}

/// <summary>
///	Enables/disables the automatic recall of the power-down state from storage location
/// 0 when power is turned on.  Select OFF to issue a Factory Reset.
/// </summary>
/// <remarks>
///	
/// </remarks>
HRESULT Agilent34980A::IAgilent34980AMemory_put_AutoRecall(VARIANT_BOOL Val)
{
	HRESULT hr = S_OK;

	hr = InstrPrintCommand();

	return hr;
}

/// <summary>
///	Returns the number of memory locations that are available for state storage.
///  Always returns 6.
/// </summary>
/// <remarks>
///	
/// </remarks>
HRESULT Agilent34980A::IAgilent34980AMemory_get_NumStates(long* Val)
{
	HRESULT hr = S_OK;

	hr = InstrQueryCommand(Val);

	return hr;
}

/// <summary>
///	Sets or gets the name connected to the specified memory location.
/// </summary>
/// <remarks>
///	Memory location is a numeric value 1 through 5.  Instrument state names are
/// upper-case, so are not case sensitive.  Use the Memory/SaveState and Memory/RecallState
/// methods to save and recall named states.
/// </remarks>
/// <param name="LocationNum">
///	Identifies the storage location of interest. Value must be one of {0|1|2|3|4|5}.
/// </param>
HRESULT Agilent34980A::IAgilent34980AMemory_get_StateName(long LocationNum, BSTR* Val)
{
	HRESULT hr = S_OK;

	hr = InstrQueryCommand(Val);

	return hr;
}

/// <summary>
///	Sets or gets the name connected to the specified memory location.
/// </summary>
/// <remarks>
///	Memory location is a numeric value 1 through 5.  Instrument state names are
/// upper-case, so are not case sensitive.  Use the Memory/SaveState and Memory/RecallState
/// methods to save and recall named states.
/// </remarks>
/// <param name="LocationNum">
///	Identifies the storage location of interest. Value must be one of {0|1|2|3|4|5}.
/// </param>
HRESULT Agilent34980A::IAgilent34980AMemory_put_StateName(long LocationNum, BSTR Val)
{
	HRESULT hr = S_OK;

	hr = InstrPrintCommand();

	return hr;
}

/// <summary>
///	Determines if a valid state has been stored in the specified memory location.
///  The valid location numbers are 1 through 5.
/// </summary>
/// <remarks>
///	
/// </remarks>
/// <param name="LocationNum">
///	Identifies the storage location of interest. Value must be one of {0|1|2|3|4|5}.
/// </param>
HRESULT Agilent34980A::IAgilent34980AMemory_get_ValidState(long LocationNum, VARIANT_BOOL* Val)
{
	HRESULT hr = S_OK;

	hr = InstrQueryCommandBool(Val);

	return hr;
}




/// <summary>
///	This property returns the names assigned to storage locations 0 through 5.
/// </summary>
/// <remarks>
///	When shipped from the factory, default names are assigned to storage locations
/// 0 through 5 (STATE_0, STATE_1, STATE_2, etc.).
/// </remarks>
HRESULT Agilent34980A::IAgilent34980AMemory_get_Catalog(BSTR* Val)
{
	HRESULT hr = S_OK;

	hr = InstrQueryCommand( Val );

	return hr;
}
