// This may look like C code, but it is really -*- C++ -*-
// Module PI : Peida Interactive      PIBaseWdgGen
// Classe de base pour la creation de nouvelles composantes
// graphiques interactives       
//                        R.Ansari -  E.Aubourg 96
// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA

#ifndef PIBWDGGEN_H_SEEN
#define PIBWDGGEN_H_SEEN


#include "pisysdep.h"
#include PIWDG_H
#include PICMAP_H
#include PIGRAPHIC_H
#include "pigraphuc.h"
#include "pievthandler.h"
#include "psfile.h"

// Mettre dans cet ordre, sinon g++ a des problemes   
#include <vector>   


enum PIPointer { PI_ArrowPointer = 1, PI_CrossPointer = 2, 
                 PI_HandPointer = 3, PI_TDLRArrowPointer = 4 };

// Forward declaration for PIDrawer
class PIDrawer; 

class PIBaseWdgGen : public PIWdg
{
public:
  enum {ClassId = 5000};

// Les methodes ...

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

  virtual long       kind() {return ClassId; }

//  Activation des evenements
  virtual void       ActivatePtrCross()        = 0;
  virtual void       ActivateButton(int bid)   = 0;
  virtual void       ActivateMove(int bid)     = 0;
  virtual void       ActivateKeyboard()        = 0;

//  Divers :   forme de la souris
  virtual void       SelPointerShape(PIPointer ptr=PI_ArrowPointer)          = 0;
  virtual PIPointer  GetPointerShape()                                       = 0;
  virtual void       AssignKeyboard()                                        = 0;

//  Fonctions qui doivent contenir le dessin du contenu du widget lui-meme
  virtual void       Draw(PIGraphic* g, int x0, int y0, int dx, int dy);
  
// Traitement des evenements   
  virtual void       Resize();
  virtual void       Enter();
  virtual void       Leave();  
  virtual void       But1Press(int x, int y);  
  virtual void       But1Release(int x, int y); 
  virtual void       But2Press(int x, int y);
  virtual void       But2Release(int x, int y);
  virtual void       But3Press(int x, int y);
  virtual void       But3Release(int x, int y);
  virtual void       PtrMove(int x, int y);
  virtual void       Ptr1Move(int x, int y);
  virtual void       Ptr2Move(int x, int y);
  virtual void       Ptr3Move(int x, int y);
  virtual void       Keyboard(int key, PIKeyModifier kmod);

// Acces aux caracteristiques du dernier evenement 
  virtual void       GetLastEventInfo(PIKeyModifier& kmod, unsigned long& tm) = 0;

// PostScript output
  virtual void       PSPrint(PSFile* psf, int ofx = 0, int ofy = 0,
			     double scale_x=1., double scale_y=1.);

// ------ Gestion des Drawers  ------
  friend class PIDrawer;
  virtual void       SetDefaultDrawRectangle(PIGrCoord x1, PIGrCoord y1, 
                                             PIGrCoord x2, PIGrCoord y2, bool psz=true); 
  virtual void       GetDefaultDrawRectangle(PIGrCoord& x1, PIGrCoord& y1, 
                                             PIGrCoord& x2, PIGrCoord& y2, bool& psz);
  virtual void       SetDefaultDrawerLimits(double xmin, double xmax, double ymin, double ymax,
                                            int axrl=kAxeDirSame, int ayud=kAxeDirSame); 
  virtual void	     SetDefaultDrawerLogScale(bool logx, bool logy);
  inline  bool       isDefaultDrawerLogScaleX() { return(mDXlog); }
  inline  bool       isDefaultDrawerLogScaleY() { return(mDYlog); }

  virtual int        AddDrawer(PIDrawer* drw, PIGrCoord x1, PIGrCoord y1, 
                               PIGrCoord x2, PIGrCoord y2, 
                               bool psz=true, bool clip=true, 
			       bool ad=false, bool lock=false);
  virtual int        AddDrawer(PIDrawer* drw, bool autolim=false, bool clip=true, 
			       bool ad=false, bool lock=false);
  virtual void       MoveResizeDrawer(int id, PIGrCoord x1, PIGrCoord y1, 
                                      PIGrCoord x2, PIGrCoord y2, bool elastic=true);
  virtual void       RemoveDrawer(int id);       // Ote un drawer de la liste
  virtual void       DeleteDrawers();            // Ote tous les drawers, delete des drawers ajoute avec ad=true

// Acces aux drawers 
  inline  int        NbDrawers() { return mDrwList.size(); } 
          int        GetDrawerIdFromNum(int n); 
          PIDrawer*  GetDrawerId(int id);   
          PIDrawer*  GetDrawer(int n); 
          bool       IsDrawerLockedId(int id);
          bool       IsDrawerAutoSizePos(int id);
          void       GetDrawerPosition(int id, PIGrCoord& x1, PIGrCoord& y1, 
				       PIGrCoord& x2, PIGrCoord& y2, bool& elastic);

// Quel est le drawer actif
          void       SetActiveDrawerId(int id);   
          void       SetActiveDrawer(int n);   
          int        GetActiveDrawerId();   
          int        GetActiveDrawerNum();   
          PIDrawer*  GetActiveDrawer();   

// Recherche du plus proche Drawer
  virtual int        FindNearestDrawerId(int x, int y);

//  Trace des Drawers ...          
  virtual void       CallDrawers(PIGraphic* g, int x0=0, int y0=0, int dx=0, int dy=0); 
  virtual void       CallDrawer(int id);

  virtual PIGraphic*  WindowGraphic();

// -------------- Variables membres protegees -------------------
protected:
// ..... Structure de la liste de gestion des drawers .....
  struct BWDrwId { 
    int id;          // Drawer Identifier
    PIGrCoord x1, y1, x2, y2;  // Drawer Position(/Size) in Widget
    // autoszp/autolim=true, Size/Limits imposed by widget - 
    // elastic=true: Pos/Size = fraction of wdget size
    bool autoszp, autolim, elastic; 
    bool clip, ad;  // clip=true : No graphic draw outside Drawer rectangle
    // ad=true: Delete Drawer when delete of PIBaseWdg
    bool lock;  // lock=true: cannot be detached/deleted
    PIDrawer* drw;   // Pointer to drawer itself
  };
// ...........................................................

  PIGraphicWin* mWGrC;  // PIGraphic (Contexte graphique) associe a la fenetre
  bool mAdfg;           // Pour la gestion de DeleteDrawers() quand appele par delete de PIBaseWdg
  int mDrwId;           // Compteur pour DrawerId
  int mActDrwId;        // Identificateur du drawer actif
  vector<BWDrwId> mDrwList;   // Liste des drawers et leur Id
//  Definition de la zone de trace et limites UC des drawers par defaut  
  PIGrCoord mDrX1, mDrY1,  mDrX2,  mDrY2;  
  bool mDrElastic;   // true --> Coord en fraction de la taille 
  double mDrXmin, mDrXmax, mDrYmin, mDrYmax;   // Limites par defaut - UC
  int  mDXdir, mDYdir;                        // Sens des axes par defaut
  bool mDXlog, mDYlog;                        // true -> echelle log - axes par defaut
};


#endif /* PIBWDGGEN_H_SEEN */

