// This may look like C code, but it is really -*- C++ -*-
// Methodes de trace d'axes - 
//                             R. Ansari  2002
// (C) LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA

#ifndef PIAXES_H
#define PIAXES_H

#include "pigraphuc.h"
#include "pigratt.h"
#include <vector>

enum {
  kCentAxes    = 0x0001,
  kBoxAxes     = 0x0002,
  kTicks       = 0x0004,
  kGridOn      = 0x0008,

  kIntTicks    = 0x0010,
  kExtTicks    = 0x0020,
  kMajTicks    = 0x0040,
  kMinTicks    = 0x0080,

  kLabelsH     = 0x1000,
  kLabelsV     = 0x2000,
  kLabels      = kLabelsH | kLabelsV,

// Axes trace par defaut
  kAxesDflt    = kBoxAxes | kTicks | kMajTicks | kIntTicks | kLabels,       
  kStdAxes     = kAxesDflt,       
  kAxesNone    = 0         // Pas de trace d axe  
};


class PIAxes {
public:

                    PIAxes();
  virtual           ~PIAxes();

  virtual void      DrawXYAxes(PIGraphicUC* g, PIGraphicAtt& gratt, 
			       unsigned int flags, bool afsz, double fszf);
  inline  void      DrawXYAxes(PIGraphicUC* g, PIGraphicAtt& gratt, unsigned int flags=kAxesDflt)
     { DrawXYAxes(g, gratt, flags, axesAFSz, fontSz); }

  virtual void      DrawXYAxes(PIGraphicUC* g, PIGraphicAtt& gratt, 
			       double xmin, double xmax, 
			       double ymin, double ymax,
			       unsigned int flags, bool afsz, double fszf);
  inline void       DrawXYAxes(PIGraphicUC* g, PIGraphicAtt& gratt, 
			       double xmin, double xmax, double ymin, double ymax, unsigned int flags=kAxesDflt)
    {   DrawXYAxes(g, gratt, xmin, xmax, ymin, ymax, flags, axesAFSz, fontSz); }

  virtual void      DrawXCaption(PIGraphicUC* g, PIGraphicAtt& att, unsigned int flags,
				 string const& xLabel); 
  virtual void      DrawYCaption(PIGraphicUC* g, PIGraphicAtt& att, unsigned int flags,
				 string const& YLabel); 

  //  Taille des ticks d'axes (en fraction de taille d'axe)
  void  ConfigureTicks(int ntickx=10, int nticky=12, 
		       double majtl=0.016, double mintl=0.01);
  //  Choix de taille automatique de fontes 
  void  ConfigureAutoFontSize(bool afsz=true, double fszf=0.04);
  void  ConfigureAxesCenter(bool fset=false,double x0=0.,double y0=0.);

  //  virtual void      DrawHorizontalAxe(double xmin, double xmax, double y, 

  //  Calcul du min et du max du display a partir des valeurs min et max a plotter
  static void ReSizeMinMax(bool axelog,double& vmin,double& vmax,double garde=0.025);
  //  Calcul des Distances optimales des subdivisions (STATIC)
  static void BestTicks(double xmin,double xmax,int nticks
		       ,vector<double>& majticks,vector<double>& minticks);
  static void BestTicksLog(double xmin,double xmax,int nticks
			  ,vector<double>& majticks,vector<double>& minticks);
  //  Calcul du format optimal (STATIC)
  static int BonFormatAxes(double xmin,double xmax,double xstep
			  ,string& format,int typf=0,int add_digit=0);
  //  Decision du format optimal pour les axes (STATIC)
  static int Le_Bon_Format(vector<double>& xticks,string& format,double& xstep);
  //  Mise en forme optimale du label numerique (STATIC)
  static void Arrange_Label(char *label);

protected:
  void Setup(PIGraphicUC* g,double xmin,double xmax,double ymin,double ymax);

  void DrawHTicks(PIGraphicUC* g, double y, double tickUp, double tickDown, vector<double>& xticks);
  void DrawVTicks(PIGraphicUC* g, double x, double tickLeft, double tickRight, vector<double>& yticks);
  void DrawHLabels(PIGraphicUC* g, double y, vector<double>& xticks, unsigned long just=0);
  void DrawVLabels(PIGraphicUC* g, double x, vector<double>& yticks, unsigned long just=0);
  void DrawGrid(PIGraphicUC* g);


  bool   setupDone;  // Si Setup a ete appele

  double xMin, xMax, yMin, yMax; 
  bool   aXdir, aYdir;           // Sens des axes horiz, vertical 
  bool   aXlog, aYlog;           // Echelle log pour les axes horiz, vertical 
  bool   axesAFSz;               // true -> AutoFontSize
  
  int xNTicks, yNTicks;             // Nb de ticks en X, Y
  double fMajTickLen, fMinTickLen;  // Taille des ticks, en fraction de Max-Min
  double fontSz;                    // Taille pour autofontsize, frac Max-Min
  vector<double> xMajTicks;
  vector<double> xMinTicks;
  vector<double> yMajTicks;
  vector<double> yMinTicks;
  double xMajTickLen,  xMinTickLen;
  double yMajTickLen,  yMinTickLen;
  bool axesCenter; double axesCentX0,axesCentY0;

};

#endif
