// Module PI : Peida Interactive   PIThermometer
// Thermometre                   R. Ansari  05/00
// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA

#include "sopnamsp.h"
#include "pitherm.h"

//++
// Class	PIThermometer
// Lib		PI
// include	pitherm.h
//
//   	Classe permettant la visualisation d'une valeur sous forme 
//   	d'une barre de progression ou d'un thermomètre, avec trois 
//	couleurs différentes, suivant deux valeurs de seuil.
//--
//++
// Links	Parents
// PIBaseWdg
//--

//++
// Titre	Constructeur
//--
//++
//  PIThermometer(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-- */
PIThermometer::PIThermometer(PIContainerGen *par, const char *nom,
                       int sx, int sy, int px, int py) 
: PIBaseWdg(par, nom, sx, sy, px, py)

{
  SetMinMax();
  val_ = 0.;
  SetThreshold();
  SetColors();
  lastperc_ = 0.;
}

/* --Methode-- */
PIThermometer::~PIThermometer()
{
}

//++
// Titre	Méthodes
//--
//++
// long  kind()
//	Retourne PIThermometer::ClassId .
//--

//++
// void  SetMinMax(double min=0., double max=1.)
//	Définit les valeurs minimum et maximum du thermomètre.
// void  GetMinMax(double& min, double& max)
//	Retourne les valeurs minimum et maximum du thermomètre.
// void  SetValue(double val)
//	Définit la valeur actuelle du thermomètre.
// void  GetValue()
//	Retourne la valeur actuelle du thermomètre.
//--

/* --Methode-- */
void
PIThermometer::SetMinMax(double min, double max)
{
  if (max <= min) return;
  min_ = min;  max_ = max;   
}

/* --Methode-- */
void 
PIThermometer::GetMinMax(double& min, double& max)
{
  min = min_;  max = max_; 
}

/* --Methode-- */
void
PIThermometer::SetValue(double val)
//	Définit la valeur actuelle du thermomètre.
{
  val_ = val;   
  Refresh();
}

/* --Methode-- */
double
PIThermometer::GetValue()
{
return val_;
}

//++
// void  SetThreshold(double t1=0.75, double t2=0.9)
//	Définit les deux seuils pour les changements de couleurs.
// void  GetThreshold(double& t1, double& t2)
//	Retourne les deux seuils pour les changements de couleurs.
// void  SetColors(PIColors c1=PI_Green, PIColors c2=PI_Yellow, PIColors c3=PI_Red)
//	Définit les trois couleurs utilisées pour l'affichage.
//|	Val : .... < Seuil1 <  ....  < Seuil2 <  ....
//|	       c1               c2                c3
//|     
//--

/* --Methode-- */
void
PIThermometer::SetThreshold(double t1, double t2)
{
  thr1_ = t1;   thr2_ = t2;  
}

/* --Methode-- */
void
PIThermometer::GetThreshold(double& t1, double& t2)
{
  t1 = thr1_;   t2 = thr2_;  
}


/* --Methode-- */
void
PIThermometer::SetColors(PIColors c1, PIColors c2, PIColors c3)
{
  lowc_ = c1;  medc_ = c2;  highc_ = c3;
}
 
/* --Methode-- */
//++
// void  Draw(PIGraphicGen* g, int x0, int y0, int dx, int dy)
//	Méthode effectuant l'affichage.
//--
void PIThermometer::Draw(PIGraphicGen* g, int /*x0*/, int /*y0*/, int /*dx*/, int /*dy*/)
{
  if (!IsVisible())  return;
  double delta = (max_-min_);
  if (delta < 1.e-39) delta = 1.e-39;

  double perc = (val_-min_)/delta;
  int sx = XSize(); 
  int sy = YSize(); 
  if (perc < lastperc_)  
    EraseWindow(0, 0, XSize(), YSize());
  
  g->SelForeground(PI_Black);
  g->DrawBox(0, 0, sx, sy);
  
  lastperc_ = perc;
  char buff[32];
  sprintf(buff, "%d%%", (int)(perc*100.));

  if (perc < 0.) perc = 0.;
  if (perc > 1.) perc = 1.;
  // Representation verticale si SizeY > SizeX 
  // ou horizontale  si SizeX > SizeY
  if (perc < thr1_)  g->SelForeground(lowc_);
  else if (perc < thr2_)  g->SelForeground(medc_);
  else g->SelForeground(highc_);

  int w,h,fa,fd;
  g->SelFont(PI_NormalSizeFont, PI_BoldFont);
  w = g->GetFont().GetStringWidth(buff);
  h = g->GetFont().GetFontHeight(fa, fd);

  g->SelLine(PI_ThinLine);
  if (sx > sy) {    // horizontal
    int dx = (double)(sx-2)*perc; 
    g->DrawFBox(1, 1, dx, sy-2);
    int dcx = (sy-2)*0.66;
    int cx = 1+dcx;   
    g->SelForeground(PI_Grey);
    while (cx <= dx) {
      g->DrawLine(cx, 1, cx, sy-2);
      cx += dcx;
    }
    g->SelForeground(PI_Black);
    cx = ((dx-w-2)>=1) ? (dx-w-2) : 1;  
    g->DrawString(cx, sy/2-1+h/2, buff);
  }
  else  {    // vertical
    int dy = (double)(sy-2)*perc;
    g->DrawFBox(1, (sy-dy-1), sx-2, dy);
    int dcy = (sx-2)*0.66;
    int cy = sy-1-dcy;
    g->SelForeground(PI_Grey);
    while (cy > (sy-dy-1)) {
      g->DrawLine(1, cy, sx-2, cy);
      cy -= dcy;
    }
    g->SelForeground(PI_Black);
    cy = ((dy+1+h) < sy-1) ? (dy+1+h) : sy-2;
    g->DrawString((sx-w)/2, cy, buff);    
  }
  
  return;
}






