#pragma once
/*
*  This is the bridge between hidapi and unreal and contains all the rawdata of the portal
*/
#include "CoreMinimal.h"
#include "hidapi.h"
#include "SkyPortalDefinitions.h"
#include "SkyPortalFigure.h"
#include "SkyPortalIO.generated.h"

#pragma region Definitions

DECLARE_LOG_CATEGORY_EXTERN(LogHIDApi, Log, All);
DECLARE_LOG_CATEGORY_EXTERN(LogSkyportalIO, Log, All);

constexpr auto write_buf_size = 0x21; //buffer size for all the write command on portal. Should always be 0x21 - 33
constexpr auto TIMEOUT = 30000; //milliseconds

/* Portal physicial device IDs */
const int VendorIds[4] = { 0x12ba, 0x54c, 0x1430, 0x1430 };
const int ProductIds[4] = { 0x150, 0x967, 0x1f17 };

#pragma endregion


FPortalStatusData ParsePortalStatus(const uint8* StatusResponse);
EPortalCommand GetPortalCommandFromChar(unsigned char Char);
FString DataToString(const uint8* data);
FString OutputToString(const unsigned char* output);

/* Contain all the data that pass inside hidapi write + the number of bytes in case of successful write
*
* @param data all the block data, should be 0x21 sized
* @param BytesTransferred In case of successful write, print the number of byte transfered. Could be used for verifications
*/
USTRUCT()
struct FWriteBlock {
	GENERATED_BODY()
	unsigned char data[write_buf_size];
	int BytesTransferred;
};

/* This class will contain and handle all the low-lewel functions
* Should be able to be called anywhere
*/
UCLASS()
class USkyPortalIO : public UObject
{
	GENERATED_BODY()

public:
	// Constructor
	USkyPortalIO();

	/* hidapi will write error message in here*/
	UPROPERTY(BlueprintReadOnly)
	FString HidError;

	/*Portal ready to be listened or to receive commands*/
	UPROPERTY(BlueprintReadOnly)
	bool bPortalReady = false;

	/* Connect to Portal - will write the PortalDevice var if success */
	bool OpenPortalHandle();

	/* Send block to portal. In windows, don't use the hidapi */
	bool Write(FWriteBlock* Block);

	/* Send raw command to portal */
	void WriteRaw(const TArray<uint8>* block);

	/* Listen to portal
	* @return The data sended by the portal device
	*/
	uint8* Read();


	/*Trying to read a figure
	* @return
	*/
	unsigned char* QueryBlock(uint8 characterIndex, uint8 block = 0x00);

	UFigureData* ReadFigureBlocks(uint8 FigureIndex);

	/* Close connection to Portal*/
	void Close();

private:

	/*TODO: Should not be here
	bool IsFalsePositive() const;
	*/


	/* Portal device ref, useful for hidapi commands */
	hid_device* PortalDevice;

};

