struct IUnknown; // Workaround for "combaseapi.h(229): error C2187: syntax error: 'identifier' was unexpected here" when using /permissive-

#include <cstdio>
#define _USE_MATH_DEFINES
#include <math.h>

#include "ClientAPI.h"

// insert the IP of your SP-ICE-3
const char* CARD_IP = "192.168.2.138";

static rlResult markDashedPattern(rlHandle handle);
static int printLastError(void);

int main()
{
	// establish a connection with the card
	rlHandle handle = rlConnect(CARD_IP, 49374);
	if (handle < 0)
		return printLastError();

	rlResult status;
	// Reset the card to its default settings:
	// This restores all settings to the values that were last saved on the card.
	if ((status = rlSystemResetToDefaults(handle)) != rlSUCCESS) goto Cleanup;

	rlLaserConfig lc;
	if ((status = rlLaserGetConfig(handle, &lc)) != rlSUCCESS) goto Cleanup;
	lc.PowerScale = 1.0;
	if ((status = rlLaserSetConfig(handle, &lc)) != rlSUCCESS) goto Cleanup;
	if ((status = rlLaserArmLaser(handle, true)) != rlSUCCESS) goto Cleanup;

	status = markDashedPattern(handle);

Cleanup:
	// Print any errors
	if (status != rlSUCCESS)
		printLastError();

	// Disconnect from the card
	printf("Disconnecting from card...\n");
	if (rlDisconnect(handle) != rlSUCCESS)
		return printLastError();

	printf("Exiting with status = %d\n", status);
	return status;
}

/// Mark two rectangles with dashed line enabled
static rlResult markDashedPattern(rlHandle handle)
{
	rlResult result;

	double jumpSpeed = 4;
	double markSpeed = 1;

	int listID = 143;

	// get the scanner's current field size
	rlScannerConfig sc;
	if ((result = rlScannerGetConfig(handle, &sc)) != rlSUCCESS) return result;

	double fieldSize = sc.FieldSize.X;
	double sizeX = 0.49 * fieldSize;
	double sizeY = 0.49 * fieldSize;

	// Dashed line pattern containing distances in μm
	// Pattern will be marked as follows: 2000μm on - 1000μm off - 5000μm on - 3000μm off
	// and will be repeated while marking until dashed line is disabled
	double dashedPattern[] = { 2000, 1000, 5000, 3000 };

	rlCommandListHandle list = rlListAllocate(handle);
	if ((result = rlListAppendPower(list, 65535)) != rlSUCCESS) return result;
	if ((result = rlListAppendJumpSpeed(list, jumpSpeed)) != rlSUCCESS)	return result;
	if ((result = rlListAppendJumpDelay(list, 0)) != rlSUCCESS)	return result;
	if ((result = rlListAppendMarkSpeed(list, markSpeed)) != rlSUCCESS)	return result;
	if ((result = rlListAppendPolyDelay(list, 0)) != rlSUCCESS)	return result;
	if ((result = rlListAppendMarkDelay(list, 0)) != rlSUCCESS)	return result;
	// Append the dashed pattern to the list
	if ((result = rlListAppendDashedLinePattern(list, dashedPattern, 4)) != rlSUCCESS)	return result;
	// Enable dashed line
	if ((result = rlListAppendEnableDashedLine(list, true, 0)) != rlSUCCESS)	return result;
	// Mark a large rectangle with dashed line enabled
	if ((result = rlListAppendJumpAbs2D(list, -sizeX, -sizeY)) != rlSUCCESS)	return result;
	if ((result = rlListAppendMarkAbs2D(list, -sizeX, sizeY)) != rlSUCCESS)	return result;
	if ((result = rlListAppendMarkAbs2D(list, sizeX, sizeY)) != rlSUCCESS)	return result;
	if ((result = rlListAppendMarkAbs2D(list, sizeX, -sizeY)) != rlSUCCESS)	return result;
	if ((result = rlListAppendMarkAbs2D(list, -sizeX, -sizeY)) != rlSUCCESS)	return result;

	// Mark a small rectangle with dashed line enabled
	// Set the dashed pattern position to 0
	if ((result = rlListAppendEnableDashedLine(list, true, 0)) != rlSUCCESS)	return result;
	if ((result = rlListAppendJumpAbs2D(list, -0.5 * sizeX, -0.5 * sizeY)) != rlSUCCESS)	return result;
	if ((result = rlListAppendMarkAbs2D(list, -0.5 * sizeX, 0.5 * sizeY)) != rlSUCCESS)	return result;
	if ((result = rlListAppendMarkAbs2D(list, 0.5 * sizeX, 0.5 * sizeY)) != rlSUCCESS)	return result;
	if ((result = rlListAppendMarkAbs2D(list, 0.5 * sizeX, -0.5 * sizeY)) != rlSUCCESS)	return result;
	if ((result = rlListAppendMarkAbs2D(list, -0.5 * sizeX, -0.5 * sizeY)) != rlSUCCESS)	return result;

	if ((result = rlListSet(handle, listID, list, false, -1)) != rlSUCCESS) return result;
	if ((result = rlListExecute(handle, listID)) != rlSUCCESS) return result;
	int doneID;
	bool done = false;
	if ((result = rlListWaitForListDone(handle, -1, &done, &doneID)) != rlSUCCESS) return result;

	if ((result = rlListDelete(handle, listID, true)) != rlSUCCESS) return result;

	// Release the local list: this frees the PC's memory occupied by the card
	if ((result = rlListReleaseHandle(list)) != rlSUCCESS) return result;

	return result;
}

// Helper function which displays the description of the last error
static int printLastError(void)
{
	char errBuffer[1024] = { 0 };
	rlGetLastError(errBuffer, sizeof(errBuffer) - 1);
	printf("%s", errBuffer);
	return rlERROR;
}
