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

#include <stdlib.h>

#include "piimgtools.h"
#include "piimage.h"

// ------ Menu des options et fenetre de dialogue pour changement de LUT --------

PIImgTools* PIImgTools::curlutw = NULL;
/* --Methode-- */
void PIImgTools::ShowPIImgTools() 
{
if (curlutw == NULL)  curlutw = new PIImgTools(PIApplicationGetApp());
curlutw->Show();
}

/* --Methode-- */
PIImgTools::PIImgTools(PIApplication* par)
: PIWindow((PIMsgHandler*)par, "PIImageTools", 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 = 8*spx+3*bsx+2*bsy; 
int wszy = 9*spy+9*bsy;
SetSize(wszx, wszy);

int cpx = spx*2;
int cpy = spy*2;
int csx = cpx;
int csy = cpy;
mLab[0] = new PILabel(this, "MinPixel", bsx, bsy, cpx, cpy);
cpy += spy+bsy; 
mLab[1] = new PILabel(this, "MaxPixel", 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+bsx; 
mText[0] = new PIText(this, "MinVal", 1.75*bsx, bsy, cpx, cpy);
mText[0]->SetText("1");
cpy += spy+bsy; 
mText[1] = new PIText(this, "MaxVal", 1.75*bsx, bsy, cpx, cpy);
mText[1]->SetText("32000");
mText[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
mText[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
cpy += spy+bsy; 
cpx = spx*2;
mOlb[0] = new PILabel(this, "LutType", bsx, bsy, cpx, cpy);
mOlb[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
cpx += spx+bsx; 
mOpt[0] = new PIOptMenu(this, "imglut-opt-1", 1.75*bsx, bsy, cpx, cpy);
mOpt[0]->AppendItem("Linear", 1100);
mOpt[0]->AppendItem("Log.", 1101);
mOpt[0]->SetValue(1100);
mOpt[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);

cpy += spy+bsy; 
cpx = spx*2;
mOlb[1] = new PILabel(this, "AutoLut", bsx, bsy, cpx, cpy);
mOlb[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
cpx += spx+bsx; 
mOpt[1] = new PIOptMenu(this, "imglut-opt-2", 1.75*bsx, bsy, cpx, cpy);
mOpt[1]->AppendItem("+3 Sig", 1203);
mOpt[1]->AppendItem("+2 Sig", 1202);
mOpt[1]->AppendItem("+1 Sig", 1201);
mOpt[1]->AppendItem("NoAuto", 1200);
mOpt[1]->AppendItem("-1 Sig", 1199);
mOpt[1]->AppendItem("-2 Sig", 1198);
mOpt[1]->AppendItem("-3 Sig", 1197);
mOpt[1]->SetValue(1202);
mOpt[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);

cpy += 2*spy+bsy; 
cpx = bsx/2;
mBut[0] = new PIButton(this, "Apply", 2500, bsx*1.75, bsy, cpx, cpy);
cpx += bsx*2;
mBut[1] = new PIButton(this, "Dismiss", 2600,  bsx*1.75, 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;
// printf("-DBG- PIImgTools()  SzX,Y= %d %d , ButPos= %d %d (off=%d)\n", wszx, wszy, cpx, cpy, offy);

cpx = 4*spx+2.75*bsx;
cpy = 2*spy;
mSc[0] = new PIScale(this, "sc-offset-lut", 2700, kSDirDownUp, 1.25*bsy, 4.5*bsy, cpx, cpy); 
cpx += 1.50*bsy;
mSc[1] = new PIScale(this, "sc-dyn-lut", 2800, kSDirDownUp, 1.25*bsy, 4.5*bsy, cpx, cpy); 
mSc[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
mSc[0]->SetMinMax(-50, 50);
mSc[0]->SetValue(0);
mSc[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
mSc[1]->SetMinMax(-50, 50);
mSc[1]->SetValue(0);

//  Option-Menu  Couleur/Zoom
cpx = bsx/2;
cpy = offy;
mOptzc[0] = new PIOptMenu(this, "imglut-opt-3", bsx*1.75, bsy, cpx, cpy);
mOptzc[0]->AppendItem("Grey32", 201);
mOptzc[0]->AppendItem("GreyInv32", 202);
mOptzc[0]->AppendItem("ColRJ32", 203);
mOptzc[0]->AppendItem("ColBR32", 204);
mOptzc[0]->AppendItem("ColRV32", 205);
mOptzc[0]->AppendItem("Grey128", 206);
mOptzc[0]->AppendItem("GreyInv128", 207);
mOptzc[0]->AppendItem("ColRJ128", 208);
mOptzc[0]->AppendItem("ColBR128", 209);
mOptzc[0]->AppendItem("Col16", 210);
mOptzc[0]->SetValue(203);
mOptzc[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);

cpx += bsx*2;
mOptzc[1] = new PIOptMenu(this, "imglut-opt-4", bsx*1.75, bsy, cpx, cpy);
mOptzc[1]->AppendItem("Agr. x10", 110);
mOptzc[1]->AppendItem("Agr. x 8", 108);
mOptzc[1]->AppendItem("Agr. x 6", 106);
mOptzc[1]->AppendItem("Agr. x 5", 105);
mOptzc[1]->AppendItem("Agr. x 4", 104);
mOptzc[1]->AppendItem("Agr. x 3", 103);
mOptzc[1]->AppendItem("Agr. x 2", 102);
mOptzc[1]->AppendItem("Zoom x 1", 101);
mOptzc[1]->AppendItem("Red. / 2", 98);
mOptzc[1]->AppendItem("Red. / 3", 97);
mOptzc[1]->AppendItem("Red. / 4", 96);
mOptzc[1]->AppendItem("Red. / 5", 95);
mOptzc[1]->AppendItem("Red. / 6", 94);
mOptzc[1]->AppendItem("Red. / 8", 92);
mOptzc[1]->AppendItem("Red. /10", 90);
mOptzc[1]->SetValue(101);
mOptzc[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);

int pbsx = bsy;
int pbsy = bsy;
int pspx = spy/2;
int pspy = spy;

cpx = 2*pspx;
cpy += pbsy+2*spy;
mButsz[0] = new PIButton(this, "1x1", 3201,  pbsx, pbsy, cpx, cpy);
mButsz[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
cpx += pbsx+pspx;
mButsz[1] = new PIButton(this, "1x2", 3202,  pbsx, pbsy, cpx, cpy);
mButsz[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
cpx += pbsx+pspx;
mButsz[2] = new PIButton(this, "1x4", 3204,  pbsx, pbsy, cpx, cpy);
mButsz[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
cpx += pbsx+pspx;
mButsz[3] = new PIButton(this, "1/2", 3198,  pbsx, pbsy, cpx, cpy);
mButsz[3]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
cpx += pbsx+pspx;
mButsz[4] = new PIButton(this, "1/4", 3196,  pbsx, pbsy, cpx, cpy);
mButsz[4]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);

cpx += pbsx+10*pspx;
mButoa[0] = new PIButton(this, "+Info", 5311,  1.5*pbsx, pbsy, cpx, cpy);
mButoa[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
cpx += 1.5*pbsx+pspx;
mButoa[1] = new PIButton(this, "-Info", 5312,  1.5*pbsx, pbsy, cpx, cpy);
mButoa[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);


cpx = 2*pspx;
cpy += pbsy+pspy;
mButcax[0] = new PIButton(this, "-X", 5201,  pbsx, pbsy, cpx, cpy);
mButcax[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
cpx += pbsx+pspx;
mButcax[1] = new PIButton(this, "-Y", 5202,  pbsx, pbsy, cpx, cpy);
mButcax[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
cpx += pbsx+pspx;
mButcax[2] = new PIButton(this, "X-Y", 5203, pbsx, pbsy, cpx, cpy);
mButcax[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);

cpx += 1.5*pbsx+pspx+10*pspx;
mButoa[2] = new PIButton(this, "-All", 5300,  1.5*pbsx, pbsy, cpx, cpy);
mButoa[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
cpx += 1.5*pbsx+pspx;
mButoa[3] = new PIButton(this, "+Curs", 5321,  1.5*pbsx, pbsy, cpx, cpy);
mButoa[3]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
cpx += 1.5*pbsx+pspx;
mButoa[4] = new PIButton(this, "+Axe", 5331,  1.5*pbsx, pbsy, cpx, cpy);
mButoa[4]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);

curlutw = this;

}

/* --Methode-- */
PIImgTools::~PIImgTools()
{
if (curlutw == this)  curlutw = NULL;
int i;
for(i=0; i<2; i++)
  {
  delete mLab[i];
  delete mBut[i];
  delete mText[i];
  delete mOpt[i];
  delete mOlb[i];
  delete mSc[i];
  delete mOptzc[i];
  }
for(i=0; i<5; i++)  delete mButsz[i];
for(i=0; i<3; i++)  delete mButcax[i];
for(i=0; i<5; i++)  delete mButoa[i];

}

/* --Methode-- */
void PIImgTools::Show()
{
char buff[32];
PIImage *mpii;
PIWindow::Show();
mpii = PIImage::CurrentPIImage();
if (mpii == NULL)  return;
min_lut = mpii->Lut()->Min();
max_lut = mpii->Lut()->Max();
sprintf(buff,"%g", min_lut);
mText[0]->SetText(buff);
sprintf(buff,"%g", max_lut);
mText[1]->SetText(buff);
if ( (mpii->Lut())->Type() == kLutType_Lin ) 
  mOpt[0]->SetValue(1100);
else mOpt[0]->SetValue(1101);
string s("NoAuto");
mOpt[1]->SetValueStr(s);
mSc[0]->SetValue(0);
mSc[1]->SetValue(0);
mOptzc[0]->SetValue(203);
mOptzc[1]->SetValue(101);
return;
}


/* --Methode-- */
void PIImgTools::Process(PIMessage msg, PIMsgHandler* /*sender*/, void* /*data*/)
{
double min, max, del;
int lauto, typ;
int typlut[2] = {kLutType_Lin, kLutType_Log} ; 

msg = UserMsg(msg);

if (msg == 2600)  { this->Hide();  return; }
PIImage* mpii = PIImage::CurrentPIImage();
if (mpii == NULL)  return;

switch (msg)
  {
  case 2500:
  case 2700 :
  case 2800 :
    {
    min = atof(mText[0]->GetText().c_str());
    max = atof(mText[1]->GetText().c_str());
    if (msg == 2700) {
      del = max_lut-min_lut;
      min = min_lut+(double)mSc[0]->GetValue()/100*del;
      max = max_lut+(double)mSc[0]->GetValue()/100*del;
    }
    if (msg == 2800) {
      del = max_lut-min_lut;
      min = min_lut-(double)mSc[1]->GetValue()/100.*del*0.5;
      max = max_lut+(double)mSc[1]->GetValue()/100.*del*0.5;
    }
    if ( (msg == 2700) || (msg == 2800) ) {
      char buff[92];
      sprintf(buff,"%g", min);
      mText[0]->SetText(buff);
      sprintf(buff,"%g", max);
      mText[1]->SetText(buff);
      lauto = 0;
    }
    else lauto = mOpt[1]->GetValue() - 1200;
    typ = mOpt[0]->GetValue() - 1100;
    if ( (typ < 0) || (typ > 1) )  typ = 0;
    (PIImage::CurrentPIImage())->SetLut(min, max, typlut[typ], lauto);
    if (msg == 2500) { 
      min_lut = min;   max_lut = max;
      mSc[0]->SetValue(0);
      mSc[1]->SetValue(0);
      }
//    ((PIImage::CurrentPIImage())->Lut())->Print();
    }
    break;

  case 3201 :
  case 3202 :
  case 3204 :
  case 3198 :
  case 3196 :
    {
    PIImage* pimg = PIImage::CurrentPIImage();
    int zm = msg-3200;
    pimg->SetZoom(zm, false);
    int sx, sy, snx, sny;
    sx = pimg->XSize();
    sy = pimg->YSize();
    if (zm > 0)
      {
      snx = pimg->Image()->XSize()*zm;
      sny = pimg->Image()->YSize()*zm;
      }
    else 
      {
      snx = pimg->Image()->XSize()/(-zm);
      sny = pimg->Image()->YSize()/(-zm);
      }
    if ((snx != sx) || (sny != sy))
      {
      int szinc[2];
      pimg->SetOffset(0, 0, false);
      szinc[0] = snx-sx;   szinc[1] = sny-sy;
      pimg->Send(pimg->Msg(), PIMsg_ResizeRequest, szinc);  
      }
    else   pimg->SetOffset(0, 0);
    
    }
    break;

  case 5201 :
    mpii->ChangeAxesConfiguration(true, false, false);
    break;
  case 5202 :
    mpii->ChangeAxesConfiguration(false, true, false);
    break;
  case 5203 :
    mpii->ChangeAxesConfiguration(false, false, true);
    break;


  case 5300 :
    mpii->SetDrawAxesFlags(kAxesNone);
    mpii->ShowCursor(false);
    mpii->MyElDrawer()->ElDelAll();
    mpii->Refresh();
    break;

  case 5311 :
    mpii->ShowInfo(true);
    break;

  case 5312 :
    mpii->ShowInfo(false);
    break;

  case 5321 :
    mpii->ShowCursor(true);
    break;

  case 5331 :
    mpii->SetDrawAxesFlags();
    break;

  default:
//    printf("PIImgTools::Process Msg %d received \n", (int)msg);
    break;
  }


CMapId cmap[10] =  { CMAP_GREY32, CMAP_GREYINV32, CMAP_COLRJ32,
                      CMAP_COLBR32, CMAP_COLRV32, CMAP_GREY128,
                      CMAP_GREYINV128, CMAP_COLRJ128, CMAP_COLBR128,
                      CMAP_COL16 };

if ((msg <= 110) && (msg >= 90))  // Zoom
  PIImage::CurrentPIImage()->SetZoom((int)(msg-100), true);
else if ((msg > 200) && (msg < 211)) // Changement de couleur 
  PIImage::CurrentPIImage()->SetColMapId(cmap[msg-201], true);

return;
}

