// Module PI : Peida Interactive     PICMapView
// Visualisation de table de couleur     R. Ansari  07/98
// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA

#include "sopnamsp.h"
#include "picmapview.h"
#include <math.h>

//++
// Class	PICMapView
// Lib		PI
// include	picmapview.h
//
//   	Classe permettant la visualisation d'une table de couleur.
//--
//++
// Links	Parents
// PIBaseWdg
//--
//++
// Links	Voir aussi
// PIColorMap
//--

//++
// Titre	Constructeur
//--
//++
//  PICMapView(PIContainerGen *par, const char *nom, int sx=256, int sy=10, int px=0, int py=0);
//	Constructeur - Le choix d'affichage (vertical ou horizontal) dépend
//	du rapport des tailles "sx", "sy"
//--


/* --Methode-- */
PICMapView::PICMapView(PIContainerGen *par, const char *nom,
                       int sx, int sy, int px, int py) 
: PIBaseWdg(par, nom, sx, sy, px, py)

{
  cmap = NULL;
  vmin = 1.;   vmax = -1.; 
}


/* --Methode-- */
PICMapView::~PICMapView()
{
  if (cmap) delete cmap;
}



//++
// Titre	Méthodes
//--
//++
// long  kind()
//	Retourne PICMapView::ClassId .
// void   SetColMap(PIColorMap* cmp=NULL, double min=1., double max=-1., bool refr=true)
//	Choix de la table de couleur et valeurs min et max. Si "refr==true",
//	la méthode "Refresh()" est appelée.
// void  SetColMapId(CMapId cmapid, double min=1., double max=-1., bool refr=true)
//	Choix de la table de couleur en utilisant le "CMapId" et 
//	définition des valeurs min et max. Si "refr==true",
//	la méthode "Refresh()" est appelée.
//--
 
/* --Methode-- */
void PICMapView::SetColMap(PIColorMap* cmp, double min, double max, bool refr)
{
  if (cmp == NULL)   { 
    if (cmap) delete cmap;
    cmap = NULL;
    vmin = 1.;  vmax = -1.;
    if (refr)  Refresh();  
    return;
    }
  if ( cmap && (cmp->Type() == cmap->Type()) && (cmp->Type() != CMAP_OTHER)
       && (cmp->IsColorIndexReversed() == cmap->IsColorIndexReversed())
       && (fabs(vmin-min) < 1.e-69)  && (fabs(vmax-max) > -1.e-69) )  return;
  if (cmap) delete cmap;
  cmap = new PIColorMap(*cmp);
  vmin = min;  vmax = max;
  if (refr)  Refresh();  
  return;
}

/* --Methode-- */
void PICMapView::SetColMapId(CMapId cmapid, bool revidx, double min, double max, bool refr)
{
  if ( cmap && (cmapid == cmap->Type()) && (cmapid != CMAP_OTHER) &&
       (cmap->IsColorIndexReversed() == revidx) &&
       ((vmin-min) < 1.e-69) &&  ((vmin-min) > -1.e-69) &&
       ((vmax-max) < 1.e-69) &&  ((vmax-max) > -1.e-69) )  return;
  if (cmap) delete cmap;
  cmap = new PIColorMap(cmapid);
  cmap->ReverseColorIndex(revidx);
  vmin = min;  vmax = max;
  if (refr)  Refresh();  
  return;
}


/* --Methode-- */
void PICMapView::Draw(PIGraphicGen* g, int /*x0*/, int /*y0*/, int /*dx*/, int /*dy*/)
{
  if (!cmap) { 
    EraseWindow(0, 0, XSize(), YSize());
    return;
    }
  // On presente la table de couleur verticalement si SizeY > SizeX 
  // ou horizontale  si SizeX > SizeY

  int sx = XSize(); 
  int sy = YSize(); 

  int k;
  if (sx > sy) {    // horizontal
    int xc, dx;
    xc = 0;
    for(k=0; k<cmap->NCol(); k++) {
      dx = (sx-xc)/(cmap->NCol()-k);
      g->SelForeground((*cmap), k);
      g->DrawFBox(xc, 0, dx+1, sy);
      xc += dx;
    }
  }
  else  {    // vertical
    int yc, dy;
    yc = sy;
    for(k=0; k<cmap->NCol(); k++) {
      dy = yc/(cmap->NCol()-k);
      yc -= dy;
      g->SelForeground((*cmap), k);
      g->DrawFBox(0, yc, sx, dy+1);
    }
  }
  if (vmin > vmax)   return;

  if ( (cmap->Type() == CMAP_GREY32) || (cmap->Type() == CMAP_GREYINV32) ||
       (cmap->Type() == CMAP_GREY128) || (cmap->Type() == CMAP_GREYINV128) || 
       (cmap->Type() == CMAP_GREEN32) )  g->SelForeground(PI_Red);
  else g->SelForeground(PI_Green);

  if (sx > sy) {    // horizontal
    int fsz = (sy < 20) ? sy-6 : 14;
    g->SelFontSzPt(fsz, PI_BoldFont);
    char buff[32];
    double av;
    av = fabs(vmin);
    if ( (av < 1.e6) && (av > 1.e-3) )  sprintf(buff, "%.2f", vmin);
    else sprintf(buff, "%8.4g", vmin);
    g->DrawString(4, sy-4, buff);
    av = fabs(vmax);
    if ( (av < 1.e6) && (av > 1.e-3) )  sprintf(buff, "%.2f", vmax);
    else sprintf(buff, "%8.4g", vmax);
    g->DrawString(sx-4-(int)g->CalcStringWidth(buff), sy-4, buff);
    } 
  else {   // vertical 
    int fsz = (sx < 64) ? sx/4 : 14;
    g->SelFontSzPt(fsz, PI_BoldFont);
    char buff[32];
    double av;
    av = fabs(vmin);
    if ( (av < 1.e6) && (av > 1.e-3) )  sprintf(buff, "%.2f", vmin);
    else sprintf(buff, "%8.4g", vmin);
    g->DrawString(4, sy-4, buff);
    av = fabs(vmax);
    if ( (av < 1.e6) && (av > 1.e-3) )  sprintf(buff, "%.2f", vmax);
    else sprintf(buff, "%8.4g", vmax);
    int fa, fd;
    g->DrawString(4, g->GetFont().GetFontHeight(fa,fd)+4, buff);
    } 
    
  return;
}






