// This may look like C code, but it is really -*- C++ -*-
// Objets traceur qui peuvent etre attaches a un PIBaseWidget
//                             R. Ansari  97-98
// (C) LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
#ifndef PIDRAWER_H
#define PIDRAWER_H

#include "pibwdggen.h"
#include "pigraphuc.h"
#include "pigratt.h"
#include "piaxes.h"


class PIDrawer {
public:
                     PIDrawer();
  virtual           ~PIDrawer();

  // if true -> PIDrawer deleted when detached from last BaseWdg
  inline  void       SetAutoDeleteOnDetach(bool fg)
                       { mFgDeleteOnDetach = fg; }
  // if true -> PIBaseWdg()->Refresh() when PIDrawer is deleted 
  inline  void       SetAutoRefreshOnDelete(bool fg)
                       { mFgRefreshOnDelete = fg; }

  virtual void       SetLimits(double xmin, double xmax, double ymin, double ymax,
                               int axrl=kAxeDirSame, int ayud=kAxeDirSame);
  inline void	     SetLogScale(bool logx, bool logy) 
                             { aXlog = logx; aYlog = logy; }

  virtual void       SetAxesFlags(unsigned int flags=kAxesNone);
  inline  void       SetAxesAutoFontSize(bool fg=true) { axesAFSz = fg; }

  virtual void       DrawAxes(PIGraphicUC* g);

  virtual void       Draw(PIGraphicUC* g, double xmin, double ymin, double xmax, double ymax); 

//  Rajoute l'information concernant la zone xmin,ymin ---> xmax,ymax au string info
  virtual void       AppendTextInfo(string& info, double xmin, double ymin, double xmax, double ymax);

// Renvoie une information liee au drawer pour une position x,y 
  virtual void       GetClickInfo(string& info,double x,double y
                                 ,double x0=0.,double y0=0.,bool fgdiff=false); 
// Renvoie une distance au point x,y 
// 0: au(x) point(s) le(s) plus proche(s) ... 1  au bord xmin/xmax , ymin/ymax
// La methode par defaut calcule la distance normalisee au point ((xmin+xmax)/2,(ymin+ymax)/2)
  virtual double     GetDistanceToPoint(double x, double y);

  virtual void       Refresh(bool refwdg=false);      // Recalcule les limites et reaffiche
  virtual void       UpdateLimits();   // Calcule et change les limites  

  // Gestion d'affichage en mode HighLight : fgh=true -> highlight =false -> normal
  virtual void	     HighLight(bool fgh);  

  inline double      XMin() const {return xMin;}
  inline double      XMax() const {return xMax;}
  inline double      YMin() const {return yMin;}
  inline double      YMax() const {return yMax;}

  void               GetAxesConfig(int& xa, int& ya);
  inline bool        isLogScaleX() { return aXlog; }
  inline bool        isLogScaleY() { return aYlog; }

  inline unsigned int GetAxesFlags() { return(axesFlags); }
  inline bool         isAxesAutoFontSize() { return axesAFSz; }

  inline PIGraphicUC*    GetGraphicUC() { return(mGrUC); }

  inline bool         LimitsFixed() const {return limitsFixed;}
  inline void         FreeLimits() {limitsFixed = false;}

  virtual void        SelGraAtt(PIGraphicUC* g);

// Changement des attributs graphiques
  inline void         SetGraphicAtt(PIGraphicAtt const& att) { mGrAtt = att; }
  inline void         UpdateGraphicAtt(PIGraphicAtt const& att) 
                      { mGrAtt.UpdateFrom(att); }

// Acces aux attributs graphiques
  inline PIGraphicAtt& GetGraphicAtt() { return(mGrAtt); }

//  Methode permettant l'affichage d'une fenetre de controle specialisee 
  virtual void       ShowControlWindow(PIBaseWdgGen* wdg);
  inline  bool       HasSpecificControlWindow() const { return mFgSpecContWind; }
  virtual void       DeactivateControlWindow(PIBaseWdgGen* wdg);

//   Methode permettant de decoder des options a partir de chaines
  virtual int        DecodeOptionString(vector<string> & opt, bool rmdecopt=true);
//   Methode retournant un vecteur de string a partir des options 
  virtual int        OptionToString(vector<string> & opt) const;

//   Texte d'aide des options disponibles
  virtual void	     GetOptionsHelpInfo(string& info);

//   On peut donner un nom a un drawer (par defaut = nom de la classe)
  inline string	     Nom() { return mName; } 
  inline string&     Name() { return mName; }
  inline void	     SetName(string const& name) { mName = name; } 

//  Les objets/methodes suivants devraient etre protected     
//  Pb avec acces depuis PIBaseWdgGen (Reza 11/07/97) 
  virtual  PIGraphicUC*  SetDrwWdg(PIBaseWdgGen* drw, int x0, int y0, int dx, int dy, PIGraphicGen* g);
//  Transformation coordonnees fenetre en coordonnees drawer
  virtual  void      WdgCoord2DrwCoord(int x, int y, double& xu, double& yu, 
				       int x0, int y0, int dx, int dy);

//  Je declare en public a cause de cxx - Reza 11/07/97 
  struct DrwBWId { int id; PIBaseWdgGen* wdg; };
  
protected:
  friend class PIBaseWdgGen;
  virtual void       Attach(PIBaseWdgGen*, int id);
  virtual void       Detach(PIBaseWdgGen*, int id);


  bool mFgDeleteOnDetach;         // si true -> delete drawer on detach
                                  // from last BaseWdg
  bool mFgRefreshOnDelete;        // si true -> On rafraichit le BaseWdg
                                  // lors du delete ou Detach
         
  double xMin, xMax, yMin, yMax;  // Valeurs en unites user
  int xW0, yW0, xWd, yWd;        // Origine/largeur ds la fenetre de trace
  bool   aXdir, aYdir;           // Sens des axes horiz, vertical 
  bool   aXlog, aYlog;           // Echelle log pour les axes horiz, vertical 
  int aXFlg, aYFlg;

  bool limitsFixed;
  unsigned int axesFlags;
  bool axesAFSz;
  PIBaseWdgGen* mBWdg;
  PIGraphicUC* mGrUC;

// Flag de control d'affichage en mode HighLight, dernier etat highlight ou non
  bool mFgHighLight, lastHLStatus;
// Flag indiquant s'il y a une fenetre de controle specifique
  bool mFgSpecContWind;
// Nom du drawer
  string mName;

  list<DrwBWId>  mBWdgList;
  bool mDndfg;

//  Gestion d attributs graphiques associes a chaque drawer
  PIGraphicAtt   mGrAtt;

};

#endif
