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

#define RETURN_IF_FAIL(x) {hr = x; if( FAILED(hr) ) return hr;}

class sptrarray
{
	void *pdata;
public:
	sptrarray(void *p):pdata(p){}
	~sptrarray() {delete []pdata; }
};








/// <summary>
/// Downloads user defined data to the bank.
/// </summary>
/// <remarks>
/// The name of the trace must start with a character and maybe up to 12 characters
/// in length.  The name has to be unique to the bank.  The data is interpreted
/// as BYTE, WORD, or LONG WORD based on the width of the first channel on the bank.
/// Changing the width of the bank, will clear all downloaded traces.  Downloading
/// data is not allowed while memory is enabled. If the bank does not already have
/// a trace assigned to it, the downloaded trace will become the assigned trace.
/// </remarks>
/// <returns>
///	
/// </returns>
/// <param name="Channel">
///	Single channel in the form sccc.
/// </param>
/// <param name="Name">
///	Trace name, up to 12 characters in length.
/// </param>
/// <param name="Data">
///	Data to be downloaded.
/// </param>
/// <param name="Width">
///	Specifies the width of the channel. It must match the width of the first channel
/// on the bank.
/// </param>
/// <param name="Points">
///	Number of points in the data.
/// </param>
HRESULT Agilent34950A::IAgilent34950ATrace_CreateCustom(BSTR Channel, BSTR Name, SAFEARRAY** Data, Agilent34950AChannelWidthEnum Width, long Points)
{
	HRESULT hr = S_OK;

	long *pDataLong = new long[Points];
	char *pDataChar = new char[Points];
	short *pDataShort = new short[Points];
	long nActualLen = 0;
	try
	{
		CSafeArray<long>::Write( *Data, pDataLong, Points, &nActualLen );
	}
	catch(...)
	{
		return ReportError( IDS_E_IVI_INVALID_VALUE, Points, "IAgilent34950ATrace_CreateCustom", "Points" );
	}

	CString sCmd;
	sCmd.Format(":TRAC:DIG:%s (@%s), %s, ", 
		EnumToString<Agilent34950AChannelWidthEnum>( Width ),
		LPCTSTR(COLE2T(Channel)), 
		LPCTSTR(COLE2T(Name)) );

	if( Width==Agilent34950AChannelWidthByte )
	{ 
		for( int i=0; i<Points; ++i )
		{
			pDataChar[i] = (char)pDataLong[i];
		}
		hr = FormattedWriteIEEEBlock( sCmd, (BYTE*)pDataChar, Points );
	}
	else if( Width==Agilent34950AChannelWidthWord )
	{ 
		for( int i=0; i<Points; ++i )
		{
			pDataShort[i] = (short)pDataLong[i];
		}
		hr = FormattedWriteIEEEBlock( sCmd, pDataShort, Points );
	}
	else if( Width==Agilent34950AChannelWidthLWord )
	{
		hr = FormattedWriteIEEEBlock( sCmd, pDataLong, Points );
	}
	else //if there was C-style cast on Width
		return ReportErrorEx( IDS_E_IVI_INVALID_VALUE, "%s%s%s", Width, "IAgilent34950ATrace_CreateCustom", "Width" );

	return hr;
}





/// <summary>
/// Generates and downloads a predefined trace to the bank.
/// </summary>
/// <remarks>
/// The name has to be unique to the bank. TIP: The user can get a count down, or
/// a walking zero’s pattern by inverting the polarity of the channels.  Changing
/// the width of the bank, will clear all downloaded traces. Downloading data is
/// not allowed while memory is enabled. If the bank does not have a trace assigned
/// to it, the downloaded trace will become the assigned trace.
/// </remarks>
/// <returns>
///	
/// </returns>
/// <param name="Channel">
///	Single channnel in the form sccc.
/// </param>
/// <param name="Type">
///	The COUNT trace is a simple count up pattern (0,1,2,…).  The WONes is a walking
/// ones pattern.
/// </param>
/// <param name="Name">
///	The name of the trace; must start with a character and maybe up to 12 characters
/// in length.
/// </param>
/// <param name="Points">
///	The length of the trace in number of samples and must fit in the available space.
/// </param>
HRESULT Agilent34950A::IAgilent34950ATrace_CreateStandard(BSTR Channel, Agilent34950ATraceTypeEnum Type, BSTR Name, long Points)
{
	HRESULT hr = S_OK;

	hr = InstrPrintCommand();

	return hr;
}

/// <summary>
/// Deletes a trace of the given name from the bank.
/// </summary>
/// <remarks>
/// For the 34950, deleting is not allowed while memory is enabled.
/// </remarks>
/// <returns>
///	
/// </returns>
/// <param name="Channel">
///	Single channel in the form sccc.
/// </param>
/// <param name="Name">
///	Trace name.
/// </param>
HRESULT Agilent34950A::IAgilent34950ATrace_Delete(BSTR Channel, BSTR Name)
{
	HRESULT hr = S_OK;

	hr = InstrPrintCommand();

	return hr;
}

/// <summary>
/// Deletes all traces on the bank.
/// </summary>
/// <remarks>
/// For the 34950, deleting is not allowed while memory is enabled.
/// </remarks>
/// <returns>
///	
/// </returns>
/// <param name="Channel">
///	Single channel in the form sccc.
/// </param>
HRESULT Agilent34950A::IAgilent34950ATrace_DeleteAll(BSTR Channel)
{
	HRESULT hr = S_OK;

	hr = InstrPrintCommand();

	return hr;
}

/// <summary>
///	Returns commas separated names of the traces on the bank.
/// </summary>
/// <remarks>
///	
/// </remarks>
/// <param name="Channel">
///	Single channel in the for sccc.
/// </param>
HRESULT Agilent34950A::IAgilent34950ATrace_get_Catalog(BSTR Channel, BSTR* val)
{
	HRESULT hr = S_OK;

	hr = InstrQueryCommand(val);

	return hr;
}

/// <summary>
///	Returns the amount of free space on the bank in terms of number of samples.
/// </summary>
/// <remarks>
///	
/// </remarks>
/// <param name="Channel">
///	Single channel in the form sccc.
/// </param>
HRESULT Agilent34950A::IAgilent34950ATrace_get_MemoryFree(BSTR Channel, long* val)
{
	HRESULT hr = S_OK;

	hr = InstrQueryCommand(val);

	return hr;
}

/// <summary>
/// Returns the length of the given trace in number of samples.
/// </summary>
/// <remarks>
/// 
/// </remarks>
/// <returns>
///	
/// </returns>
/// <param name="Channel">
///	Single channel in the form sccc.
/// </param>
/// <param name="TraceName">
///	Name of the trace.
/// </param>
HRESULT Agilent34950A::IAgilent34950ATrace_GetPoints(BSTR Channel, BSTR TraceName, long* val)
{
	HRESULT hr = S_OK;

	hr = InstrQueryCommand(  val );

	return hr;
}
