// This may look like C code, but it is really -*- C++ -*-
//     Classes ArrayAdapter           R. Ansari  05/98
// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA


#ifndef PARRADAPTER_SEEN
#define PARRADAPTER_SEEN

#include "machdefs.h"
#include "lut.h"

class P1DArrayAdapter {
public :
                  P1DArrayAdapter(int sz=0);
  virtual         ~P1DArrayAdapter();
 
  virtual double  Value(int i) = 0;
  inline  int     Size() { return (mSize) ; }
  virtual void    DefineXCoordinate(double x0, double dx);
  virtual double  X(int i);
     
protected :
  int mSize;
  double mOx, mDx;
};

// Cette classe est un adaptateur pour les PIImages et 
// autres classes de PI qui operent sur des structures 
// de type Tableaux 2-D (images, ...) 
class P2DArrayAdapter;

typedef char * (* P2DAA_InfoStringFunc) (P2DArrayAdapter * aa, int ix, int iy);
/* Longueur de retour de P2DAA_InfoString : 128 char */
 
class P2DArrayAdapter {
public :
                  P2DArrayAdapter(int sx=0, int sy=0);
  virtual 	  ~P2DArrayAdapter();

  void  	  ConfigureAxes(bool invx=false, bool invy=false, bool exy=false,
                                int sx=-1, int sy=-1);

  inline void     GetAxesConfiguration(bool& invx, bool& invy, bool& exy)
                               { invx = invX; invy = invY; exy = eXY; }

  virtual void    DefineXYCoordinates(double x0, double y0, double dx, double dy);
// Doit etre defini par les classes derivees
  virtual double  Value(int ix, int iy) = 0;   

  virtual void    XYfromxy(int ix, int iy, double& x, double& y);

  virtual char *  InfoString(int ix, int iy);

  inline  void    SetInfoStringFunction(P2DAA_InfoStringFunc isf)
                  { ISFunc = isf; }

  inline  int     XSize() { return ( eXY ? sY : sX ) ; }
  inline  int     YSize() { return ( eXY ? sX : sY ) ; }

  inline  void    XYCoord(int i, int j, double& x, double& y)
                         { int ix, iy;  IJ2xy(i, j, ix, iy); 
                           XYfromxy(ix, iy, x, y); }
  inline  void    Coord(int i, int j, double& x, double& y)
                       { int ix, iy;  double f; IJ2xy(i, j, ix, iy); 
                       XYfromxy(ix, iy, x, y); if (eXY) {f=x; x=y; y=f; } }
  inline  double  operator() (int i, int j) 
                         { int ix, iy;  IJ2xy(i, j, ix, iy); 
                         return Value(ix, iy); }
  inline void     IJ2xy(int i, int j, int& x, int& y)
                  { if  (eXY) {int ii = i; i = j; j = ii; }
                  x = i*sgnX+offX; y = j*sgnY+offY; 
                  return; }

//    Calcul Min-Max, Moy-Sig
  virtual int     CheckDyn(double& min, double& max, double& moy, double& sig, int& nbnul, int& nbsat, int vit=10);
//    Calcul AutoLut
  virtual void    ComputeLut_PicHisto(double& min, double& max, int nbsig=1, double fracmax=0.95);

//    Calcul pixmap avec un LUT
  virtual unsigned char * ComputePixmap(LUT* lut, int ofx, int ofy, int zm, 
                           int xwsz, int ywsz, unsigned char * opix, 
                           int * oxsp, int * oysp);
protected :
  int sX, sY;
  double mOx, mDx, mOy, mDy;
  int sgnX, sgnY;
  int offX, offY;
  bool invX, invY, eXY;

  P2DAA_InfoStringFunc ISFunc;

};

template <class T> 
class P1DAdapter : public P1DArrayAdapter {
public :
                  P1DAdapter(T* data, int sz, bool ad=false) :
                    P1DArrayAdapter(sz)
                    { aDel = ad; mData = data; }

  virtual 	  ~P1DAdapter() { if ( (aDel) && (mData) ) delete[] mData; }
  virtual double  Value(int i) 
                    {  if ( (i < 0) || (i >= mSize) ) return(0.); 
                    return(mData[i]); }
protected :
  bool aDel;
  T* mData;
};


template <class T> 
class P2DAdapter : public P2DArrayAdapter {
public :
                  P2DAdapter(T* data, int sx, int sy, bool ad=false) :
                    P2DArrayAdapter(sx, sy)
                    { aDel = ad; mData = data; }

  virtual 	  ~P2DAdapter() { if ( (aDel) && (mData) ) delete[] mData; }
  virtual double   Value(int ix, int iy) 
                    {  if ( (ix < 0)  || (iy < 0) || (ix >= sX) || (iy >= sY) ) return(0.); 
                    return(mData[ix+iy*sX]); }
protected :
  bool aDel;
  T* mData;
};



#endif
