// This may look like C code, but it is really -*- C++ -*-
// Module PI : Peida Interactive  PIScDrawWdg PIYfXDrawer
// Gestionnaire Drawer-2D  E.Aubourg, R. Ansari  96-98
// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA

#ifndef PISCDRAWWDG_H
#define PISCDRAWWDG_H

#include "pisysdep.h"
#include PIBWDG_H
#include PISTDWDG_H
#include PIWIN_H
#include "pidrawer.h"


// PIScDrawWdg, Gestionnaire de traceur 2D 

class PIScDrawWdg : public PIBaseWdg {
public:
  enum {ClassId = 5300};

                     PIScDrawWdg(PIContainerGen *par, const char *nom,
                                   int sx=100, int sy=100, int px=0, int py=0);
  virtual            ~PIScDrawWdg();

  virtual long       kind() {return ClassId; }
  
  virtual void       SetLimits(double xmin, double xmax, double ymin, double ymax, 
                               int axrl=kAxeDirSame, int ayud=kAxeDirSame, bool tmp=false);
  inline  void	     SetLogScale(bool logx, bool logy)	
                           { SetDefaultDrawerLogScale(logx, logy); }
  inline  bool       isLogScaleX() { return(mDXlog); }
  inline  bool       isLogScaleY() { return(mDYlog); }

  virtual void	     UpdateLimits();  // Calcule et change les limites a partir de Drawer-No-1 

  inline void        SetAxesFlags(unsigned int flags=kBoxAxes | kExtTicks | kLabels) 
                                  { mBDrw->SetAxesFlags(flags); }
  inline void	     SetTitles(const char* tt=NULL, const char* tb=NULL)
                            { mBDrw->SetTitles(tt, tb); }
  inline void	     SetTitles(string const & tt, string const & tb)
                            { mBDrw->SetTitles(tt, tb); }

  int                AddScDrawer(PIDrawer*, bool ad=false);   // Ajoute un Drawer en auto 
  inline PIElDrawer* BaseDrawer() { return mBDrw; };

// Configuration et limites des axes 
  inline unsigned int GetAxesFlags() { return(mBDrw->GetAxesFlags()); }
  inline void         GetAxesConfig(int& xa, int& ya) { mBDrw->GetAxesConfig(xa, ya); }

  inline double XMin() const {return mBDrw->XMin();}
  inline double XMax() const {return mBDrw->XMax();}
  inline double YMin() const {return mBDrw->YMin();}
  inline double YMax() const {return mBDrw->YMax();}

  inline double XPPos() const { return mPPos[0]; }
  inline double YPPos() const { return mPPos[1]; }

  int    LimitsFixed() const {return mBDrw->LimitsFixed();}
  void   FreeLimits() { mBDrw->FreeLimits(); }
    

  virtual string     GetClickText(double x, double y); // Donne le texte a afficher pour position x,y
  virtual void	     ActivateSpecializedControls();   // Pour activer des controles specifiques

  virtual void       UpdateInfoWindow();    // Affiche et met a jour la fenetre info texte
                                            // concernant le petit pave autour de la pos. courante 

  void               SetTextWin(PILabel * tw, bool trw=true, int tx=500, int ty=30);

  virtual void       But1Press(int x, int y);
  virtual void       But1Release(int x, int y);
  virtual void       Ptr1Move(int x, int y);

  virtual void       But2Press(int x, int y);
  virtual void       But2Release(int x, int y);
  virtual void       Ptr2Move(int x, int y);
  
  virtual void       But3Press(int x, int y);
  virtual void       But3Release(int x, int y);
  virtual void       Ptr3Move(int x, int y);

  virtual void       Keyboard(int key, PIKeyModifier kmod);
  virtual void       PasteSelection(unsigned int typ, void *pdata, unsigned int l);

  static  string     SetFormatOpt(double xmin,double xmax);
  
protected:
  double xMinS, xMaxS, yMinS, yMaxS; // Sauvegarde pour zoom
  double mPPos[2];        // Position courante (user coordinates)
  double mPSz[2];         // Taille courant du pave info 
  int mCPosX, mCPosY;     // Position click souris X,Y
  bool mFgReticule;       // Controle l'affiche d'une réticule (Bouton-1)
  string mFormatOpt[2];   // Format optimal d'impression des textes

  PIElDrawer* mBDrw;
  
  int xBegDrag, yBegDrag;
  int xEndDrag, yEndDrag;
  PIColors cForCol;
  PIGOMode cGOmod;  
  PIPointer cPointer;
  PILineAtt cLatt;
  PILabel * mTxw;  
  PILabel * mTrlb;
  PIWindow * mTrW;

// Fenetre pour l'affichage des informations 
  PIWindow * mInfoW;
  PIText * mInfoTxt;

private:
  void  UpdateText(int xp, int yp);
};


// ----------------------------------------------------------
// Classe de traceur de points/fonction Y=F(x)
// Trace Y=ay->Value() = f(X= ax->Value()) si ax et ay != NULL
// Trace Y=ax->Value() = f(X= ax->X())  si ay == NULL
 
class P1DArrayAdapter;
class PIYfXDrawer : public PIDrawer {
public:
                     PIYfXDrawer(P1DArrayAdapter* ax, P1DArrayAdapter* ay, bool ad);
  virtual           ~PIYfXDrawer();
  
  virtual void       Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax);
  virtual void       UpdateLimits();
  
       
protected:
  P1DArrayAdapter* mAx;
  P1DArrayAdapter* mAy;
  int mSz;
  bool mAdDO;
};

// ----------------------------------------------------------
// Classe de traceur de fonction  double = f(fouble)
// ----------------------------------------------------------

class PIFuncDrawer : public PIDrawer {
public:
  typedef double(*FUNC)(double);
                     PIFuncDrawer(FUNC);
  virtual           ~PIFuncDrawer();
  
  virtual void       Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax);
protected:
  FUNC               mFunc;
};

#endif
