// Module PI : Peida Interactive     PIImage
// Affichage d'image            R. Ansari  05/95
// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA
//                        Refonte   Reza   10/95


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "piimage.h"
#include "piimgtools.h"
#include "pidrwtools.h"
#include PIAPP_H

//++
// Class	PIImage
// Lib		PI
// include	piimage.h
//
//   	Classe pour la l'affichage et la manipulation d'images.
//	Peut contrôler un PIPixmap pour l'affichage d'une zone
//	agrandie (zoom) et un PIPixmap pour l'affichage de toute
//	l'image (réduite).
//	Utilise les adaptateur de tableaux 2D manipuler le
//	contenu des images ("P2DArrayAdapter").
//
//	* Bouton-1 : Envoie le message "PIMsg_Active" et affiche
//	les coordonnées courantes et la valeur du pixel, 
//	et positionne le pavé.
//	* Bouton-2 : Permet de définir une zone de l'image et repositionne le pavé.
//	* Bouton-3 : Permet de déplacer l'image dans la fenêtre
//
//	Gestion du clavier :
//	* <Alt>O : Affichage de la fenêtre de contrôle des paramètres de visualisation.
//	* <Alt>G : Affichage de la fenêtre de changement des attributs graphiques
//	* <Alt>R : Rafraîchit l'affichage.
//	* <Alt>V : Copier/*Coller* Ajout du texte du buffer copier/coller
//	sur l'objet à la position courante.
//	* <Alt>C : *Copier*/Coller Permet de copier le contenu de la zone sélectionnée
//	de l'image sous forme texte.
//	* <Alt>Z : Supprime les textes et signes ajoutés au dessin.
//	* Touches Curseurs : déplace la pavé.
//--
//++
// Links	Parents
// PIPixmap
//--

//++
// Titre	Constructeurs, méthodes
//--
//++
//  PIImage(PIContainerGen *par, char *nom=NULL, int sx=0, int sy=0, int px=0, int py=0)
//	Créateur
//  
//--

// --------------------------------------------------------------------------------
// ----------------------------- Classe PIImage -----------------------------------
// --------------------------------------------------------------------------------
// Variable globale pour la gestion de l'image courante 
PIImage* PIImage::cur_piimage = NULL;
/* --Methode-- */
PIImage* PIImage::CurrentPIImage() 
{ 
return(cur_piimage); 
}

/* --Methode-- */
void PIImage::SetCurrentPIImage(PIImage* curimg) 
{ 
cur_piimage = curimg;
}

/* --Methode-- */
PIImage::PIImage(PIContainerGen *par, char *nom,
   int sx, int sy, int px, int py) :
  PIPixmap(par, nom, sx, sy, px, py)
{

img = NULL;
aisup = false;
curshow = true;
winovis = true;     // $CHECK$ Reza A enlever si possible 17/6/96


zow = NULL;   // Widget zoom
gvw = NULL;   // widget vue globale
cmvw = NULL;  // widget ColorMapView
// Fenetre transient et Label pour affichage de l'info (texte PixVal)
int tx, ty;
PIApplicationPrefCompSize(tx, ty);
tx *= 5;    ty = (int)(ty*0.8);
trtw = new PIWindow(this, "PixVal", PIWK_transient, tx, ty, 0, 0);
trtw->SetAutoDelChilds(true);
trtlb = new PILabel(trtw, "PixVal", tx, ty, 0, 0);
trtlb->SetBinding(PIBK_fixed,PIBK_fixed, PIBK_fixed,PIBK_fixed);
ustrtw = atrtw = false;
if ((sx < 300) || (sy < 150) ) atrtw = true;
showinfo = false;

gpixm = zpixm = pixm = NULL;
xsgpxm = xszpxm = xspxm = 0;
ysgpxm = yszpxm = yspxm = 0;
lut = NULL; 
offx = offy = 0;
xpav = ypav = 0;
xpv0 = ypv0 = 0;
xszpav = yszpav = 1;
xmv0 = ymv0 = -1;
dxmv = dymv = 0;
xcurs = ycurs = -1;
zoom = 1;
zmgv = 1;

mdrw = new PIElDrawer();
gvdrw = new PIElDrawer();
AddDrawer(mdrw, true, false, false);

SetLut(0., 32000., kLutType_Lin, 0, false);
SetColMapId(CMAP_COLRJ32);
// pour le copier-coller
cpbuffer = NULL;
cpbuflen = 0;

SetBackgroundColor(PI_Black);

ActivateKeyboard();
ActivateButton(1);
ActivateMove(1);
ActivateButton(2);
ActivateMove(2);
ActivateButton(3);
ActivateMove(3);

cur_piimage = this;
}

/* --Methode-- */
PIImage::~PIImage()
{
if (pixm) delete pixm;
if (zpixm) delete zpixm;
if (zow) 
  {
  zow->SetPixmap(NULL,0,0);
  zow->EraseWindow();
  }
if (gpixm) delete gpixm;
if (gvw) 
  {
  gvw->SetPixmap(NULL,0,0);
  gvw->EraseWindow();
  gvw->SetMsg(0); gvw->SetMsgParent(NULL); 
  gvw->SetUserData(NULL, 0); 
  }
if (cmvw)  cmvw->SetColMap(NULL, 1., -1., true);
if (lut) delete lut;
delete mdrw;
delete gvdrw;
if (aisup && img)  delete img;   // Suppression automatique d'image
delete trtw;
if (cpbuffer)  delete[] cpbuffer;
if (this == cur_piimage)  cur_piimage = NULL;
}

/* --Methode-- */
void PIImage::Process(PIMessage msg, PIMsgHandler* sender, void* data)
{
if (UserMsg(msg) == (Msg()+626))
  {
  if (ModMsg(msg) == PIMsg_Click) 
    { int* pxy=(int *)data;   SetPave(pxy[0]*zmgv, pxy[1]*zmgv); }
  if (ModMsg(msg) == PIMsg_Resize)
    { ComputeGloVPixmap();   SetGloVPixmap(); }
  }
else ReSend(msg, sender, data);
return;
}

/* --Methode-- */
void PIImage::SetImage(P2DArrayAdapter *pim, bool ad, bool refr)
{

offx = offy = 0;
xpav = ypav = 0;
xszpav = yszpav = 1;
img = pim;
if (gpixm) delete gpixm;
gpixm = NULL;
xsgpxm = ysgpxm = 0;
zmgv = 1;

if (img)  {
//  SetSize(img->XSize(), img->YSize());
  CenterPave();
  double min=1., max=-1., moy, sig;
  int nbnul, nbsat;
  img->CheckDyn(min, max, moy, sig, nbnul, nbsat);
  SetLut(min, max, kLutType_Lin, 1, refr);
  aisup = ad;
  }
else aisup = false;
return;
}

/* --Methode-- */
void PIImage::ChangeAxesConfiguration(bool ix, bool iy, bool xy, bool refr)
{
if (!img) return;
bool invx, invy, exy;
img->GetAxesConfiguration(invx, invy, exy);
if (ix)  invx = !invx;
if (iy)  invy = !invy;
if (xy)  exy = !exy;
img->ConfigureAxes(invx, invy, exy);
ComputeGloVPixmap();
if (refr) Apply();
}

/* --Methode-- */
void PIImage::SetZoomWin(PIPixmap * zw, bool refr) 
{
zow = zw;
if (zow && refr && img)
  ComputeZoomPixmap();
return;
}

/* --Methode-- */
void PIImage::SetGloVWin(PIPixmap * zw, bool refr) 
{
gvw = zw;
if (gvw && img)  
  { ComputeGloVPixmap();
  if (refr) SetGloVPixmap(); } 
return;
}

/* --Methode-- */
void PIImage::SetCMapWin(PICMapView * cw, bool refr)
{
cmvw = cw;
if (cmvw && refr) cmvw->SetColMap(cmap, Lut()->Min(), Lut()->Max(), true);
}


/* --Methode-- */
void PIImage::UseInfoWin(bool trw)
{
ustrtw = trw;
}

/* --Methode-- */
void PIImage::ShowInfo(bool si)
{
if (showinfo == si) return;
showinfo = si;
if (showinfo && img)  { 
  char buff[256];
  double x,y;
  img->XYCoord(xpav, ypav, x, y);
  sprintf(buff," X= %g , Y= %g  Pix= %g (%d,%d)      ", 
          x, y , (*img)(xpav, ypav), xpav, ypav );
  DrawInfo(mWGrC, buff);
  }
else DrawInfo(mWGrC, NULL);
}

/* --Methode-- */
void PIImage::ShowCursor(bool sc)
{
if (curshow == sc) return;
curshow = sc;
if (curshow)  DrawCursor(mWGrC);
else DrawCursor(mWGrC, -1, -1);
return;
}

/* --Methode-- */
void PIImage::SetLut(double min, double max, int typlut, int lauto, bool refr)
{
if (lut) delete(lut);
if (lauto && img) 
  {
  int nbsig = lauto;  
  double fracmax = 1. - 0.05*nbsig;
  img->ComputeLut_PicHisto(min, max, nbsig, fracmax);
  }

lut = new LUT(min, max, NbCol(), typlut);

ComputeGloVPixmap();
if (refr) Apply();
return;
}


/* --Methode-- */
void PIImage::SetLut(LUT *clut, bool refr)
{
LUT * olut = lut;
lut = new LUT(clut->Min(), clut->Max(), NbCol(), clut->Type());
if (olut) delete olut;

ComputeGloVPixmap();
if (refr) Apply();
return;
}

/* --Methode-- */
void PIImage::SetZoomF(float fzm, bool refr)
{
int zm;

if (fzm < 0.01) return;
if (fzm < 1.)  zm = (int)(-(1./fzm));
else zm = (int)(fzm+0.25);
SetZoom(zm, refr);
return;
}

/* --Methode-- */
void PIImage::SetZoom(int zm, bool refr)
{
if ((zm == 0) || (zm == -1) )  zoom = 1;
else if (zm > 20)  zoom = 20;
else if (zm < -20) zoom = -20;
else zoom = zm;
if (img)
  { SetOffsetFromPave();
  if (refr) Apply(); }
return;
}

/* --Methode-- */
float PIImage::GetZoomF()
{
if (zoom >= 1)  return((float)zoom);
else return(-1./(float)zoom);
}


/* --Methode-- */
void PIImage::SetOffset(int ox, int oy, bool refr)
{
if (img == NULL)  {offx = offy = 0;  return; }
if (ox < 0)  ox = 0;
if (ox >= (img->XSize()-1))  ox = img->XSize()-2;
if (oy < 0)  oy = 0;
if (oy >= (img->YSize()-1))  oy = img->YSize()-2;
offx = ox;  offy = oy;
CenterPave();
if (refr) Apply();
return;
}


/* --Methode-- */
void PIImage::SetPave(int x, int y, bool refr, bool cent)
{
int xc, yc;

if (img == NULL)  
  { offx = offy = 0; 
  xpav = ypav = 0; 
  return; }

if ( (x >= (img->XSize()-1)) || ( x < 0)  ||
     (y >= (img->YSize()-1)) || ( y < 0)  ) return;

if ( (x == xpav) && (y == ypav) )  return;
xpav = x;  ypav = y;

if ( PosImg2W(xpav,ypav,&xc, &yc) || cent)  // Il faut recenter l'image
  { SetOffsetFromPave();  
  if (refr) Apply(true);  }
else if (refr)
  { Apply(false);  if (curshow)  DrawCursor(mWGrC);  }

return;
}

/* --Methode-- */
void PIImage::SetColMap(PIColorMap* cmp, bool refr)
{
if (!cmp)  return;
int cmapid = cmp->Type();
if ( (cmapid == CMAP_GREY32) || (cmapid == CMAP_GREYINV32) || 
     (cmapid == CMAP_GREY128) || (cmapid == CMAP_GREYINV128))  mdrw->SetColAtt(PI_Red);
else mdrw->SetColAtt(PI_White);
PIPixmap::SetColMap(cmp, refr);
if (zow)  zow->SetColMap(cmp, refr);
if (gvw)  gvw->SetColMap(cmp, refr);
if (cmvw) cmvw->SetColMap(cmap, Lut()->Min(), Lut()->Max(), refr);
return;
}

/* --Methode-- */
void PIImage::SetColMapId(CMapId cmapid, bool refr)
{
if ( (cmapid == CMAP_GREY32) || (cmapid == CMAP_GREYINV32) || 
     (cmapid == CMAP_GREY128) || (cmapid == CMAP_GREYINV128))  mdrw->SetColAtt(PI_Red);
else mdrw->SetColAtt(PI_White);
PIPixmap::SetColMapId(cmapid, refr);
if (zow)  zow->SetColMapId(cmapid, refr);
if (gvw)  gvw->SetColMapId(cmapid, refr);
if (cmvw) cmvw->SetColMapId(cmapid, Lut()->Min(), Lut()->Max(), refr);
return;
}


/* --Methode-- */
void PIImage::Apply(bool mw)
{
if (img == NULL)  return;
if (mw)  {  
  ComputePixmap();
  Send(Msg(), PIMsg_Active);
  cur_piimage = this;
  PIDrwTools::SetCurrentBaseWdg(this);
  }
else {
  char buff[256];
  double x,y;
  img->XYCoord(xpav, ypav, x, y);
  sprintf(buff," X= %g , Y= %g  Pix= %g (%d,%d)      ", 
          x, y , (*img)(xpav, ypav), xpav, ypav );
  if (ustrtw || atrtw)  trtlb->SetLabel((string)buff);
  else DrawInfo(mWGrC, buff);
  }
if (zow != NULL)   ComputeZoomPixmap();
if (gvw != NULL)
  if ( (gvw->UserData() != this) || (mw) )  SetGloVPixmap();
if (cmvw) cmvw->SetColMap(cmap, Lut()->Min(), Lut()->Max(), true);
  
return;
}

/* --Methode-- */
void PIImage::Resize()
{
// printf("PIImage::Resize\n");
// On bascule sur la fenetre transient pour l'affichage des valeurs si fenetre trop petite
if ((XSize() < 300) || (YSize() < 150) ) atrtw = true;  
else atrtw = false;
PIPixmap::Resize();
CenterPave();
Apply();
return;
}

/* --Methode-- */
void PIImage::Draw(PIGraphic* g, int x0, int y0, int dx, int dy)
{
PIPixmap::Draw(g, x0, y0, dx, dy);
winovis = false;    // $CHECK$ Reza A enlever si possible 17/6/96
if (curshow) {
  int xc,yc;
  PosImg2W(xpav, ypav, &xc, &yc);
  if ((xc >= x0) && (xc < x0+dx) && 
      (yc >= y0) && (yc < y0+dy) )  DrawCursor(g, xc, yc);
  }

if (showinfo && img) {
  char buff[256];
  double x,y;
  img->XYCoord(xpav, ypav, x, y);
  sprintf(buff," X= %g , Y= %g  Pix= %g (%d,%d)      ", 
        x, y , (*img)(xpav, ypav), xpav, ypav );
  DrawInfo(mWGrC, buff); 
  }

return;
}

/* --Methode-- */
void PIImage::Keyboard(int key, PIKeyModifier kmod)
{
cur_piimage = this;
if (kmod == PIKM_Alt) {
  if      (key == 'R' || key == 'r') Apply(true);  // Pour tout rafraichir  
  else if (key == 'V' || key == 'v') RequestSelection();  // Pour coller (copier/coller)  
  else if (key == 'Z' || key == 'z') { mdrw->ElDelAll();  Refresh(); } // Pour supprimer tous les signes 
  else if (key == 'O' || key == 'o') PIImgTools::ShowPIImgTools();   // Fentre LUT et options 
  else if (key == 'G' || key == 'g') {   // Fentre attributs graphiques 
    PIDrwTools::SetCurrentBaseWdg(this);
    PIDrwTools::ShowPIDrwTools();   // Fentre axes et options de trace
    }
// ----  Le copier ---- 
  else if ((key == 'C' || key == 'c') && img) { 
    // On limite la taille a 48x48
    int i1 = XPave();  
    int i2 = ( XSzPave() < 48 ) ? i1+XSzPave() : i1+48;
    int j1 = YPave();  
    int j2 = ( YSzPave() < 48 ) ? j1+YSzPave() : i1+48;
    if ( ( (i2-i1) < 1 ) || ((j2-j1) < 1) ) return;
    if (!ClaimSelection())  return;  // On n'a pas pu prendre possession de la zone d'echange
    if (cpbuffer)  delete[] cpbuffer;
    cpbuflen = (j2-j1)*(i2-i1+2)*12+(j2-j1)+128;
    cpbuffer = new char[cpbuflen];
    sprintf(cpbuffer,"PIImage: Pave(%dx%d) en (%d, %d) MaxCopie= 48x48 \n", 
            XSzPave(), YSzPave(), i1, j1);
    int i,j;
    int l = strlen(cpbuffer);
    for(j=j1; j<j2; j++) {
      sprintf(cpbuffer+l,"L %3d:",j);
      l += 6;
      for(i=i1; i<i2; i++) { sprintf(cpbuffer+l," %10g", (*img)(i, j));  l += 11; }
      cpbuffer[l] = '\n';  l++;
      }
    cpbuffer[l] = '\0';
    cpbuflen = l+1;
    }
  }


else if (kmod == PIKM_Blank) {
  switch (key) {
    case PIK_Up :
      SetPave(xpav, ypav-1, true, false);
      break;
    case PIK_Down :
      SetPave(xpav, ypav+1, true, false);
      break;
    case PIK_Left :
      SetPave(xpav-1, ypav, true, false);
      break;
    case PIK_Right :
      SetPave(xpav+1, ypav, true, false);
      break;
    default :
      break;
  }
}

}


/* --Methode-- */
void PIImage::But1Press(int x, int y)
{
int xp, yp;

Send(Msg(), PIMsg_Active);
cur_piimage = this;
PIDrwTools::SetCurrentBaseWdg(this);
if (img == NULL)  return;
if ( PosW2Img(x, y, &xp, &yp) )  return;
SelPointerShape(PI_CrossPointer);
xpav = xp;  ypav = yp;
if (ustrtw || atrtw) ShowTrTxW();
Apply(false);
if (curshow)  DrawCursor(mWGrC, -1,-1);
return;
}


/* --Methode-- */
void PIImage::Ptr1Move(int x, int y)
{
int xp, yp;
if (img == NULL)  return;
if ( PosW2Img(x, y, &xp, &yp) )  return;
xpav = xp;  ypav = yp;
Apply(false);
return;
}


/* --Methode-- */
void PIImage::But1Release(int /*x*/,  int /*y*/)
{
SelPointerShape(PI_ArrowPointer);
if (curshow)  DrawCursor(mWGrC);
if (ustrtw || atrtw) trtw->Hide();
else if (!showinfo) DrawInfo(mWGrC, NULL);
return;
}


/* --Methode-- */
void PIImage::But2Press(int x, int y)
{

Send(Msg(), PIMsg_Active);
cur_piimage = this;
PIDrwTools::SetCurrentBaseWdg(this);
if (img == NULL)  return;
if ( PosW2Img(x, y, &xpv0, &ypv0) )  {  xmv0 = -1;  return; }
xmv0 = x;  ymv0 = y;  dxmv = dymv = 0;
if (curshow)  DrawCursor(mWGrC,-1,-1);
mWGrC->SelGOMode(PI_GOXOR);
if (GetColMapId() == CMAP_COLRJ32)
mWGrC->SelForeground(PI_Yellow);
else mWGrC->SelForeground(PI_Magenta);
mWGrC->SelLine(PI_NormalLine);
if (ustrtw || atrtw) ShowTrTxW();
return;
}

/* --Methode-- */
void PIImage::Ptr2Move(int x, int y)
{
int xp, yp;
if (img == NULL)  return;
if (xmv0 < 0)  return;
if ( PosW2Img(x, y, &xp, &yp) )  return;
mWGrC->DrawBox(xmv0, ymv0, dxmv, dymv);
dxmv = x-xmv0;  dymv = y-ymv0;
mWGrC->DrawBox(xmv0, ymv0, dxmv, dymv);

 {
 char buff[256];  
 double x,y;
 img->XYCoord(xp, yp, x, y);
 sprintf(buff," X= %g , Y= %g  Pix= %g  (C= %d,%d)   ", 
         x, y , (*img)(xp, yp),  (xp+xpv0)/2, (yp+ypv0)/2 );
 if (ustrtw || atrtw) trtlb->SetLabel((string)buff);
 else DrawInfo(mWGrC, buff);
 }

return;
}

/* --Methode-- */
void PIImage::But2Release(int x, int y)
{
int xp2, yp2;

if (img == NULL)  return;
if (xmv0 < 0)  return;
mWGrC->DrawBox(xmv0, ymv0, dxmv, dymv);
mWGrC->SelGOMode(PI_GOCopy);
mWGrC->SelForeground(PI_White);
if ( PosW2Img(x, y, &xp2, &yp2) )  
  PosW2Img(xmv0+dxmv, ymv0+dymv, &xp2, &yp2);
xpav = (xpv0+xp2)/2;
ypav = (ypv0+yp2)/2;
xszpav = ((xp2-xpv0) > 0) ? (xp2-xpv0) : 1;
yszpav = ((yp2-ypv0) > 0) ? (yp2-ypv0) : 1;

Apply(false);
if (curshow)  DrawCursor(mWGrC);
if (ustrtw || atrtw) trtw->Hide();
else if (!showinfo) DrawInfo(mWGrC, NULL);
return;
}


/* --Methode-- */
void PIImage::But3Press(int x, int y)
{
int xp, yp;

Send(Msg(), PIMsg_Active);
cur_piimage = this;
PIDrwTools::SetCurrentBaseWdg(this);
if (img == NULL)  return;
if ( PosW2Img(x, y, &xp, &yp) )  { xmv0 = -1;  return; }
if (curshow)  DrawCursor(mWGrC,-1,-1);
if (ustrtw || atrtw) ShowTrTxW();
SelPointerShape(PI_TDLRArrowPointer);
xmv0 = xp;
ymv0 = yp;
return;
}


/* --Methode-- */
void PIImage::Ptr3Move(int x, int y)
{
int xp, yp;
if (img == NULL)  return;
if (xmv0 < 0)  return;
if ( PosW2Img(x, y, &xp, &yp) )  return;

char buff[256];
sprintf(buff," DelX= %d , DelY= %d    ", xp-xmv0, yp-ymv0);
if (ustrtw || atrtw) trtlb->SetLabel((string)buff);
else DrawInfo(mWGrC, buff);
}

/* --Methode-- */
void PIImage::But3Release(int x, int y)
{
int xp, yp;

SelPointerShape(PI_ArrowPointer);
if (ustrtw || atrtw) trtw->Hide();
if (img == NULL)  return;
if (xmv0 < 0)  return;
if ( PosW2Img(x, y, &xp, &yp) )  return;

offx -= (xp-xmv0);
offy -= (yp-ymv0);

if (offx < 0)  offx = 0;
if (offy < 0)  offy = 0;
if (offx >= img->XSize())  offx = img->XSize();
if (offy >= img->YSize())  offy = img->YSize();
xpav = xmv0;  ypav = ymv0;
xmv0 = ymv0 = -1;
Apply();
return;
}


/* --Methode-- */
void PIImage::PasteSelection(unsigned int typ, void *pdata, unsigned int l)
{
if (!img) return;
if (typ != PICP_string) return;
int ll = (l<256) ? l+1 : 256;
char pc[256];
strncpy(pc, (char*)pdata, ll-1);  pc[ll-1] = '\0';
double fx, fy;
img->Coord(xpav, ypav, fx, fy); 
mdrw->ElAddText(fx, fy, pc );
mdrw->Refresh();
}

/* --Methode-- */
void * PIImage::ProvideSelection(unsigned int& typ, unsigned int& len)
{
typ = PICP_string;
len = cpbuflen;
return(cpbuffer);
}

/* --Methode-- */
void PIImage::SelectionLost()
{
if (cpbuffer)  delete[] cpbuffer;
cpbuffer = NULL;
cpbuflen = 0;
return;
}



/* --Methode-- */
void PIImage::ComputePixmap()
{
unsigned int xwsz, ywsz;

if (img == NULL)  return;
xwsz = XSize();
ywsz = YSize();

pixm = img->ComputePixmap(lut, offx, offy, zoom, xwsz, ywsz, pixm, &xspxm, &yspxm);
int xw1, yw1, xw2, yw2;
xw1 = (xwsz-xspxm)/2;
if (xw1 < 0) xw1 = 0;
yw1 = (ywsz-yspxm)/2;
if (yw1 < 0) yw1 = 0;
xw2 = xspxm+xw1;
yw2 = yspxm+yw1;
SetDefaultDrawRectangle(xw1, yw1, xw2, yw2, false);
// printf("--DBG-- ComputePixmap() %d %d $ %d %d :: %d %d , %d %d \n", xwsz, ywsz, xspxm, yspxm, xw1, yw1, xw2, yw2);
int x1,y1, x2,y2;
ofx = xw1;  ofy = yw1;
PosW2Img(xw1, yw1, &x1, &y1);
PosW2Img(xw2, yw2, &x2, &y2);
double fx1,fy1, fx2, fy2; 
img->Coord(x1,y1, fx1, fy2);  // fy1 et fy2 echange expres pour utiliser kAxeDirAuto  
img->Coord(x2,y2, fx2, fy1);  // En effet Image de haut vers bas, Axes de bas vers haut par defaut 
SetDefaultDrawerLimits(fx1, fx2, fy1, fy2, kAxeDirAuto, kAxeDirAuto);
// printf("--DBG2-- ComputePixmap() %g %g  %g %g  \n", fx1, fx2, fy1, fy2);
xcurs = ycurs = -1;
SetPixmap(pixm, xspxm, yspxm, true, xw1, yw1); 
// Refresh();
return; 
}


/* --Methode-- */
void PIImage::ComputeZoomPixmap()
{
unsigned int xwsz, ywsz;
int lofx, lofy;
int zm;

if (zow == NULL)  return;
if (img == NULL)  return;

xwsz = zow->XSize();
ywsz = zow->YSize();

zm = zoom+4;
if ( (zm==-1) || (zm == 0) ) zm = 1;
if (zm > 0)
  {
  lofx = xpav-(xwsz/2/zm);
  lofy = ypav-(ywsz/2/zm);
  }
else 
  {
  lofx = xpav+(xwsz*zm/2);
  lofy = ypav+(ywsz*zm/2);
  }
if (lofx < 0)  lofx = 0;
if (lofy < 0)  lofy = 0;

zpixm = img->ComputePixmap(lut, lofx, lofy, zm, xwsz, ywsz, zpixm, &xszpxm, &yszpxm);
zow->SetColMap(cmap, false);
zow->SetPixmap(zpixm, xszpxm, yszpxm); 
zow->SetUserData((void *)this, 0);
// zow->Refresh();
return; 

}


/* --Methode-- */
void PIImage::ComputeGloVPixmap()
{
unsigned int xwsz, ywsz;
int zmx,zmy;

if (gvw == NULL)  return;
if (img == NULL)  return;

xwsz = gvw->XSize();
ywsz = gvw->YSize();

zmx = img->XSize()/xwsz;
zmy = img->YSize()/ywsz;

if (zmx < zmy)   zmx = zmy;
if (zmx < 1)  zmx = 1;
zmgv = zmx;
if (zmx > 1)  zmx = -zmx;
gpixm = img->ComputePixmap(lut, 0, 0, zmx, xwsz, ywsz, gpixm, &xsgpxm, &ysgpxm);
// printf("DEBUG-ComputeGloVPixmap()  %d-%d , (%d,%d) , %d-%d \n", xwsz, ywsz, zmx, zmy, xsgpxm, ysgpxm);
return;
}

/* --Methode-- */
void PIImage::SetGloVPixmap()
{
float zm;
int x,y, dx,dy;

int xw1, yw1, xw2, yw2;
xw1 = (gvw->XSize()-xsgpxm)/2;
if (xw1 < 0) xw1 = 0;
yw1 = (gvw->YSize()-ysgpxm)/2;
if (yw1 < 0) yw1 = 0;
xw2 = xsgpxm+xw1;
yw2 = ysgpxm+yw1;

if (zoom > 0) zm = zmgv*zoom;
else zm = (float)zmgv/(float)(-zoom);
x = offx/zmgv+1+xw1;
y = offy/zmgv+1+yw1;
dx =  (int) ( (float)XSize()/zm-1. );  
dy =  (int) ( (float)YSize()/zm-1. );  

gvw->DeleteDrawers();
gvdrw->ElDelAll();
gvdrw->SetLimits(xw1, xw2, yw1, yw2, kAxeDirLtoR, kAxeDirUpDown);
int cmapid = cmap->Type();
if ( (cmapid == CMAP_GREY32) || (cmapid == CMAP_GREYINV32) || 
     (cmapid == CMAP_GREY128) || (cmapid == CMAP_GREYINV128)) gvdrw->SetColAtt(PI_Red); 
else gvdrw->SetColAtt(PI_Yellow);
gvdrw->SetLineAtt(PI_NormalLine);
gvdrw->ElAddRect(x,y,dx,dy);
gvw->AddDrawer(gvdrw, xw1, yw1, xw2, yw2, false); 
gvw->SetColMap(cmap, false);
gvw->SetPixmap(gpixm, xsgpxm, ysgpxm, true, xw1, yw1); 
gvw->SetUserData((void *)this, 0);
gvw->SetMsg(Msg()+626);
gvw->SetMsgParent(this);

return; 
}

/* --Methode-- */
void PIImage::DrawCursor(PIGraphic* g) 
{
int xc, yc;
if (PosImg2W(xpav, ypav, &xc, &yc)) DrawCursor(g, -1, -1);
else DrawCursor(g, xc, yc);
return;
}

#define CURSHSIZE  25
 
/* --Methode-- */
void PIImage::DrawCursor(PIGraphic* g, int xc, int yc)
{

if (winovis)  return;      // $CHECK$ Reza A enlever si possible 17/6/96

g->SelGOMode(PI_GOCopy);
if ( (GetColMapId() == CMAP_GREY32) || (GetColMapId() == CMAP_GREYINV32) ||
     (GetColMapId() == CMAP_GREY128) || (GetColMapId() == CMAP_GREYINV128) )  g->SelForeground(PI_Red);
else  g->SelForeground(PI_White);

if (zoom < 3)  g->SelLine(PI_NormalLine);
else g->SelLine(PI_ThickLine);

if ((xcurs>=0) && (ycurs>=0) && (g->kind() != PI_PSFileGraphics ) ) {
  PIPixmap::Draw(g, xcurs-3, ycurs-CURSHSIZE, 6, CURSHSIZE*2); 
  PIPixmap::Draw(g, xcurs-CURSHSIZE, ycurs-3, CURSHSIZE*2, 6); 
}
if ((xc >= 0) && (yc >= 0)) 
  {
  xcurs = xc;   ycurs = yc;
  g->DrawLine(xcurs-CURSHSIZE, ycurs, xcurs-4, ycurs);
  g->DrawLine(xcurs+4, ycurs, xcurs+CURSHSIZE, ycurs);
  g->DrawLine(xcurs, ycurs-CURSHSIZE, xcurs, ycurs-4);
  g->DrawLine(xcurs, ycurs+4, xcurs, ycurs+CURSHSIZE);
  }
else { xcurs = ycurs = -1; }

g->SelGOMode(PI_GOCopy);
g->SelLine(PI_NormalLine);
g->SelForeground(PI_White);
return;
}

 
/* --Methode-- */
void PIImage::DrawInfo(PIGraphic* g, char* txt)
{
g->SelFont(PI_NormalSizeFont, PI_RomanFont);
if (txt) { 
  PIColors fgc = g->GetForeground();
  PIGOMode gm = g->GetGOMode();
  g->SelGOMode(PI_GOCopy);
  g->SelForeground(PI_White);
  g->SelBackground(PI_Black);
  g->DrawOpaqueString(20, YSize()-5, txt);
  g->SelGOMode(gm);
  g->SelForeground(fgc);
  }
else {
  int a,d,h;
  h = g->GetFontHeight(a, d);
  if (g->kind() != PI_PSFileGraphics )   PIPixmap::Draw(g, 0, YSize()-10-h, XSize(), h+10); 
  }
return;
}

/* --Methode-- */
void PIImage::ShowTrTxW()
{
if (trtw) 
  {
  int tpx, tpy;
  GetScreenPos(tpx, tpy);
  tpy -= (trtw->YSize()+5);
  if (tpy < 0)  tpy = 0;
  trtw->SetPos(tpx, tpy);
  trtw->Show();  
  }

return;
}

/* --Methode-- */
int PIImage::PosW2Img(int xiw, int yiw, int * xp, int * yp)
{
if (!img) { *xp = *yp = 0;  return(1); }
xiw -= ofx;  yiw -= ofy;   // Offset d'affichage du pixmap
if (zoom > 0)
  {
  *xp = xiw/zoom+offx;
  *yp = yiw/zoom+offy;
  }
else
  {
  *xp = offx-xiw*zoom;
  *yp = offy-yiw*zoom;
  }

if ( (*xp >= 0) && (*xp < img->XSize() ) &&
     (*yp >= 0) && (*yp < img->YSize() )  )   return(0);
else return(1);
}


/* --Methode-- */
int PIImage::PosImg2W(int xp, int yp, int * xiw, int * yiw)
{
if (!img) { *xiw = *yiw = -1;  return(1); }
if (zoom > 0)
  {
  *xiw = (xp-offx)*zoom+(zoom/2);
  *yiw = (yp-offy)*zoom+(zoom/2);
  }
else
  {
  *xiw = (offx-xp)/zoom;
  *yiw = (offy-yp)/zoom;
  }

*xiw += ofx;  *yiw += ofy;    // Offset d'affichage du pixmap
if (*xiw > XSize())  *xiw = -1;
if (*yiw > YSize())  *yiw = -1;

if ((*xiw < 0) || (*yiw < 0))  return(1);
else return(0);
}


/* --Methode-- */
void PIImage::SetOffsetFromPave()
{
if (!img) { offx = offy = 0; return; }
if (zoom > 0)
  {
  offx = xpav-XSize()/2/zoom;
  offy = ypav-YSize()/2/zoom;
  }
else
  {
  offx = xpav+XSize()/2*zoom;
  offy = ypav+YSize()/2*zoom;
  }

if (offx < 0)  offx = 0;
if (offx >= (img->XSize()-1))  offx = img->XSize()-2;
if (offy < 0)  offy = 0;
if (offy >= (img->YSize()-1))  offy = img->YSize()-2;

return;
}

/* --Methode-- */
void PIImage::CenterPave()
{
int xwsz, ywsz;

if (zoom > 0)
  { xwsz = XSize()/zoom;  
  ywsz = YSize()/zoom;  }
else
  { xwsz = -(XSize()*zoom); 
  ywsz = -(YSize()*zoom); }

if (img) {   
  if (xwsz > (img->XSize()-offx)) xwsz = (img->XSize()-offx);
  if (ywsz > (img->YSize()-offy)) ywsz = (img->YSize()-offy);
  }
xpav = offx+xwsz/2; 
ypav = offx+ywsz/2;
xszpav = ((xwsz+ywsz)/20) ;
if (xszpav < 1) xszpav = 1;
yszpav = xszpav; 

return;
}
