#ifndef GC_REFERENCESYSTEMS_H
#define GC_REFERENCESYSTEMS_H


class IGcReferenceSystem
{
public:

  virtual void pix_xy(int& x, int& y, float range, float az) const = 0;
  virtual void pix_xy(int& x, int& y, float range, float az, float refaz) const = 0;
  virtual void pix_xy(int& x, int& y, float range, float az, float refaz, float scale) const = 0;

  virtual void pix_xy_os_rel(int& x, int& y, float range, float az) const = 0;

  virtual int pix_x(float range, float az) const = 0;
  virtual int pix_y(float range, float az) const = 0;

  virtual float reference_azimuth() const = 0;
  virtual float reference_range() const = 0;
  virtual float reference_vel() const = 0;

  virtual int pix_to_pix_x(float x) const = 0;
  virtual int pix_to_pix_y(float y) const = 0;

  virtual int az_pix(float az) const = 0;
  virtual int az_pix_half_scan_sector(float az, bool is_left_sector) const = 0;
  virtual int el_pix(float el) const = 0;

  virtual void rng_az_pix_xy(int& x, int& y, float range, float az) const = 0;

  virtual void rng_az_el_pix_xy(int& x, int& y, float range, float az, float el) const;

  virtual void rng_az_subpix_xy(float& x, float& y, float range, float az) const = 0;
  virtual void vel_az_pix_xy(int& x, int& y, float velocity, float az) const = 0;

  virtual void rng_pix_y(int& y, float range) const = 0;
  virtual int rng_pix_y(float range) const = 0;

  virtual int rng_pix_radius(float range, float scale) const = 0;

  virtual int len_pix_qmy() const = 0;

  virtual void pix_ac_rot_xy(int x, int y, int &rotX, int &rotY) const = 0;
  virtual void pix_trkv_rot_xy(int x, int y, int &rotX, int &rotY, float trkv_ang) const = 0;

  virtual void nav_rng_az(float &range, float &az, float x, float y) const = 0;
  virtual void nav_rng_az(float &range, float &az, float x, float y, float az_ref) const = 0;
  virtual void nav_rng_vel_az(float &range, float &velocity, float &az, float x, float y) const = 0;
  virtual void nav_az_el(float &az, float &el, float x, float y) const = 0;

  //Geographic
  virtual bool geo_pix_xy(int& x, int& y, float latitude, float longitude) const = 0;

protected:
  //IGcReferenceSystem();
  virtual ~IGcReferenceSystem();

private:
  //IGcReferenceSystem(const IGcReferenceSystem&);
  //void operator=(const IGcReferenceSystem&);
};

class GcReferenceSystemCx
{
public:
  enum { MovingFrame, AntennaFrame, PixelFrame, FramesCardinality_};


  IGcReferenceSystem& tgtSys() const { return **pTgtSys;}
  IGcReferenceSystem& operator->() const { return **pNavSys;}

protected:
  static IGcReferenceSystem* frames[FramesCardinality_];

  static IGcReferenceSystem** pTgtSys; //targets (radar detected objects) refrences system

  static IGcReferenceSystem** pNavSys; //navigation objects reference system (usually the same of tgtSys, but in VS
  static IGcReferenceSystem** pRotNavSys; //rotated navigation objects reference system (usually the same of tgtSys, but in VS
};

class GcReferenceSystems
{
public:
  static IGcReferenceSystem& pixels;

  static IGcReferenceSystem& bodyBScan;
  static IGcReferenceSystem& bodyPPI;

  static IGcReferenceSystem& navBScan;
  static IGcReferenceSystem& frzNavBScan;
  static IGcReferenceSystem& expNavBScan;
  static IGcReferenceSystem& frzExpNavBScan;

  static IGcReferenceSystem& navPPI;
  static IGcReferenceSystem& frzNavPPI;
  static IGcReferenceSystem& expNavPPI;
  static IGcReferenceSystem& frzExpNavPPI;

  static IGcReferenceSystem& rotatedNavPPI;

  static IGcReferenceSystem& navAAPPI;

  static IGcReferenceSystem& geoImage;
};



#include "GcObject.h"

class GcReferenceSystem: public GcObject, public IGcReferenceSystem
{
public:
  GcReferenceSystem(const char* const name);
  virtual ~GcReferenceSystem();

  virtual void pix_xy(int& x, int& y, float range, float az) const;
  virtual void pix_xy(int& x, int& y, float range, float az, float refaz) const;
  virtual void pix_xy(int& x, int& y, float range, float az, float refaz, float scale) const;

  virtual void pix_xy_os_rel(int& x, int& y, float range, float az) const;

  virtual int pix_x(float range, float az) const;
  virtual int pix_y(float range, float az) const;

  virtual float reference_azimuth() const;
  virtual float reference_range() const;
  virtual float reference_vel() const;

  virtual int pix_to_pix_x(float x) const;
  virtual int pix_to_pix_y(float y) const;

  virtual int az_pix(float az) const;
  virtual int az_pix_half_scan_sector(float az, bool is_left_sector) const;
  virtual int el_pix(float el) const;

  virtual void rng_az_pix_xy(int& x, int& y, float range, float az) const;
  virtual void rng_az_subpix_xy(float& x, float& y, float range, float az) const;
  virtual void vel_az_pix_xy(int& x, int& y, float velocity, float az) const;

  virtual void rng_pix_y(int& y, float range) const;
  virtual int rng_pix_y(float range) const;

  virtual int rng_pix_radius(float range, float scale) const;

  virtual int len_pix_qmy() const;

  virtual void pix_ac_rot_xy(int x, int y, int &rotX, int &rotY) const;
  virtual void pix_trkv_rot_xy(int x, int y, int &rotX, int &rotY, float trkv_ang) const;

  virtual void nav_rng_az(float &range, float &az, float x, float y) const;
  virtual void nav_rng_az(float &range, float &az, float x, float y, float az_ref) const;
  virtual void nav_rng_vel_az(float &range, float &velocity, float &az, float x, float y) const;
  virtual void nav_az_el(float &az, float &el, float x, float y) const;

  virtual bool geo_pix_xy(int& x, int& y, float latitude, float longitude) const;

  GC_OBJ_MON_DECLARE(GcReferenceSystem)
};

#endif // GC_REFERENCESYSTEMS_H
