// This may look like C code, but it is really -*- C++ -*-
// Module PI : Peida Interactive PIDrawer3D PIDraw3DWdg
// Drawer et DrawWidget 3D       R. Ansari 06/98
// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA

#ifndef PIDRW3D_H_SEEN
#define PIDRW3D_H_SEEN

#include "pisysdep.h"
#include "pidrawer.h"
#include "pigraph3d.h"

#include PIBWDG_H


// -----------------  Traceur (Drawer) 3D  -------------------

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

  virtual void		Set3DView_Obs(double xo, double yo, double zo, double teta, double phi, double psi, 
                                      double dax, double day, double co, double dco=0.2);
  virtual void       	Set3DView(double xc, double yc, double zc, double xo, double yo, double zo, 
                                  double dax, double day, double dco=0.2, double psi=0.);
  bool           	Get3DView(double& xc, double& yc, double& zc, double& xo, double& yo, double& zo,
                                  double& teta, double& phi, double& psi, double& dax, double& day, double& co, double& dco);
  
  virtual PIGraphicUC*	SetDrwWdg(PIBaseWdgGen* drw, int x0, int y0, int dx, int dy, PIGraphicGen* g);

  virtual void       	DrawAxes(PIGraphicUC* g);
  virtual void       	Draw3DBoxe(PIGraphic3D* g3, double xx1, double xx2, double yy1, double yy2, 
                                                    double zz1, double zz2, double xl1, double xl2, 
                                                    double yl1, double yl2, double zl1, double zl2);

  double XMin3() const {return x3Min;}
  double XMax3() const {return x3Max;}
  double YMin3() const {return y3Min;}
  double YMax3() const {return y3Max;}
  double ZMin3() const {return z3Min;}
  double ZMax3() const {return z3Max;}

protected :
  double xO, yO, zO;  // Position observateur = camera
  double xC, yC, zC;  // Position centre du champ
  double tO,fO,pO;    // Orientation observateur (Teta, Phi, Psi, Angles d Euler)
  double daxO, dayO;  // Demi-ouverture de la camera suivant les deux axes de projection (xp/zp, yp/zp) 
  double lCO, dlCO;   // Distance Camera-Centre du champ et profondeur de champ 
  bool v3D_obs;      // Si defini par Set3DView_Obs 
  double x3Min, x3Max;  // Pour delimiter le cube 3D 
  double y3Min, y3Max;  // Pour delimiter le cube 3D 
  double z3Min, z3Max;  // Pour delimiter le cube 3D 
};


//------------------------------ Classe PIDrawer3D --------------------

class PIDraw3DWdg : public PIBaseWdg {
public:
  enum {ClassId = 5500};

			PIDraw3DWdg(PIContainerGen *par, const char *nom,
                                    int sx=100, int sy=100, int px=0, int py=0);
  virtual		~PIDraw3DWdg();
  virtual long		kind() {return ClassId; }


  virtual void		Set3DView_Obs(double xo, double yo, double zo, double teta, double phi, double psi, 
                                      double dax, double day, double co, double dco=0.2);
  virtual void       	Set3DView(double xc, double yc, double zc, double xo, double yo, double zo, 
                                  double dax, double day, double dco=0.2, double psi=0.);
  bool           	Get3DView(double& xc, double& yc, double& zc, double& xo, double& yo, double& zo, 
                                  double& teta, double& phi, double& psi, double& dax, double& day, double& co, double& dco);

  virtual void          Update3DView();   // Vue 3-D a partir de Drawer No 1

  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); }
  inline PIElDrawer*    BaseDrawer() { return mBDrw; };

  int                   AddDrawer3D(PIDrawer3D*, bool ad=false);   // Ajoute un Drawer 

//  Pour tenir trace des Drawers-3D qui sont detruits 
  virtual void      	RemoveDrawer(int id);       
  virtual void       	DeleteDrawers();            

  virtual void		But1Press(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);


protected :
  virtual void		SetDrawers3DView();
  virtual void		DrawXYZAxes();

  PIElDrawer* mBDrw;   // Objet traceur d'elements de fond
  int mPx, mPy;        // Position pointeur - Bouton-1 
  
  bool vfixed;       // SetView fait ou pas
  list<int> m3DrIl;  // Liste des Id drawers 3D 
  PIGraphic3D* mGr3d;   // PIGraphic3D courante
  int lPx, lPy;         // dernier position pointeur
  PIColors lCol;        // Couleur
  double cTeta, cPhi, cUlen;    // Pour garder valeurs avant rotation, Unite de longeur
  double cXc, cYc, cZc;         // Pour garder position du centre de champ 
  double clCO, cDax, cDay;      // Pour garder les valeurs avant Zoom In/Out
  bool  rOfg;                  // si Vrai  on fait tourner l'objet et pas la camera
  bool  axfg;                  // si Vrai on trace les axes
  bool  skcfg;                 // si Vrai click-2 au centre -> rotation objet
};

#endif
