// This may look like C code, but it is really -*- C++ -*-
// Module PI : Peida Interactive     PIGraphic 
// Primitives de trace graphiques    R. Ansari  97
// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA

#ifndef PIGRAPHICGEN_H_SEEN
#define PIGRAPHICGEN_H_SEEN

#include "pisysdep.h"

#include PIWDG_H
#include PICMAP_H
#include PIFONT_H

#include "picolist.h"  // enum PIColors


enum PILineAtt { PI_NotDefLineAtt = -1,
                 PI_NormalLine = 0, PI_ThinLine = 1, PI_ThickLine = 2 ,
                 PI_DashedLine = 64, PI_ThinDashedLine = 65, PI_ThickDashedLine = 66 ,
                 PI_DottedLine = 128, PI_ThinDottedLine = 129, PI_ThickDottedLine = 130 };

enum PIMarker  { PI_NotDefMarker = -1,
                 PI_DotMarker = 0, PI_PlusMarker=1, PI_CrossMarker=2,  
                 PI_CircleMarker=3, PI_FCircleMarker=4,
                 PI_BoxMarker=5, PI_FBoxMarker=6,
                 PI_TriangleMarker=7, PI_FTriangleMarker=8,
                 PI_StarMarker=9, PI_FStarMarker=10 };

enum PIGrPosHorizontal { PI_HorizontalLeft = 0, PI_HorizontalCenter = 1, 
			 PI_HorizontalRight = 2 };
enum PIGrPosVertical { PI_VerticalBottom = 32, PI_VerticalCenter = 36, 
		       PI_VerticalTop = 40 };

enum PIGOMode { PI_GOCopy = 0, PI_GOXOR = 1, PI_GOInvert = 2 }; 


//  Classe pour gerer indifferement des coordonnees double ou int 
class PIGrCoord {
public:
  inline PIGrCoord() { iv = 0; dv = 0.;}
  inline PIGrCoord(int a) { iv = a; dv = (double)a;}
  inline PIGrCoord(float a) { iv = (int)a; dv = (double)a;}
  inline PIGrCoord(double a) { iv = (int)a; dv = a;}
  inline PIGrCoord(PIGrCoord const & gc) { iv = gc.iv;  dv = gc.dv; }
  inline operator int() { return(iv); }
  inline operator short() { return((short)iv); }
  inline operator unsigned int() { return((unsigned int)iv); }
  inline operator unsigned short() { return((unsigned short)iv); }
  inline operator float() { return((float)dv); }
  inline operator double() { return(dv); }
  inline PIGrCoord& operator= (int a) { iv = a; dv = (double)a; return(*this); }
  inline PIGrCoord& operator= (float a) { iv = (int)a; dv = (double)a; return(*this); }
  inline PIGrCoord& operator= (double a) { iv = (int)a; dv = a; return(*this); }
  inline PIGrCoord& operator= (PIGrCoord const & gc) { iv = gc.iv; dv = gc.dv;  return(*this); }
  int iv;
  double dv;
};

enum PIGraphicsType { PI_UnknownGraphics = 0, 
                      PI_ScrWindowGraphics = 2, PI_ScrBufferGraphics = 3, 
                      PI_PSFileGraphics = 8, 
                      PI_UCGraphics = 32, PI_3DGraphics = 36 };

// Classe generique de trace graphique de base :

class PIGraphicGen
{
public:
                     PIGraphicGen();
                     PIGraphicGen(PIWdg* wdg);
                     PIGraphicGen(PIScreenBuffer* grb);
  virtual           ~PIGraphicGen();

  virtual int        kind();

//  Espace des coordonnees
  virtual void       GetGrSpace(PIGrCoord& xmin, PIGrCoord& xmax, PIGrCoord& ymin, PIGrCoord& ymax); 

//  Trace graphiques
  virtual void       Erase(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)     = 0;
  virtual void       DrawString(PIGrCoord x, PIGrCoord y, const char* s, int pos = 0)        = 0;
  virtual void       DrawOpaqueString(PIGrCoord x, PIGrCoord y, const char* s, int pos = 0)  = 0;
  virtual void       DrawLine(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2)  = 0;
  virtual void       DrawBox(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)   = 0;
  virtual void       DrawFBox(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)  = 0;
  virtual void       DrawCircle(PIGrCoord x0, PIGrCoord y0, PIGrCoord r)               = 0;
  virtual void       DrawFCircle(PIGrCoord x0, PIGrCoord y0, PIGrCoord r)              = 0;
  virtual void       DrawOval(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)  = 0;
  virtual void       DrawFOval(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy) = 0;
  virtual void       DrawPolygon(PIGrCoord *x, PIGrCoord *y, int n, bool cinc=true)    = 0;  
  virtual void       DrawFPolygon(PIGrCoord *x, PIGrCoord *y, int n, bool cinc=true)   = 0;  
  virtual void       DrawArc(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy,
                             double degdeb, double degfin)                             = 0;
  virtual void       DrawFArc(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy, 
                              double degdeb, double degfin)                            = 0;
  virtual void       DrawMarker(PIGrCoord x0, PIGrCoord y0)                            = 0;
  virtual void       DrawMarkers(PIGrCoord *x, PIGrCoord *y, int n)                    = 0;
  virtual void       DrawPixmap(PIGrCoord x, PIGrCoord y, unsigned char *pix, 
                                int sx, int sy, PIColorMap* cmap)              = 0;

// Modifications attributs graphiques
  virtual void       SelForeground(PIColors col=PI_Black)                      = 0;
  virtual void       SelBackground(PIColors col=PI_White)                      = 0;
  virtual void       SelForeground(PIColorMap& cmap, int cid)                  = 0;
  virtual void       SelBackground(PIColorMap& cmap, int cid)                  = 0;
  virtual void       SelGOMode(PIGOMode mod=PI_GOCopy)                         = 0;
  virtual void       SelLine(PILineAtt att=PI_NormalLine)                      = 0;
  virtual void       SelMarker(int msz=3, PIMarker mrk=PI_DotMarker)           = 0;
// Modifications de fonte
  virtual void	     SelFont(PIFont & fnt)				       = 0; 
  virtual void       SelFont(PIFontSize sz=PI_NormalSizeFont, 
                             PIFontAtt att=PI_RomanFont)		       = 0;
  virtual void       SelFontSzPt(int npt=12, PIFontAtt att=PI_RomanFont)       = 0; 

// Selection de zone de trace (clip)
  virtual void       SetClipRectangle(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)  = 0;
  virtual void       ClearClipRectangle()                                      = 0;

// Acces aux attributs graphiques 
  virtual PIColors   GetForeground()    = 0;
  virtual PIColors   GetBackground()    = 0;
  virtual PIGOMode   GetGOMode()        = 0;
  virtual PILineAtt  GetLineAtt()       = 0;
  virtual PIMarker   GetMarker()        = 0;
  virtual int        GetMarkerSize()    = 0;

// Acces a la fonte et ses attributs
  inline  PIFont     GetFont() { return (myFont) ; }
  virtual PIGrCoord  GetFontHeight(PIGrCoord& asc, PIGrCoord& desc);
  virtual PIGrCoord  CalcStringWidth(char const* s);

// Sauvegarde des attributs graphiques 
  virtual void       SaveGraphicAtt();
  virtual void       RestoreGraphicAtt();

protected:
// Pour Save/Restore des attributs graphiques 
  PIWdg* myWdg;
  PIScreenBuffer* myGrb;

  PIFont myFont;
  PIColors  sFCol, sBCol;
  PIGOMode sGOm;
  PIFont sFont;
  PILineAtt sLAtt;
  int sFSize;
  PIMarker sMrk;
  int sMrkSz;
};

typedef PIGraphicGen PIGraphic;

// hierarchie apparente
//   PIGraphic               ( == Gen, mais pas visible de l'utilisateur).
//     PIGraphicWin   ( == X ou Mac)
//     PIGraphicPS
//     PIGraphicUC

#endif      // PIGRAPHGEN_H_SEEN
