// This may look like C code, but it is really -*- C++ -*-
// Module PI : Peida Interactive PIDrawer3D PIDraw3DWdg
// Drawer  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 "pieldrw.h"
#include "pigraph3d.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 void		Set3DBox(double xmin, double xmax, double ymin, double ymax,
				 double zmin, double zmax,
				 double scx=1., double scy=1., double scz=1.);
  inline  void		SetAutoScale(bool fgxy, bool fgz) 
    { aScxy = fgxy;  aScz = fgz; }

  inline  void		Copy3DBox(PIDrawer3D& dr3) {
    Set3DBox(dr3.XMin3(), dr3.XMax3(), dr3.YMin3(), dr3.YMax3(), 
	     dr3.ZMin3(), dr3.ZMax3(), dr3.GetScaleX(), dr3.GetScaleY(), dr3.GetScaleZ());  
    SetAutoScale(dr3.isAutoScaleXY(), dr3.isAutoScaleZ());
  }

  static  void	        ComputeScaleFactor(double xmin, double xmax, double ymin, double ymax,
					   double zmin, double zmax, bool asxy, bool asz,
					   double& scy, double& scz);
  
  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);
//   Methode de decodage des options
  virtual int        DecodeOptionString(vector<string> & opt, bool rmdecopt=true);
  virtual int        OptionToString(vector<string> & opt) const;
//   Texte d'aide des options disponibles
  virtual void       GetOptionsHelpInfo(string& info);

  // Cordonnees du cube 3D
  inline double XMin3() const {return x3Min;}
  inline double XMax3() const {return x3Max;}
  inline double YMin3() const {return y3Min;}
  inline double YMax3() const {return y3Max;}
  inline double ZMin3() const {return z3Min;}
  inline double ZMax3() const {return z3Max;}
  // Facteur d'echelle: Cube3D = Coord.User(3D)*Scale
  inline double GetScaleX() const {return mScx;}
  inline double GetScaleY() const {return mScy;}
  inline double GetScaleZ() const {return mScz;}
  inline double ScaleX(double x) const {return x*mScx;}
  inline double ScaleY(double y) const {return y*mScy;}
  inline double ScaleZ(double z) const {return z*mScz;}
  inline bool   isAutoScaleXY() const { return aScxy; }
  inline bool   isAutoScaleZ()  const { return aScz; }

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 
  double mScx, mScy, mScz;  // Facteur d'echelle entre coord. utilise et cube 3D
                            // x/y/z-Cube3D = x/y/z-User * mScx/y/z 
  bool aScxy, aScz;    // Auto-scale X-Y, Z
};


// -----------------  Traceur d'elements 3D  -------------------
class PIElDrawer3D : public PIDrawer3D
{
public:
                     PIElDrawer3D();
  virtual           ~PIElDrawer3D();

//   Methode de decodage des options
  virtual int        DecodeOptionString(vector<string> & opt, bool rmdecopt=true);

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

  inline PIElDrwMgr& ElDrwMgr()    { return eltsMgr; }

  inline void        SetTitles(string tt, string tb)   { titleT = tt;  titleB = tb; }
  inline void        SetTitles(string tt, string tb, PIGraphicAtt const& att) 
                        { titleT = tt;  titleB = tb; titleAtt = att; }
  inline void        ShowTitles(bool fg=true) { showTitles = fg; }

// -- Pour compatibilite avec l'interface precedente , Reza 08/2002 
  inline void        ElDel(int id) { eltsMgr.ElDel(id); }
  inline void        ElDelLast()   { eltsMgr.ElDelLast(); }
  inline void        ElDelAll()    { eltsMgr.ElDelAll(); }
  
  inline int	     ElAddText(PIGrCoord x, PIGrCoord y, const char* s)
                                   { return eltsMgr.ElAddText(x, y, s); }

protected:
  PIElDrwMgr eltsMgr;
  string titleT, titleB;       // Titre Haut - Bas
  PIGraphicAtt titleAtt;       // Attributs graphiques de trace de titre
  bool showTitles;             // Affichage des titres si true

};


#endif
