#pragma once
#include "../RODxxx/RawDataSensor.h"
#include"../Toolbox/ParameterNotSupportedException.h"
#include "FilterType.h"

using namespace std;

#ifdef NAVIGATIONSENSOR_EXPORTS
#define NAVIGATIONSENSOR __declspec(dllexport)
#else
#define NAVIGATIONSENSOR __declspec(dllimport)
#endif

#define SECTORS_COUNT 264
#define IMAGE_SEGMENT_SIZE 20
#define PIXELS_PER_SEGMENT 640


#define ZERO_TO_ZERO_POINT_ZERO_FIVE_AT_TWENTY_HZ 2
#define ZERO_TO_ZERO_POINT_ZERO_TWENTYFIVE_AT_TEN_HZ 3

typedef int PAGE_INDEX;
#define CUSTOMIZE_LOGO_PAGE 0
#define OPERATING_STATUS_PAGE 1
#define WMS_STATUS_PAGE 2
#define ETH_USB_CONNECT_STATUS_PAGE 3
#define NETWORK_INFORMATION_PAGE 4
#define BLUETHOOT_CONNECTION_PAGE 5

typedef int OLED_WAKEUP_RANGE;
#define THREE_HUNDRED_MM  0
#define FIVE_HUNDRED_MM  1
#define TEN_HUNDRED_MM  2
#define FIFTEEN_HUNDRED_MM  3
#define TWENTY_HUNDRED_MM  4

typedef int OLED_WAKEUP_TIME;
#define TWO_SEC  0
#define THREE_SEC  1
#define FIVE_SEC  2
#define TEN_SEC  3

typedef unsigned int PAGE_DIRECTION;
#define NORMAL 0
#define UPSIDE_DOWN 1

typedef unsigned int DISPLAY_MODE;
#define NORMAL_MODE 0
#define ON_MODE 1
#define OFF_MODE 2

typedef unsigned int MDI_TRANSMISSION_STATUS;
#define MDI_OFF_MODE 0
#define MDI_ON_MODE 1

typedef uint16_t IMAGE_PIXEL;
typedef vector<IMAGE_PIXEL> LOGO_IMAGE_SEGMENT;

class NAVIGATIONSENSOR NavigationSensor : public RawDataSensor
{
public:
	/// <summary>
	/// Base constructor
	/// </summary>
	NavigationSensor();

	/// <summary>
	/// Destructor (disconects the data sensor)
	/// </summary>
	~NavigationSensor();

	/// <summary>
	/// Copy constructor: sets the basic communication object
	/// </summary>
	/// <param name="comm">The basic communication object</param>
	NavigationSensor(BaseCommunication* comm);

	/// <summary>
	/// Sets the angle resolution. Can be either ZERO_TO_ZERO_POINT_TWO_AT_EIGHTY_HZ, ZERO_TO_ZERO_POINT_ON_AT_FOURTY_HZ, ZERO_TO_ZERO_POINT_ZERO_FIVE_AT_TWENTY_HZ or ZERO_TO_ZERO_POINT_ZERO_ZERO_TWENTYFIVE_AT_TEN_HZ)
	/// </summary>
	/// <param name="pResolution"></param>
	/// <returns>A configuration result encapsulation</returns>
	ConfigurationResult SetAngularResolution(ANGULAR_RESOLUTION pResolution);

	/// <summary>
	/// Returns the filter type
	/// </summary>
	/// <returns>An object representing the filter type</returns>
	/// 
	FilterType GetFilterType();
	/// <summary>
	/// Sets the filter type
	/// </summary>
	/// <param name="pFilterType">A object representing the filter type</param>
	ConfigurationResult SetFilterType(FilterType pFilterType);

	/// <summary>
	/// Returns the display page index
	/// </summary>
	/// <returns>An enum givin the page index</returns>
	PAGE_INDEX GetDisplayPageIndex();

	/// <summary>
	/// Sets the display page on the given direction  (Accepted values: CUSTOMIZE_LOGO_PAGE, OPERATING_STATUS_PAGE, WMS_STATUS_PAGE, ETH_USB_CONNECT_STATUS_PAGE,NETWORK_INFORMATION_PAGE or BLUETHOOT_CONNECTION_PAGE
	/// </summary>
	/// <param name="pPageIndex">The direction index</param>
	/// <returns>A configuration result encapsulation</returns>
	ConfigurationResult SetDisplayPageIndex(PAGE_INDEX pPageIndex);
	
	/// <summary>
	/// Gets the platform version
	/// </summary>
	/// <returns>a uint16_t containing the version number</returns>
	uint16_t GetPlatformVersion();
#ifndef LEUZE
	/// <summary>
	/// Returns the display page direction
	/// </summary>
	/// <returns>An enum givin the page direction</returns>
	PAGE_DIRECTION GetDisplayPageDirection();

	/// <summary>
	/// Sets the display page on the given direction (Accepted values: NORMAL or UPDIDE_DOWN)
	/// </summary>
	/// <param name="pPageDirection">The page direction</param>
	/// <returns>A configuration result encapsulation</returns>
	ConfigurationResult SetDisplayPageDirection(PAGE_DIRECTION pPageDirection);
#endif

#ifndef LEUZE
	/// <summary>
	/// Returns the display mode (values are  NORMAL_MODE, ON_MODE or OFF_MODE)
	/// </summary>
	/// <returns>tAn enum giving the display mode</returns>
	DISPLAY_MODE GetDisplayMode();


	/// <summary>
	/// sets the display mode (Accepted values: NORMAL_MODE, ON_MODE or OFF_MODE)
	/// </summary>
	/// <param name="pdisplayMode">the display mode</param>
	/// <returns>A configuration result encapsulation</returns>
	ConfigurationResult SetDisplayMode(DISPLAY_MODE pdisplayMode);
#endif

#ifndef LEUZE
	/// <summary>
	/// Returns the sensor's logo image
	/// </summary>
	/// <returns>A vector of unsigned unsigned int 16</returns>
	vector<LOGO_IMAGE_SEGMENT> GetLogoImage();


	/// <summary>
	/// Sets the sensor's logo image
	/// </summary>
	/// <param name="pLogoImage">A vector of unsigned unsigned int 16</param>
	/// <returns>A configuration result ecpasuplation</returns>
	ConfigurationResult SetLogoImage(vector<LOGO_IMAGE_SEGMENT> pLogoImage);

	/// <summary>
	/// Resets the logo image to its default
	/// </summary>
	/// <returns>A configuration result ecpasuplation</returns>
	ConfigurationResult ResetLogoImage();
#endif

	/// <summary>
	/// Returns the window monitoring system of each sector (SECTORS_COUNT sectors - 132 -)
	/// </summary>
	/// <returns></returns>
	vector<unsigned int> GetWms() ;

	/// <summary>
	/// Gets the sensor's control status led
	/// </summary>
	/// <returns>An encapsulation representing the sensor's control status led</returns>
	SensorLeds GetSensorLeds();
	
	/// <summary>
	/// Sets the sensors external status led (ON or OFF)
	/// </summary>
	/// <param name="pLeds">The encapsulation of the leds to be set</param>
	/// <returns>A configuration result encapsulation</returns>
	ConfigurationResult SetSensorLeds(SensorLeds pLeds);

	/// <summary>
	/// Gets the sensor lamps status
	/// </summary>
	/// <returns>An encapsulation of the sensor's internal lamps status</returns>
	SensorLamps GetSensorLamps();

	// Command settings management
	// Data retrieve
	/// <summary>
	/// Gets whole data information
	/// </summary>
	/// <returns>An encapsulated way to group the network information</returns>
	NetworkInformation  GetNetworkInformation();

	/// <summary>
	/// Gets the contamination status
	/// </summary>
	/// <returns>An ContaminationStatus representing the contamination status</returns>
	ContaminationStatus GetContaminationStatus();

	// DEPRECATED METHOD

	/// <summary>
	/// Sets the sensor's immunity level
	/// </summary>
	/// <param name="pImmunityLevel">The immunity level to be set</param>
	/// <returns>A configuration result encapsulation</returns>
	[[deprecated("Use of this method is deprecated in Navigation sensor")]]
	ConfigurationResult SetImmunityLevel(int pImmunityLevel) { return NULL; }

	/// <summary>
	/// Gets the immunity level
	/// </summary>
	/// <returns>An integer representing the immunity level</returns>
	[[deprecated("Use of this method is deprecated in Navigation sensor")]]
	unsigned int GetImmunityLevel() { return -1; }
#ifndef LEUZE
	/// <summary>
	/// Returns the OLED wake up range
	/// </summary>
	/// <returns>0 for 300mm, 1 for 500mm, 2 for 1000mm, 3 for 1500mm, 4 for 2000mm</returns>
	OLED_WAKEUP_RANGE GetDisplayWakeUpRange();

	/// <summary>
	/// Sets the OLED wake up range
	/// </summary>
	/// <param name="range">>0 for 300mm, 1 for 500mm, 2 for 1000mm, 3 for 1500mm, 4 for 2000mm</param>
	/// <returns>A configuration result encapsulation</returns>
	ConfigurationResult SetDisplayWakeUpRange(OLED_WAKEUP_RANGE range);
#endif

#ifndef LEUZE
	/// <summary>
	/// Returns the OLED wake up time
	/// </summary>
	/// <returns>0 for 2sec, 1 for 3sec, 2 for 5sec, 3 for 10sec</returns>
	OLED_WAKEUP_RANGE GetDisplayWakeUpTime();

	/// <summary>
	/// Sets the OLED wake up time
	/// </summary>
	/// <param name="range">>0 for 2sec, 1 for 3sec, 2 for 5sec, 3 for 10sec</param>
	/// <returns>A configuration result encapsulation</returns>
	ConfigurationResult SetDisplayWakeUpTime(OLED_WAKEUP_RANGE range);
#endif
	/// <summary>
	/// Returns the MDI transmission status
	/// </summary>
	/// <returns>0 for OFF, 1 for ON</returns>
	MDI_TRANSMISSION_STATUS GetMdiTransmissionStatus();

	/// <summary>
	/// Shows the device identification
	/// </summary>
	void ShowDeviceIdentification();

private:
	string GetFilter = { 0x47, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72 };
	string GetPageIndex = { 0x47, 0x65, 0x74, 0x50, 0x49, 0x6E, 0x64, 0x65, 0x78 };
	string GetPageDirection = { 0x47, 0x65, 0x74, 0x50, 0x44, 0x69, 0x72 };
	string GetCustomizedLogoImage = { 0x47, 0x65, 0x74, 0x43, 0x75, 0x73, 0x74, 0x49, 0x6D, 0x67 };
	string GetDisplayPageMode = { 0x47, 0x65, 0x74, 0x50, 0x4D, 0x6F, 0x64, 0x65 };
	string GetWmsValue = { 0x47, 0x65, 0x74, 0x57, 0x6D, 0x73 };
	string GetARange = { 0x47, 0x65, 0x74, 0x41, 0x52, 0x61, 0x6E, 0x67, 0x65 };
	string GetATime = { 0x47, 0x65, 0x74, 0x41, 0x54, 0x69, 0x6D, 0x65 };

	string SetFilter = { 0x53, 0x65, 0x74, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72 };
	string SetPageIndex = { 0x53, 0x65, 0x74, 0x50, 0x49, 0x6E, 0x64, 0x65, 0x78 };
	string SetPageDirection = { 0x53, 0x65, 0x74, 0x50, 0x44, 0x69, 0x72 };
	string SetCustomizedLogoImage = { 0x53, 0x65, 0x74, 0x43, 0x75, 0x73, 0x74, 0x49, 0x6D, 0x67 };
	string SetDisplayPageMode = { 0x53, 0x65, 0x74, 0x50, 0x4D, 0x6F, 0x64, 0x65 };
	string SetARange = { 0x53, 0x65, 0x74, 0x41, 0x52, 0x61, 0x6E, 0x67, 0x65 };
	string SetATime = { 0x53, 0x65, 0x74, 0x41, 0x54, 0x69, 0x6D, 0x65 };

	string GetShowId = { 0x47, 0x65, 0x74, 0x53, 0x68, 0x6F, 0x77, 0x49, 0x44 };
	string GetTxMdi = { 0x47, 0x65, 0x74, 0x54, 0x78, 0x4D, 0x44, 0x49 };
	
};

