#include <stdio.h>
#include <iostream>
#include <string.h>
#include <vector>
#include "example.h"
#include "htra_api.h"
using namespace std;

#define IS_USB 1 // By default, a USB-type device is used. If using an Ethernet-type device, define IS_USB as 0.

int SWP_EZGetPartialSweep()
{
	int Status = 0;      // Return value of the function.
	void* Device = NULL; // Memory address of the current device.
	int DevNum = 0;      // Specifies the device number.

	BootProfile_TypeDef BootProfile; // Boot profile structure, includes physical interface, power supply type, etc.
	BootInfo_TypeDef BootInfo;       // Boot information structure, includes device info, USB speed, etc.

	BootProfile.DevicePowerSupply = USBPortAndPowerPort; // Use both USB data port and external power port for power supply.

#if IS_USB==1
	// Configure USB interface.
	BootProfile.PhysicalInterface = USB;
#else 
	// Configure Ethernet interface.
	BootProfile.PhysicalInterface = ETH;
	BootProfile.ETH_IPVersion = IPv4;
	BootProfile.ETH_RemotePort = 5000;
	BootProfile.ETH_ReadTimeOut = 5000;
	BootProfile.ETH_IPAddress[0] = 192;
	BootProfile.ETH_IPAddress[1] = 168;
	BootProfile.ETH_IPAddress[2] = 1;
	BootProfile.ETH_IPAddress[3] = 100;
#endif

	Status = Device_Open(&Device, DevNum, &BootProfile, &BootInfo);              // Open the device.

	Device_Open_ErrorHandling(Status, &Device, DevNum, &BootProfile, &BootInfo); // If Status is not 0, perform corresponding error handling based on the return value.

	SWP_EZProfile_TypeDef SWP_EZProfileIn;  // SWP input configuration, including start/stop frequency, RBW, reference level, etc.
	SWP_EZProfile_TypeDef SWP_EZProfileOut; // SWP output configuration.
	SWP_TraceInfo_TypeDef TraceInfo;        // Trace info under the current configuration, including number of trace points, number of hops, etc.

	SWP_EZProfileDeInit(&Device, &SWP_EZProfileIn); // Initialize parameters related to SWP mode.

	SWP_EZProfileIn.StartFreq_Hz = 9e3;   // Configure start frequency.
	SWP_EZProfileIn.StopFreq_Hz = 6.35e9; // Configure stop frequency.
	SWP_EZProfileIn.RBW_Hz = 300e3;       // Configure RBW.

	Status = SWP_EZConfiguration(&Device, &SWP_EZProfileIn, &SWP_EZProfileOut, &TraceInfo); // Apply SWP mode configuration.
	if (Status == APIRETVAL_NoError)
	{
		cout << " Configuration successfully applied " << endl;
	}

	/* If device opening fails, return error message. When the following errors occur, the device cannot operate properly. It is recommended to follow the prompt and reopen the device */
	else
	{

		switch (Status)
		{
			case APIRETVAL_ERROR_BusOpenFailed:printf("Error - Check device power supply, data cable connection, and ensure that the driver is installed correctly\n");break;
			case APIRETVAL_ERROR_RFACalFileIsMissing:printf("Error - RF calibration file is missing, please copy the RF calibration file to the CalFile folder\n");break;
			case APIRETVAL_ERROR_IFACalFileIsMissing:printf("Error - IF calibration file is missing, please copy the IF calibration file to the CalFile folder\n");break;
			case APIRETVAL_ERROR_DeviceConfigFileIsMissing:printf("Error - Configuration file is missing, please copy the configuration file to the CalFile folder\n");break;
			case APIRETVAL_ERROR_DeviceSpecFileIsMissing:printf("Error - Device specification file is missing, please copy the device specification file to the CalFile folder\n");break;
			default:printf("Other error returned, Status = %d\n", Status);break;
		}

		return Status;
	}
	
	vector<double> Frequency(TraceInfo.FullsweepTracePoints);    // Create frequency array.
	vector<float> PowerSpec_dBm(TraceInfo.FullsweepTracePoints); // Create power array.
	int HopIndex = 0;                                            // Current hop index.
	int FrameIndex = 0;                                          // Current frame index.
	MeasAuxInfo_TypeDef MeasAuxInfo;                             // Auxiliary info for measurement data, includes: peak power index, peak power, device temperature, GPS coordinates, absolute timestamp, etc.

	// Loop to acquire spectrum data.
	while (1)
	{
		for (int i = 0; i < TraceInfo.TotalHops; i++) // TraceInfo.TotalHops represents the number of frames under current configuration. Call SWP_GetPartialSweep TraceInfo.TotalHops times to obtain a full trace.
		{
			Status = SWP_GetPartialSweep(&Device, Frequency.data() + i * TraceInfo.PartialsweepTracePoints, PowerSpec_dBm.data() + i * TraceInfo.PartialsweepTracePoints, &HopIndex, &FrameIndex, &MeasAuxInfo); // Acquire spectrum data.

			if (Status == APIRETVAL_NoError)
			{
				// UserCode here
				/*

				For example: display spectrum or perform other processing

				*/

			}

			/* If data acquisition fails, return error message. When the following errors occur, follow the prompts */
			else
			{
				switch (Status)
				{
				  case APIRETVAL_WARNING_IFOverflow:printf("Warning - IF saturation, it is recommended to reconfigure. Reference level <= signal power.\n"); break; // If SWP_GetPartialSweep returns -12, it is recommended to reconfigure the parameters and retry.
				  case APIRETVAL_WARNING_ReconfigurationIsRecommended:printf("Warning - The temperature variation of the current device is large. It is recommended to reconfigure the temperature.\n"); break; // If SWP_GetPartialSweep returns -14, it is recommended to reconfigure and then reacquire.
				  default:printf("Return other errors: Status = %d\n", Status); Device_Close(&Device); break;
				}
			}
		}
	}

	Device_Close(&Device); // Close the device.

	return 0;
}
