// +-------------------------------- DISCLAIMER ---------------------------------+
// |                                                                             |
// | This program is provided to you free of charge "as such".                   |
// | You should not assume that this program is error-free or suitable for any   |
// | purpose whatsoever.                                                         |
// |                                                                             |
// | EURESYS does not give any representation, warranty or undertaking that this |
// | program is free of any defect or error or suitable for any purpose. EURESYS |
// | shall not be liable, in contract, in torts or otherwise, for any damages,   |
// | loss, costs, expenses or other claims for compensation, including those     |
// | asserted by third parties, arising out of or in connection with the use of  |
// | this program.                                                               |
// +-----------------------------------------------------------------------------+

#pragma once

#include "../Common/GrabberInterface.h"

// LMI C Wrapper
#include <GoSdk/GoSdk.h>


#define NM_TO_MM(VALUE) (((k64f)(VALUE))/1000000.0)
#define UM_TO_MM(VALUE) (((k64f)(VALUE))/1000.0)

// gocator transmits range data as 16-bit signed integers. 0x8000 signifies invalid range data.
#define INVALID_RANGE_16BIT ((signed short)0x8000)

// Device data
#define BIT_DEPTH 16

// Sensor parameters default values
#define EXPOSURE_TIME_DEFAULT 30.f
#define FREQUENCY_DEFAULT 200.f
#define X_FIELD_OF_VIEW 45.f
#define MEASUREMENT_RANGE 9.5f
#define X_START -11.5f
#define Z_START -28.f
#define SURFACE_LENTH 25.f


class LMIGrabber : public GrabberInterface
{
public:
  // Construction and destruction
  LMIGrabber(const std::string& device_name = "");
  ~LMIGrabber();

  // Acquisition control
  virtual void Start(int num_frame = 1);
  virtual long long int WaitFrame(int timeout_ms = -1);
  virtual void ReleaseFrame();
  virtual void Stop();

  // Bit depth for DepthMap and ZMap
  virtual int GetBitDepth();

  // Data retrieval
  virtual void GetDepthMap(Easy3D::EDepthMap& map);
  virtual void GetPointCloud(Easy3D::EPointCloud& pc);
  virtual void GetZMap(Easy3D::EZMap& zmap);

  // Parameter handling GUI
  virtual void InvokeParameterPanel();

private:
  // Set data acquisition mode
  void SetPointCloudMode();
  void SetZMapMode();

protected:

  // Grabbing state
  bool started;
  bool locked;
  long long int frame_counter;

  // Last converted data
  Easy3D::EPointCloud* point_cloud;
  Easy3D::EZMap16* zmap;

  // Device user configuration
  std::string acquisition_mode;
  float exposure_time;
  float frequency;
  float x_field_of_view;
  float measurement_range;
  float x_start;
  float z_start;
  float surface_length;

  // GoSensor
  kAssembly api;
  GoSystem system;
  GoSensor sensor;
  GoSetup setup;
  GoDataSet dataset;
  kIpAddress ipAddress;
  k32u id;
  kSize sensorCount;
  GoSurfaceGeneration surface;
};
