#pragma once
#include "BaseCommunication.h"
#include "BaseEnumeration.h"
#include "BaseDataRecorder.h"
#include "AvailableResolution.h"
#include "SoftwareVersion.h"
#include "ContaminationStatus.h"
#include "ConfigurationResult.h"
#ifdef STARFLEETTOOLBOX_EXPORTS
#define BASESENSOR __declspec(dllexport)
#else
#define BASESENSOR __declspec(dllimport)
#endif


#ifdef LEUZE
#pragma message("---------------------------------------------------------------------------------- Leuze compilation --------------------------------------------------------------------------")
#endif
/// <summary>
/// Basic representation of a sensor. Must be inherited by subclasses in charge of sensor implementation
/// This base class encapsulate the communication mechanism 
/// </summary>
class BASESENSOR BaseSensor abstract
{
public:
	/// <summary>
	/// Base constructor
	/// </summary>
	BaseSensor();

	/// <summary>
	/// Copy constructor (sets the communication layer)
	/// </summary>
	/// <param name="comm">The communication layer to be used</param>
	BaseSensor(BaseCommunication* comm);

	/// <summary>
	/// Destructor
	/// </summary>
	~BaseSensor();

	/// <summary>
	/// Returns the communication layer
	/// </summary>
	/// <returns>A pointer to the basic communication layer encapsulation</returns>
	BaseCommunication* GetCommunication();

	/// <summary>
	/// Sets the communication layer
	/// </summary>
	/// <param name="pCom">The communication layer to be set</param>
	void SetCommunication(BaseCommunication* pCom); 

	/// <summary>
	/// Returns the data recorder
	/// </summary>
	/// <returns>A pointer to the basic data recorder layer encapsulation</returns>
	BaseDataRecorder* GetDataRecorder();

	/// <summary>
	/// Sets the data recorder
	/// </summary>
	/// <param name="pDataRecorder">The data recorder layer to be set</param>
	void SetDataRecorder(BaseDataRecorder* pDataRecorder);

	/// <summary>
	/// Pure virtual definition of a function that will initialise the
	/// extend class (connection, threads creation etc.)
	/// </summary>
	virtual CommunicationStatus Initialize() = 0;

	/// <summary>
	/// Pure virtual method that closes all communication
	/// stops all threads and cleanup memory
	/// This method must be called when finishing usage of sensor
	/// </summary>
	virtual void Close() = 0;

	/// <summary>
	/// Pure virtual definition of a function that will help the caller
	/// to retrieve the data
	/// </summary>
	/// <returns></returns>
	virtual RawData RetrieveRawData() = 0;

	/// <summary>
	/// Gets the platform version
	///</summary>
	/// <returns>a uint16_t containing the version number</returns>
	virtual uint16_t GetPlatformVersion() = 0;

	/// <summary>
	/// Gets available ensor resolutions
	/// </summary>
	/// <returns></returns>
	vector<AvailableResolution> GetAvailableResolutions();

	static vector<AvailableResolution> GetAvailableResolutions(PRODUCT_IDENTIFICATION productIdentifier);

	/// <summary>
	/// Gets the sensor version data
	/// </summary>
	/// <returns>An encapsulation representing the sensor version</returns>
	virtual SoftwareVersion GetVersion() = 0;

	/// <summary>
	/// Gets the sensor's name 
	/// </summary>
	/// <returns>A string representing the sensor's name</returns>
	virtual string GetDeviceName() = 0;

	/// <summary>
	/// Gets the sensor runtime hours
	/// </summary>
	/// <returns>A long representing the sensor's runtime hours</returns>
	virtual long GetRuntimeHours() = 0;

	/// <summary>
	/// Gets the temperature
	/// </summary>
	/// <returns>An integer representing the sensor's temperature</returns>
	virtual int GetTemperature() = 0;

	/// <summary>
	/// Sets the sensor's name 
	/// </summary>
	/// <returns>A string representing the sensor's name</returns>
	virtual ConfigurationResult SetDeviceName(string pName) = 0;

	/// <summary>
	/// Gets the contamination status
	/// </summary>
	/// <returns>An ContaminationStatus representing the contamination status</returns>
	virtual ContaminationStatus GetContaminationStatus() = 0;
protected:
	MethodCompatibility GetMethodCompatibility(Method method);
	char ComputeChecksum(string pTocompute);
	string ComputeBinaryCommand(string pToCompute);
#ifdef LEUZE
	// RAW commands headers
	string HEADER = { 0x02 , 0x4C, (char)0x45,(char)0x55, 0x5A, 0x45 }; //Start of text	
#else
	// RAW commands headers
	string HEADER = { 0x02 , 0x02, (char)0xBE,(char)0xA0, 0x12, 0x34 }; //Start of text
#endif
	
	string CHECKSUM = { 0x03 }; // Computed end of text
	string cRN = { 0x63, 0x52, 0x4E }; //Command read by name
	string cWN = { 0x63, 0x57, 0x4E }; //Command write by name
	string cRA = { 0x63, 0x52, 0x41 }; //Response read command
	string cWA = { 0x63, 0x57, 0x41 }; //Response write command
	string SPC = { 0x20 }; //Space

	// RAW commands
	string SendMDI = { 0x53 ,0x65 ,0x6E ,0x64 ,0x4D ,0x44 ,0x49 };
	string StopMDI = { 0x53 ,0x74 ,0x6F ,0x70 ,0x4D ,0x44 ,0x49 };

	string GetIP = { 0x47, 0x65, 0x74, 0x49, 0x50 };
	string GetGW = { 0x47 ,0x65 ,0x74 ,0x47 ,0x57 };
	string GetMask = { 0x47 ,0x65 ,0x74 ,0x4D ,0x61 ,0x73 ,0x6B };
	string GetDHCP = { 0x47 ,0x65 ,0x74 ,0x44 ,0x48 ,0x43 ,0x50 };
	string GetProto = { 0x47 ,0x65 ,0x74 ,0x50 ,0x72 ,0x6F ,0x74 ,0x6F };
	string GetPort = { 0x47 ,0x65 ,0x74 ,0x50 ,0x6F ,0x72 ,0x74 };
	string GetPType = { 0x47 ,0x65 ,0x74 ,0x50 ,0x54 ,0x79 ,0x70, 0x65 };
	string GetResol = { 0x47 ,0x65 ,0x74 ,0x52 ,0x65 ,0x73 ,0x6F, 0x6C };
	string GetDir = { 0x47 ,0x65 ,0x74 ,0x44 ,0x69 ,0x72 };
	string GetRange = { 0x47 ,0x65 ,0x74 ,0x52, 0x61, 0x6E, 0x67, 0x65 };
	string GetSkip = { 0x47 ,0x65 ,0x74 ,0x53, 0x6B, 0x69, 0x70 };
	string GetCont = { 0x47 ,0x65 ,0x74 ,0x43, 0x6F, 0x6E, 0x74 };
	string GetStat = { 0x47 ,0x65 ,0x74 ,0x53, 0x74, 0x61, 0x74 };
	string GetVer = { 0x47 ,0x65 ,0x74 ,0x56, 0x65, 0x72 };
	string GetPLVerBin = { 0x47, 0x65, 0x74, 0x50, 0x4C, 0x56, 0x65, 0x72 };
	string GetTem = { 0x47 ,0x65 ,0x74 ,0x54, 0x65, 0x6D };
	string GetELog = { 0x47 ,0x65 ,0x74 ,0x45, 0x4C, 0x6F, 0x67 };
	string GetLED = { 0x47 ,0x65 ,0x74 ,0x4C, 0x45, 0x44 };
	string GetLamp = { 0x47 ,0x65 ,0x74 ,0x4C, 0x61, 0x6D, 0x70 };
	string GetEthCfg = { 0x47 ,0x65 ,0x74 ,0x45 ,0x74 ,0x68, 0x43, 0x66, 0x67 };
	string GetHours = { 0x47 ,0x65 ,0x74 ,0x48 ,0x6F ,0x75, 0x72, 0x73 };
	string GetName = { 0x47 ,0x65 ,0x74 ,0x4E ,0x61 ,0x6D, 0x65 };
	string GetFilter = { 0x47 ,0x65 ,0x74 ,0x46 ,0x69 ,0x6C, 0x74, 0x65 , 0x72 };
	string GetWCalib = { 0x47 ,0x65 ,0x74, 0x57, 0x43, 0x61, 0x6C, 0x69, 0x62 };
	string GetWinStat = { 0x47, 0x65, 0x74, 0x57, 0x69, 0x6E, 0x53, 0x74, 0x61, 0x74 };

	string GetECode = { 0x47 ,0x65 ,0x74 ,0x45 ,0x43 ,0x6F, 0x64, 0x65 };

	string SetIP = { 0x53, 0x65, 0x74, 0x49, 0x50 };
	string SetGW = { 0x53, 0x65, 0x74, 0x47, 0x57 };
	string SetMask = { 0x53, 0x65, 0x74, 0x4D, 0x61, 0x73, 0x6B };
	string SetDHCP = { 0x53, 0x65, 0x74, 0x44, 0x48, 0x43, 0x50 };
	string SetProto = { 0x53, 0x65, 0x74, 0x50, 0x72, 0x6F, 0x74,0x6F };
	string SetPort = { 0x53, 0x65, 0x74, 0x50, 0x6F, 0x72, 0x74 };
	string SetPType = { 0x53, 0x65, 0x74, 0x50, 0x54, 0x79, 0x70, 0x65 };
	string SetResol = { 0x53, 0x65, 0x74, 0x52,0x65, 0x73, 0x6F, 0x6C };
	string SetDir = { 0x53, 0x65, 0x74, 0x44, 0x69, 0x72 };
	string SetRange = { 0x53, 0x65, 0x74, 0x52, 0x61, 0x6E, 0x67, 0x65 };
	string SetSkip = { 0x53, 0x65, 0x74, 0x53, 0x6B, 0x69, 0x70 };
	string SetCont = { 0x53, 0x65, 0x74, 0x43, 0x6F, 0x6E, 0x74 };
	string SetLED = { 0x53, 0x65, 0x74, 0x4C, 0x45, 0x44 };
	string SetEthCfg = { 0x53 ,0x65 ,0x74 ,0x45 ,0x74 ,0x68, 0x43, 0x66, 0x67 };
	string SetName = { 0x53 ,0x65 ,0x74 ,0x4E ,0x61 ,0x6D, 0x65 };
	string SetFilter = { 0x53 ,0x65 ,0x74 ,0x46 ,0x69 ,0x6C, 0x74, 0x65 , 0x72 };
	string SetWCalib = { 0x53 ,0x65 ,0x74, 0x57, 0x43, 0x61, 0x6C, 0x69, 0x62 };

	string Reset = { 0x52, 0x65, 0x73, 0x65, 0x74 };
	string Reboot = { 0x52, 0x65, 0x62, 0x6F, 0x6F, 0x74 };
protected:
	SoftwareVersion __version;
private:
	BaseCommunication* _comm;
	BaseDataRecorder* _recorder = NULL;	
};

