// This may look like C code, but it is really -*- C++ -*-
// Outils de manipulation des axes des PIScDrawWdg
//                                   R. Ansari 07/2001
// LAL (Orsay) / IN2P3-CNRS  DAPNIA/SPP (Saclay) / CEA

#include <stdlib.h>
#include <iostream.h>

#include "piaxestools.h"

//++
// Class	PIAxesTools
// Lib		PI
// include	piaxestools.h
//
//	Classe de fenêtre de dialogue permettant de modifier interactivement
//	Permet aussi de modifier les attributs d'axes pour les "PIScDrawWdg"
//--
// Links	Parents
// PIWindow
//--
//++
// Links	Voir aussi
// PIScDrawWdg
//--

//++
// Titre	Méthodes statiques
//--
//++
// void  ShowPIAxesTools() 	
//	Méthode statique permettant l'affichage de la fenêtre de contrôle des
//	attributs graphiques des "Drawer". L'instance de la classe
//	 "PIAxesTools" est créée si nécessaire.
// void  HidePIAxesTools() 
//	Désacative (cache) la fenêtre "PIAxesTools" (méthode statique).
// void  SetCurrentBaseWdg(PIBaseWdgGen* cbw)
//	Méthode statique permettant de sélectionner le "PIBaseWdg" courant.
// PIBaseWdgGen*  GetCurrentBaseWdg()
//	Retourne le "PIBaseWdg" courant (méthode statique).
//--


PIAxesTools* PIAxesTools::cwaxet = NULL;
PIScDrawWdg* PIAxesTools::curscdwdg = NULL;

/* --Methode-- */
void PIAxesTools::ShowPIAxesTools() 
{
if (cwaxet == NULL)  cwaxet = new PIAxesTools(PIApplicationGetApp());
cwaxet->Show();
}

/* --Methode-- */
void PIAxesTools::HidePIAxesTools() 
{
if (cwaxet == NULL)  return; 
cwaxet->Hide();
}

/* --Methode-- */
void PIAxesTools::SetCurrentScDrawWdg(PIScDrawWdg* csw)
{
if (curscdwdg == csw) return;
curscdwdg = csw;
}

/* --Methode-- */
PIScDrawWdg* PIAxesTools::GetCurrentScDrawWdg()
{
return(curscdwdg);
}

/* --Methode-- */
PIAxesTools::PIAxesTools(PIApplication* par)
: PIWindow((PIMsgHandler*)par, "PIAxesTools", PIWK_normal, 240, 240, 150, 150)
{
int bsx, bsy, spx, spy;

// On definit la taille a partir de la taille par defaut des composantes 
// PIApplicationPrefCompSize(bsx, bsy);
par->PrefCompSize(bsx, bsy);
spx = bsx/10;
spy = bsy/4;

int wszx = 5*spx+3.5*bsx; 
int wszy = 6*bsy+8*spy;
SetSize(wszx, wszy);

int cpx = spx*2;
int cpy = spy*2;
int csx = cpx;
int csy = cpy;
mLab[0] = new PILabel(this, "X Min Max", 1.25*bsx, bsy, cpx, cpy);
cpy += spy+bsy; 
mLab[1] = new PILabel(this, "Y Min Max", 1.25*bsx, bsy, cpx, cpy);
mLab[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
mLab[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);

cpy = spy*2;
cpx += spx+1.25*bsx; 
mText[0] = new PIText(this, "x_min_max", 2.25*bsx, bsy, cpx, cpy);
mText[0]->SetText("-1.0  1.0");
cpy += spy+bsy; 
mText[1] = new PIText(this, "y_min_max", 2.25*bsx, bsy, cpx, cpy);
mText[1]->SetText("-1.0  1.0");
mText[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
mText[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);

cpx = spx+0.25*bsx;
cpy += spy+bsy; 
mCkb[0] = new PICheckBox(this,"X-RtoL", 2000, bsx, bsy, cpx, cpy);
cpx += spx+bsx; 
mCkb[1] = new PICheckBox(this,"Y-UpDn", 2001, bsx, bsy, cpx, cpy);
cpx += spx+bsx; 
mCkb[2] = new PICheckBox(this,"Grid", 2002, bsx, bsy, cpx, cpy);
mCkb[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
mCkb[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
mCkb[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
cpy += spy+bsy; 
cpx = spx+0.25*bsx;
mCkb[3] = new PICheckBox(this,"LogScale-X", 2003, bsx*1.5, bsy, cpx, cpy);
cpx += bsx*1.5+3*spx;
mCkb[4] = new PICheckBox(this,"LogScale-Y", 2004, bsx*1.5, bsy, cpx, cpy);
mCkb[3]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
mCkb[4]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);

cpy += spy+bsy; 
cpx = spx+0.25*bsx;
mBut[0] = new PIButton(this, "GetAxesInfo", 2100, bsx*1.5, bsy, cpx, cpy);
cpx += bsx*1.5+3*spx;
mBut[1] = new PIButton(this, "AutoLimits", 2200, bsx*1.5, bsy, cpx, cpy);
mBut[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
mBut[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);

cpy += spy+bsy; 
cpx = spx+0.25*bsx;
mBut[2] = new PIButton(this, "SetAxes", 2500, bsx*1.5, bsy, cpx, cpy);
cpx += bsx*1.5+3*spx;
mBut[3] = new PIButton(this, "Dismiss", 2777, bsx*1.5, bsy, cpx, cpy);
mBut[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
mBut[3]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);

/*
int offy = cpy+bsy+spy*2;

//  Option-Menu  Marker, Line, couleur, etc...
cpx = 2*spx;
cpy += 3*spy+bsy;

int bsyo = bsy;  
int spyo = spy; 
bsy = 0.85*bsy;   spy = 0.85*spy;

mOpt[0] = new PIOptMenu(this, "bwt-opt-0", bsx*1.75, bsy, cpx, cpy);
mOpt[0]->AppendItem("Def.Col", 100);
mOpt[0]->AppendItem("Black", 101);
mOpt[0]->AppendItem("White", 102);
mOpt[0]->SetValue(100);
mOpt[0]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);

cpx += spx+1.75*bsx; 
mOpt[1] = new PIOptMenu(this, "bwt-opt-1", bsx*1.75, bsy, cpx, cpy);
mOpt[1]->AppendItem("No.CMap", 200);
*/


cwaxet = this;
}

/* --Methode-- */
PIAxesTools::~PIAxesTools()
{
if (cwaxet == this)  cwaxet = NULL;
int i;
for(i=0; i<2; i++)  {
  delete mLab[i];
  delete mBut[i];
  delete mText[i];
}
for(i=0; i<4; i++)  delete mBut[i];
for(i=0; i<5; i++)  delete mCkb[i];

}


/* --Methode-- */
void PIAxesTools::Show()
{
PIWindow::Show();
UpdateAxesInfoFromScWdg();
return;
}

/* --Methode-- */
void PIAxesTools::UpdateAxesInfoFromScWdg()
{
char buff[128];
if (curscdwdg != NULL) {
  PIScDrawWdg* scd = curscdwdg;
  sprintf(buff, "%g  %g", scd->XMin(), scd->XMax());
  mText[0]->SetText(buff);
  sprintf(buff, "%g  %g", scd->YMin(), scd->YMax());
  mText[1]->SetText(buff);
  int xa, ya;
  scd->GetAxesConfig(xa, ya);
  if (xa & kAxeDirRtoL) mCkb[0]->SetState(true);
  if (ya & kAxeDirUpDown)  mCkb[1]->SetState(true);
  if (scd->GetAxesFlags() & kGridOn) mCkb[2]->SetState(true);
  mCkb[3]->SetState(scd->isLogScaleX());
  mCkb[4]->SetState(scd->isLogScaleY());
  }
else {
  mText[0]->SetText("-1.0  1.0");
  mText[1]->SetText("-1.0  1.0");
  mCkb[0]->SetState(false);
  mCkb[1]->SetState(false);
  mCkb[2]->SetState(false);
  mCkb[3]->SetState(false);
  mCkb[4]->SetState(false);
  }

return;
}

void PIAxesTools::SetAxes(bool refr)
{
  double xmin, xmax, ymin, ymax;
  int axrl = kAxeDirLtoR;
  int ayud = kAxeDirDownUp;
  PIScDrawWdg* scd = curscdwdg;
  if ( scd == NULL )  return;
  if (mText[0]->GetText().length() > 1) {
    xmin = -1.;   xmax = 1.;
    sscanf(mText[0]->GetText().c_str(), "%lg %lg" , &xmin, &xmax);
  }
  else {
    xmin = scd->XMin();
    xmax = scd->XMax();
  }
  if (mText[1]->GetText().length() > 1) {
    ymin = -1.;   ymax = 1.;
    sscanf(mText[1]->GetText().c_str(), "%lg %lg" , &ymin, &ymax);
  }
  else {
    ymin = scd->YMin();
    ymax = scd->YMax();
  }      
  if (mCkb[0]->GetState())  axrl = kAxeDirRtoL ;
  if (mCkb[1]->GetState())  ayud = kAxeDirUpDown;
  scd->SetLimits(xmin, xmax, ymin, ymax, axrl, ayud);
  unsigned int flags = scd->GetAxesFlags();
  if (mCkb[2]->GetState()) scd->SetAxesFlags(flags | kGridOn);
  else  scd->SetAxesFlags(flags & ~kGridOn);
  scd->SetLogScale(mCkb[3]->GetState(), mCkb[4]->GetState() );

  if (refr) scd->Refresh();
  return;
}

/* --Methode-- */
void PIAxesTools::Process(PIMessage msg, PIMsgHandler* /*sender*/, void* /*data*/)
{

msg = UserMsg(msg);


switch (msg) {
  case 2100 :
    UpdateAxesInfoFromScWdg();
    break;

  case 2200 :
    if ( curscdwdg != NULL ) { 
      curscdwdg->UpdateLimits();
      UpdateAxesInfoFromScWdg();
    }
    /*
      PIDraw3DWdg* dr3 = dynamic_cast<PIDraw3DWdg *>(curscdwdg);
      if (dr3 != NULL) dr3->Update3DView();
    */
    break;

  case 2500 :
    SetAxes(true);
    break;

  case 2777 :
    Hide();
    break;

  default :
    break;
  }

return;
}





