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

#include <stdlib.h>

#include "pidrwtools.h"
#include "piscdrawwdg.h"
#include "pi3ddrw.h"


PIDrwTools* PIDrwTools::cwdrwt = NULL;
PIBaseWdgGen* PIDrwTools::mCurBW = NULL;

/* --Methode-- */
void PIDrwTools::ShowPIDrwTools() 
{
if (cwdrwt == NULL)  cwdrwt = new PIDrwTools(PIApplicationGetApp());
cwdrwt->Show();
}

/* --Methode-- */
void PIDrwTools::SetCurrentBaseWdg(PIBaseWdgGen* cbw)
{
if (mCurBW == cbw) return;
mCurBW = cbw;
if (cwdrwt)  { 
  if (mCurBW != NULL)  { 
    cwdrwt->mNDr = mCurBW->NbDrawers()-1;
    if (cwdrwt->mNDr < 0)  cwdrwt->mNDr = 0;
    }
  else cwdrwt->mNDr = 0;
  char buff[32];
  sprintf(buff,"%d", cwdrwt->mNDr);
  cwdrwt->mNlb->SetLabel(buff);  
  }
}
/* --Methode-- */
PIBaseWdgGen* PIDrwTools::GetCurrentBaseWdg()
{
return(mCurBW);
}

/* --Methode-- */
PIDrwTools::PIDrwTools(PIApplication* par)
: PIWindow((PIMsgHandler*)par, "PIDrawerTools", PIWK_dialog, 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->PrefCompSz(bsx, bsy);
spx = bsx/10;
spy = bsy/4;

int wszx = 5*spx+3.5*bsx; 
int wszy = (7+3*0.85)*(spy+bsy);
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", 2000, bsx, bsy, cpx, cpy);
cpx += spx+bsx; 
mCkb[2] = new PICheckBox(this,"Grid", 2000, 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;;
mBut[0] = new PIButton(this, "SetAxes", 2600, bsx*1.5, bsy, cpx, cpy);
cpx += bsx*1.5+3*spx;
mBut[1] = new PIButton(this, "AutoLimits", 2700, 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);

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]->AppendItem("Grey", 103);
mOpt[0]->AppendItem("Red", 104);
mOpt[0]->AppendItem("Blue", 105);
mOpt[0]->AppendItem("Green", 106);
mOpt[0]->AppendItem("Yellow", 107);
mOpt[0]->AppendItem("Magenta", 108);
mOpt[0]->AppendItem("Cyan", 109);
mOpt[0]->AppendItem("Turquoise", 110);
mOpt[0]->AppendItem("NavyBlue", 111);
mOpt[0]->AppendItem("Orange", 112);
mOpt[0]->AppendItem("SiennaRed", 113);
mOpt[0]->AppendItem("Purple", 114);
mOpt[0]->AppendItem("LimeGreen", 115);
mOpt[0]->AppendItem("Gold", 116);
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);
mOpt[1]->AppendItem("Grey32", 201);
mOpt[1]->AppendItem("GreyInv32", 202);
mOpt[1]->AppendItem("ColRJ32", 203);
mOpt[1]->AppendItem("ColBR32", 204);
mOpt[1]->AppendItem("ColRV32", 205);
mOpt[1]->AppendItem("Grey128", 206);
mOpt[1]->AppendItem("GreyInv128", 207);
mOpt[1]->AppendItem("ColRJ128", 208);
mOpt[1]->AppendItem("ColBR128", 209);
mOpt[1]->AppendItem("Col16", 210);
mOpt[1]->SetValue(200);
mOpt[1]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);


cpx = 2*spx;
cpy += spy+bsy;
mOpt[2] = new PIOptMenu(this, "bwt-opt-2", bsx*1.75, bsy, cpx, cpy);
mOpt[2]->AppendItem("Def.Mrk", 300);
mOpt[2]->AppendItem("Mrk Dot(.)", 301);
mOpt[2]->AppendItem("Mrk Plus(+)", 302);
mOpt[2]->AppendItem("Mrk Cross(x)", 303);
mOpt[2]->AppendItem("Mrk Circle", 304);
mOpt[2]->AppendItem("Mrk FCircle", 305);
mOpt[2]->AppendItem("Mrk Box", 306);
mOpt[2]->AppendItem("Mrk FBox", 307);
mOpt[2]->AppendItem("Mrk Triangle", 308);
mOpt[2]->AppendItem("Mrk FTriangle", 309);
mOpt[2]->AppendItem("Mrk Star", 310);
mOpt[2]->AppendItem("Mrk FStar", 311);
mOpt[2]->SetValue(300);
mOpt[2]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);

cpx += spx+1.75*bsx; 
mOpt[3] = new PIOptMenu(this, "bwt-opt-3", bsx*1.75, bsy, cpx, cpy);
mOpt[3]->AppendItem("Mrk 1 pt", 401);
mOpt[3]->AppendItem("Mrk 3 pt", 403);
mOpt[3]->AppendItem("Mrk 5 pt", 405);
mOpt[3]->AppendItem("Mrk 7 pt", 407);
mOpt[3]->AppendItem("Mrk 9 pt", 409);
mOpt[3]->AppendItem("Mrk 11 pt", 411);
mOpt[3]->AppendItem("Mrk 13 pt", 413);
mOpt[3]->AppendItem("Mrk 15 pt", 415);
mOpt[3]->SetValue(405);
mOpt[3]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);

cpx = 2*spx;
cpy += spy+bsy;
mOpt[4] = new PIOptMenu(this, "bwt-opt-4", bsx*1.75, bsy, cpx, cpy);
mOpt[4]->AppendItem("Def.Font", 500);
mOpt[4]->AppendItem("Normal-Font", 511);
mOpt[4]->AppendItem("Bold", 512);
mOpt[4]->AppendItem("Ital", 513);
mOpt[4]->AppendItem("Small-Font", 521);
mOpt[4]->AppendItem("Small-Bold", 522);
mOpt[4]->AppendItem("Small-Ital", 523);
mOpt[4]->AppendItem("Big-Font", 531);
mOpt[4]->AppendItem("Big-Bold", 532);
mOpt[4]->AppendItem("Big-Ital", 533);
mOpt[4]->AppendItem("Huge-Font", 541);
mOpt[4]->AppendItem("Huge-Bold", 542);
mOpt[4]->AppendItem("Huge-Ital", 543);
mOpt[4]->SetValue(500);
mOpt[4]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);

cpx += spx+1.75*bsx; 
mOpt[5] = new PIOptMenu(this, "bwt-opt-5", bsx*1.75, bsy, cpx, cpy);
mOpt[5]->AppendItem("Def.Line", 600);
mOpt[5]->AppendItem("Thin-Line", 601);
mOpt[5]->AppendItem("Normal-Line", 602);
mOpt[5]->AppendItem("Thick-Line", 603);
mOpt[5]->AppendItem("ThinDashed", 604);
mOpt[5]->AppendItem("Dashed-Line", 605);
mOpt[5]->AppendItem("ThickDashed", 606);
mOpt[5]->AppendItem("ThinDotted", 607);
mOpt[5]->AppendItem("Dotted-Line", 608);
mOpt[5]->AppendItem("ThickDotted", 609);
mOpt[5]->SetValue(600);
mOpt[5]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);

cpx = 2*spx;
cpy += spy+bsyo;
bsy = bsyo; spy = spyo;
mButdr[0] = new PIButton(this, "-", 3501, bsy, bsy, cpx, cpy);
cpx += bsy+0.25*spy;
mNlb = new PILabel(this,"NumDr", bsy, bsy, cpx, cpy);
mNlb->SetLabel("0");
mNDr = 0;
cpx += bsy+0.25*spy;
mButdr[1] = new PIButton(this, "+", 3502, bsy, bsy, cpx, cpy);
mButdr[0]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
mButdr[1]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
mNlb->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);

cpx = wszx-1.7*bsx-3*spx;
mButcf[0] = new PIButton(this, "GetAtt", 2800, 0.85*bsx, bsy, cpx, cpy);
cpx += 0.85*bsx+spx;
mButcf[1] = new PIButton(this, "SetAtt", 2900, 0.85*bsx, bsy, cpx, cpy);
mButcf[0]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
mButcf[1]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);

cpx = spx+0.25*bsx;;
cpy += spy+bsy;
mButcf[2] = new PIButton(this, "Refresh", 3000, bsx*1.5, bsy, cpx, cpy);
mButcf[2]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
cpx += bsx*1.5+3*spx;
mButcf[3] = new PIButton(this, "Dismiss", 3777, bsx*1.5, bsy, cpx, cpy);
mButcf[2]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
mButcf[3]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);

cwdrwt = this;

}

/* --Methode-- */
PIDrwTools::~PIDrwTools()
{
if (cwdrwt == this)  cwdrwt = NULL;
int i;
for(i=0; i<2; i++)
  {
  delete mLab[i];
  delete mBut[i];
  delete mText[i];
  delete mButcf[i];
  }

for(i=0; i<3; i++) { delete mCkb[i];   delete mButcf[i]; }
delete mBut[2];
for(i=0; i<6; i++)  delete mOpt[i];
delete mNlb;
}

//  Declaration des differents attributs graphiques 
static PIColors cols[17] = { PI_NotDefColor, 
                     PI_Black, PI_White, PI_Grey, 
                     PI_Red, PI_Blue, PI_Green, 
                     PI_Yellow, PI_Magenta, 
                     PI_Cyan , PI_Turquoise, PI_NavyBlue, 
                     PI_Orange, PI_SiennaRed, PI_Purple, 
                     PI_LimeGreen, PI_Gold };

static PIMarker mrk[12] = { PI_NotDefMarker, PI_DotMarker, 
                            PI_PlusMarker, PI_CrossMarker,
                            PI_CircleMarker, PI_FCircleMarker,
                            PI_BoxMarker, PI_FBoxMarker,
                            PI_TriangleMarker, PI_FTriangleMarker,
                            PI_StarMarker, PI_FStarMarker };
static PILineAtt line[10] = { PI_NotDefLineAtt, PI_ThinLine, PI_NormalLine, PI_ThickLine, 
                              PI_ThinDashedLine, PI_DashedLine, PI_ThickDashedLine, 
                              PI_ThinDottedLine, PI_DottedLine, PI_ThickDottedLine };

static PIFontAtt fntatt[4] = { PI_NotDefFontAtt, PI_RomanFont, PI_BoldFont, PI_ItalicFont };
static PIFontSize fntsz[5] = { PI_NotDefFontSize, PI_NormalSizeFont, PI_SmallSizeFont, 
                               PI_BigSizeFont, PI_HugeSizeFont };
static CMapId cmap[11] = {  CMAP_OTHER, CMAP_GREY32, CMAP_GREYINV32,
                            CMAP_COLRJ32, CMAP_COLBR32, CMAP_COLRV32,  
                            CMAP_GREY128, CMAP_GREYINV128, CMAP_COLRJ128, CMAP_COLBR128, CMAP_COL16 };

/* --Methode-- */
void PIDrwTools::Show()
{
PIWindow::Show();
char buff[92]; 
mNDr = 0;

if (mCurBW != NULL)  { 
  mNDr = mCurBW->NbDrawers()-1;
  if (mNDr < 0)  mNDr = 0;
  }

UpdateAttFromDrawer();

mCkb[0]->SetState(false);
mCkb[1]->SetState(false);
mCkb[2]->SetState(false);

if ((mCurBW != NULL) && ( mCurBW->kind() == PIScDrawWdg::ClassId ) ) {
  PIScDrawWdg* scd = ( PIScDrawWdg*)mCurBW;
  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);
  }
else {
  mText[0]->SetText("-1.0  1.0");
  mText[1]->SetText("-1.0  1.0");
  }
sprintf(buff, "%d", mNDr);
mNlb->SetLabel(buff);



return;
}

/* --Methode-- */
void PIDrwTools::UpdateAttFromDrawer()
{

PIDrawer* dr = NULL;

mOpt[0]->SetValue(100);
mOpt[1]->SetValue(200);
mOpt[2]->SetValue(300);
mOpt[3]->SetValue(405);
mOpt[4]->SetValue(500);
mOpt[5]->SetValue(600);

if ( (mCurBW != NULL) && (mCurBW->NbDrawers() > 0) ) 
  dr = mCurBW->GetDrawer(mNDr);

if (!dr)  return;
int jj,kk;
PIColors fc = dr->GetFgColAtt();
for(kk=0; kk<17; kk++) 
  if (fc == cols[kk])  { mOpt[0]->SetValue(100+kk);  break; }    
CMapId cmi = dr->GetColMapId();
for(kk=0; kk<11; kk++)
  if (cmi == cmap[kk]) { mOpt[1]->SetValue(200+kk);  break; }  
PIMarker mk = dr->GetMarker();   
for(kk=0; kk<12; kk++) 
  if (mk == mrk[kk])   { mOpt[2]->SetValue(300+kk);  break; }
kk = dr->GetMarkerSz();
if (kk < 1)  kk = 1;
if (kk > 15) kk = 15;
if (kk%2 == 0) kk++;
mOpt[3]->SetValue(400+kk);
PIFontAtt fat = dr->GetFontAtt();
PIFontSize fsz = dr->GetFontSz();
for(kk=0; kk<4; kk++)
  if (fat ==  fntatt[kk]) break;
for(jj=0; jj<5; jj++) 
  if (fsz == fntsz[jj])  break;

if (kk >= 4) kk = 3;
if (jj >= 5) jj = 4;
mOpt[4]->SetValue(500+jj*10+kk);
PILineAtt lat = dr->GetLineAtt();
for(kk=0; kk<10; kk++)
  if (lat == line[kk])   { mOpt[5]->SetValue(600+kk);  break; }

return;
}

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

msg = UserMsg(msg);
if (msg == 3777)  { Hide(); return; }

if (mCurBW == NULL)   return;

char strg[64];
double xmin, xmax, ymin, ymax;
int axrl = kAxeDirLtoR;
int ayud = kAxeDirDownUp;
int k, kk, kkk;

switch (msg) {

  case 2600 :
    sscanf(mText[0]->GetText().c_str(), "%lg %lg" , &xmin, &xmax);
    sscanf(mText[1]->GetText().c_str(), "%lg %lg" , &ymin, &ymax);
    if (mCkb[0]->GetState())  axrl = kAxeDirRtoL ;
    if (mCkb[1]->GetState())  ayud = kAxeDirUpDown;
    if ( mCurBW->kind() == PIScDrawWdg::ClassId ) { 
      ((PIScDrawWdg*)mCurBW)->SetLimits(xmin, xmax, ymin, ymax, axrl, ayud);
      unsigned int flags = ((PIScDrawWdg*)mCurBW)->GetAxesFlags();
      if (mCkb[2]->GetState()) ((PIScDrawWdg*)mCurBW)->SetAxesFlags(flags | kGridOn);
      else  ((PIScDrawWdg*)mCurBW)->SetAxesFlags(flags & ~kGridOn);
      }
    else mCurBW->SetDefaultDrawerLimits(xmin, xmax, ymin, ymax, axrl, ayud);
    mCurBW->Refresh();
    break;

  case 2700 :
    if ( mCurBW->kind() == PIScDrawWdg::ClassId ) ((PIScDrawWdg*)mCurBW)->UpdateLimits();
    else if ( mCurBW->kind() == PIDraw3DWdg::ClassId) ((PIDraw3DWdg*)mCurBW)->Update3DView();
    break;

  case 2800 :
    UpdateAttFromDrawer();
    break;

  case 2900 :
  case 3000 :
    {
    PIDrawer* drw = mCurBW->GetDrawer(mNDr);
    if (drw == NULL)  return;
    k = mOpt[0]->GetValue()-100;
    if ( (k < 0) || (k > 16) )  k = 0;
    drw->SetColAtt(cols[k]);
    k = mOpt[1]->GetValue()-200;
    if ( (k < 0) || (k > 10) )  k = 0;
    drw->SetColMapId(cmap[k]);
    k =  mOpt[2]->GetValue()-300;
    if ( (k < 0) || (k > 11) )  k = 0;
    kk =  mOpt[3]->GetValue()-400;
    if ( (kk < 1) || (kk > 27) )  kk = 1;
    drw->SetMarkerAtt(kk, mrk[k]);
    k =  (mOpt[4]->GetValue()-500);
    kk = k/10;   kkk = k%10;
    drw->SetFontAtt(fntsz[kk], fntatt[kkk]);
    k =  mOpt[5]->GetValue()-600;
    if ( (k < 0) || (k > 9) )  k = 0;
    drw->SetLineAtt(line[k]);
    if (msg == 2900) drw->Refresh();
    else mCurBW->Refresh();
    }
    break;        

  case 3501 :
  case 3502 :
    if (msg == 3501) {  mNDr--;   if (mNDr < 0)  mNDr = 0; }
    else { mNDr++;  if (mNDr >= mCurBW->NbDrawers())  mNDr--; }
    sprintf(strg, "%d", mNDr);
    mNlb->SetLabel(strg);
    /*   On ne change pas les options choisies   Reza+cmv 2/10/98  
    mOpt[0]->SetValue(100);
    mOpt[1]->SetValue(200);
    mOpt[2]->SetValue(300);
    mOpt[3]->SetValue(405);
    mOpt[4]->SetValue(500);
    mOpt[5]->SetValue(600);
    */
    break;

  default :
    break;
  }

return;
}

