// Module PI : Peida Interactive     PIGraphicPS
// Trace graphiques en PostScript    R. Ansari  97
// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA

#include <stdio.h>

#include "pigraphps.h"

//++
// Class	PIGraphicPS
// Lib		PI
// include	pigraphps.h
//
//   	Classe les services de tracé graphique avec sortie PostScript
//	Toutes les méthodes de tracé de "PIGraphic" sont redéfinies pour
//	produire du PostScript 
//--
//++
// Links	Parent
// PIGraphic
//--
//++
// Links	Voir aussi
// PSFile
//--

//++
// Titre	Constructeurs, méthodes
//--
//++
// PIGraphicPS(PSFile * psf, double x0, double y0, double dx, double dy)
//	Création d'un objet "PIGraphicPS" à partir d'un objet "PSFIle* psf".
//	"(x0, y0)" détermine l'origine du nouveau bloc rectangulaire sur 
//	la page et "dx, dy" l'extension du bloc. 
// PIGraphicPS(PSFile * psf, PIWdg* wdg, double ofx, double ofy)
//	Création d'un objet "PIGraphicPS" à partir d'un objet "PSFIle* psf"
//|	x0 = wdg->XPos()+ofx    y0 = wdg->YPos()+ofy
//|	dx = wdg->XSize()       dy = wdg->YSize()
//
// int kind()
//	 Renvoie le type ("= PI_PSFileGraphics")
//--

/* --Methode-- */
PIGraphicPS::PIGraphicPS(PSFile * psf, PIWdg* wdg, double ofx, double ofy)
: PIGraphicGen()
{
BuildFromPSFile(psf, (double)wdg->XPos()+ofx, (double)wdg->YPos()+ofy, 
                     (double)wdg->XSize(), (double)wdg->YSize() );  
}

/* --Methode-- */
PIGraphicPS::PIGraphicPS(PSFile * psf, double x0, double y0, double dx, double dy)
: PIGraphicGen()
{
BuildFromPSFile(psf, x0, y0, dx, dy);
}

/* --Methode-- */
PIGraphicPS::~PIGraphicPS()
{
mPSOut->EndBloc();
}

/* --Methode-- */
int PIGraphicPS::kind()
{
return PI_PSFileGraphics; 
}


/* --Methode-- */
void PIGraphicPS::BuildFromPSFile(PSFile * psf, double x0, double y0, double dx, double dy)
{
mPSOut = psf;

mGOm = PI_GOCopy;

mFCol = mBCol = PI_Grey;
SelForeground(PI_Black);
SelBackground(PI_White);
mLAtt = PI_ThinLine;
SelLine();
mFAtt = PI_BoldFont;  mFSize = 0;
SelFont();
SelMarker(1, PI_DotMarker);

if (psf) psf->NewBloc(x0, y0, dx, dy, dx, dy);
mXmin = mYmin = 0.;
mXmax = dx;  mYmax = dy;
mFCfMap.red = mFCfMap.blue = mFCfMap.blue = 0;
mBCfMap = mFCfMap; 
}

/* --Methode-- */
void PIGraphicPS::GetGrSpace(PIGrCoord& xmin, PIGrCoord& xmax, PIGrCoord& ymin, PIGrCoord& ymax)
{
xmin = ymin = 0;  
xmax = mXmax; ymax = mYmax;
}

/* --Methode-- */
void PIGraphicPS::Erase(PIGrCoord, PIGrCoord, PIGrCoord, PIGrCoord)
{
// A Faire ??? $CHECK$ 
return;
}

/* --Methode-- */
void PIGraphicPS::DrawString(PIGrCoord x, PIGrCoord y, const char* s, int /*pos*/)
{
if(mPSOut)
  mPSOut->DrawString((double)x,(double)y,s,mFCol,mFAtt,mFSize); /* $CHECK$ PIFontSize ?? */
return;
}

/* --Methode-- */
void PIGraphicPS::DrawOpaqueString(PIGrCoord x, PIGrCoord y, const char* s, int /*pos*/)
{
if(mPSOut)
  mPSOut->DrawString((double)x,(double)y,s,mFCol,mFAtt,mFSize); /* $CHECK$ PIFontSize ?? */
return;
}

 
/* --Methode-- */
void PIGraphicPS::DrawLine(PIGrCoord x1, PIGrCoord y1, PIGrCoord x2, PIGrCoord y2)
{
if(mPSOut)
  mPSOut->DrawLine((double)x1,(double)y1,(double)x2,(double)y2,mFCol,mLAtt);
return;
}


/* --Methode-- */
void PIGraphicPS::DrawBox(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
{
if(mPSOut)
  mPSOut->DrawBox((double)x0,(double)y0,(double)dx,(double)dy,mFCol,mLAtt);
return;
}

/* --Methode-- */
void PIGraphicPS::DrawFBox(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
{
if(mPSOut)
  mPSOut->DrawFBox((double)x0,(double)y0,(double)dx,(double)dy, mFCol, mFCol, mLAtt);
return;
}

/* --Methode-- */
void PIGraphicPS::DrawCircle(PIGrCoord x0, PIGrCoord y0, PIGrCoord r)
{
if(mPSOut)
  mPSOut->DrawCircle((double)x0,(double)y0,(double)r,mFCol,mLAtt);
return;
}

/* --Methode-- */
void PIGraphicPS::DrawFCircle(PIGrCoord x0, PIGrCoord y0, PIGrCoord r)
{
if(mPSOut)
  mPSOut->DrawFCircle((double)x0,(double)y0,(double)r,mFCol,mFCol,mLAtt);
return;
}

/* --Methode-- */
void PIGraphicPS::DrawOval(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
{
// $CHECK$ Reza/ Nicolas  12 Nov 98 - A faire
}

/* --Methode-- */
void PIGraphicPS::DrawFOval(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy)
{
// $CHECK$ Reza/ Nicolas  12 Nov 98 - A faire
}

/* --Methode-- */
void PIGraphicPS::DrawPolygon(PIGrCoord *x, PIGrCoord *y, int n, bool cinc)
{
int i;
double *xtmp;
double *ytmp;

if(! mPSOut) return;

xtmp = new double[n];
ytmp = new double[n];
for(i = 0 ; i < n ; i++) {xtmp[i] = (double)x[i] ; ytmp[i] = (double)y[i] ; }
//double xoff,yoff;
//if (cinc) { xoff=yoff=0.; }   // Coord en mode incremental
//else { xoff = (double)x[0];  yoff = (double)y[0]; }   //   Coord en mode absolu
//xtmp[0] = (double)x[0];
//ytmp[0] = (double)y[0];
//for(i=1;i<n;i++) {
//  xtmp[i] = (double)x[i]-xoff;
//  ytmp[i] = (double)y[i]-yoff;
//}
mPSOut->DrawPolygon(xtmp,ytmp,n,mFCol,mLAtt,cinc);
delete[] xtmp;
delete[] ytmp;

return;
}


/* --Methode-- */
void PIGraphicPS::DrawFPolygon(PIGrCoord *x, PIGrCoord *y, int n, bool cinc)
{
int i;
double *xtmp;
double *ytmp;

if(! mPSOut) return;

xtmp = new double[n];
ytmp = new double[n];
for(i = 0 ; i < n ; i++) {xtmp[i] = (double)x[i] ; ytmp[i] = (double)y[i] ; }
//double xoff,yoff;
//if (cinc) { xoff=yoff=0.; }   // Coord en mode incremental
//else { xoff = (double)x[0];  yoff = (double)y[0]; }   //   Coord en mode absolu
//xtmp[0] = (double)x[0];
//ytmp[0] = (double)y[0];
//for(i=1;i<n;i++) {
//  xtmp[i] = (double)x[i]-xoff;
//  ytmp[i] = (double)y[i]-yoff;
//}
mPSOut->DrawFPolygon(xtmp,ytmp,n,mFCol,mFCol,mLAtt,cinc);
delete[] xtmp;
delete[] ytmp;

return;
}

/* --Methode-- */
void PIGraphicPS::DrawArc(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy,double degdeb, double degfin)
{
// $CHECK$ Reza/ Nicolas  12 Nov 98 - A faire
}

/* --Methode-- */
void PIGraphicPS::DrawFArc(PIGrCoord x0, PIGrCoord y0, PIGrCoord dx, PIGrCoord dy,double degdeb, double degfin)
{
// $CHECK$ Reza/ Nicolas  12 Nov 98 - A faire
}

/* --Methode-- */
void PIGraphicPS::DrawMarker(PIGrCoord x0, PIGrCoord y0)
{
if(mPSOut)
  mPSOut->DrawMarker((double)x0,(double)y0,mMrk,mFCol,mMrkSz);
return;
}

/* --Methode-- */
void PIGraphicPS::DrawMarkers(PIGrCoord *x, PIGrCoord *y, int n)
{
int i;
double *xtmp;
double *ytmp;

if( !mPSOut)  return;

xtmp = new double[n];
ytmp = new double[n];
for(i=0;i<n;i++){
  xtmp[i] = (double)x[i];
  ytmp[i] = (double)y[i];
}
mPSOut->DrawMarkers(xtmp,ytmp,n,mMrk,mFCol, mMrkSz);
delete[] xtmp;
delete[] ytmp;

return;
}


/* --Methode-- */
void PIGraphicPS::DrawPixmap(PIGrCoord x, PIGrCoord y, unsigned char *pix, 
                            int sx, int sy, PIColorMap* cmap)
{
if ( (sx < 1) || (sy < 1) )  return;
if ((pix == NULL) || (cmap == NULL)) return;
if(mPSOut) 
  mPSOut->Image((double)x, (double)y, (double)sx, (double)sy, sx, sy, pix, cmap);
return;
}

/* --Methode-- */
void PIGraphicPS::SelForeground(PIColors col)
{
mFCol = col;
return;
}

/* --Methode-- */
void PIGraphicPS::SelBackground(PIColors col)
{
mBCol = col;
return;
}

/* --Methode-- */
void PIGraphicPS::SelForeground(PIColorMap& cmap, int cid)
{
// A Faire Voir Nicolas  
mFCfMap = cmap.GetColor(cid);
mFCol = PI_ColorFromMap;
mPSOut->SelForeground(cmap, cid) ; 
return;
}

/* --Methode-- */
void PIGraphicPS::SelBackground(PIColorMap& cmap, int cid)
{
// A Faire Voir Nicolas  
mBCfMap = cmap.GetColor(cid);
mBCol = PI_ColorFromMap;
return;
}

/* --Methode-- */
void PIGraphicPS::SelGOMode(PIGOMode mod)
{
mGOm = mod;
return;
}

/* --Methode-- */
void PIGraphicPS::SelFontSzPt(int npt, PIFontAtt att)
{
mFSize = npt;
mFAtt = att;
return;
}

static int fntsz[5] = {8,10,12,14,16};

/* --Methode-- */
void PIGraphicPS::SelFont(PIFontSize sz, PIFontAtt att)
{
int i;
switch (sz) {
  case PI_SmallSizeFont:
    i = 0;
    break;
  case PI_NormalSizeFont:
    i = 2;
    break;
  case PI_BigSizeFont:
    i = 4;
    break;
  default:
    i=2;
    break;
  }
mFSize = fntsz[i];
mFAtt = att;
return;
}



/* --Methode-- */
void PIGraphicPS::SelLine(PILineAtt att)
{
mLAtt = att;
return;
}


/* --Methode-- */
void PIGraphicPS::SelMarker(int msz, PIMarker mrk)
{
if (msz > 1)  { mMrk = mrk;  mMrkSz = msz; }
else  { mMrk = PI_DotMarker;  mMrkSz = 1; }
return;
}


/* --Methode-- */
void PIGraphicPS::SetClipRectangle(PIGrCoord /*x0*/, PIGrCoord /*y0*/, PIGrCoord /*dx*/, PIGrCoord /*dy*/)
{
/*  $CHECK$  A FAIRE , voir Nicolas  */
return;
}

/* --Methode-- */
void PIGraphicPS::ClearClipRectangle()
{ 
/*  $CHECK$  A FAIRE , voir Nicolas  */
return;
}

/* --Methode-- */
PIColors  PIGraphicPS::GetForeground() 
{
return (mFCol);
}

/* --Methode-- */
PIColors  PIGraphicPS::GetBackground() 
{
return (mBCol);
}


/* --Methode-- */
PIGOMode   PIGraphicPS::GetGOMode()
{
return (mGOm);
}

/* --Methode-- */
PIFontAtt  PIGraphicPS::GetFontAtt()
{
return (mFAtt);
}

/* --Methode-- */
int        PIGraphicPS::GetFontSize()
{
return (mFSize);
}

/* --Methode-- */
PILineAtt  PIGraphicPS::GetLineAtt()
{
return (mLAtt);
}

/* --Methode-- */
PIMarker   PIGraphicPS::GetMarker()
{
return (mMrk);
}

/* --Methode-- */
int        PIGraphicPS::GetMarkerSize()
{
return (mMrkSz);
}

/* --Methode-- */
int        PIGraphicPS::GetFontHeight(int& asc, int& desc)   
{
/*  $CHECK$  A refaire , voir Nicolas  */
asc = mFSize; desc = 0; 
return(asc+desc);
}


/* --Methode-- */
PIGrCoord PIGraphicPS::CalcStringWidth(char const* s)
{
return((double)(mFSize*strlen(s)*0.5));   /*  facteur 0.5 ad'hoc $CHECK$  Voir Nicolas ! */
}

/* --Methode-- */
void PIGraphicPS::SaveGraphicAtt()
{  
// Pour optimier l'implementation de PIBaseWdgGen
sFCol = mFCol;    sBCol = mBCol;
sGOm = mGOm;
sFAtt = mFAtt;   sFSize = mFSize;
sMrk = mMrk;   sMrkSz = mMrkSz;
return;
}


/* --Methode-- */
void PIGraphicPS::RestoreGraphicAtt()
{
  if (sFCol != PI_ColorFromMap) SelForeground(sFCol);  
// else    A faire Nicolas  
  if (sBCol != PI_ColorFromMap) SelBackground(sBCol);
// else    A faire Nicolas  
  SelGOMode(sGOm);
  SelFontSzPt(sFSize, sFAtt);
  SelLine(sLAtt);
  SelMarker(sMrkSz, sMrk);
  return;
}





