// 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
// modifs pour 
#include <stdlib.h>

#include "sopnamsp.h"
#include "pidrwtools.h"
#include <iostream>
#include <list>
#include <typeinfo>
#include "piscdrawwdg.h"
#include "pi3dwdg.h"

//++
// Class	PIDrwTools
// Lib		PI
// include	pidrwtools.h
//
//	Classe de fenêtre de dialogue permettant de modifier interactivement
//	Les attributs graphique des "Drawer" attachés aux "PIBaseWdg".
//--
// Links	Parents
// PIWindow
//--
//++
// Links	Voir aussi
// PIDrawer
// PIBaseWdg
//--
//++
// Links	Ainsi que
// PIScDrawWdg
// PIImage
// PIDraw3DWdg
//--

//++
// Titre	Méthodes statiques
//--
//++
// void  ShowPIDrwTools() 	
//	Méthode statique permettant l'affichage de la fenêtre de contrôle des
//	attributs graphiques des "Drawer". L'instance de la classe
//	 "PIDrwTools" est créée si nécessaire.
// void  HidePIDrwTools() 
//	Désacative (cache) la fenêtre "PIDrwTools" (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).
//--


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

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

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

/* --Methode-- */
void PIDrwTools::HidePIDrwTools() 
{
if (cwdrwt == NULL)  return; 
cwdrwt->Hide();
}

/* --Methode-- */
void PIDrwTools::SetCurrentBaseWdg(PIBaseWdgGen* cbw)
{
if (mCurBW == cbw) return;
mCurBW = cbw;
if (cwdrwt != NULL)
  cwdrwt->UpdateControlsFromDrawer(-9);
}

/* --Methode-- */
PIBaseWdgGen* PIDrwTools::GetCurrentBaseWdg()
{
return(mCurBW);
}

/* --Methode-- */
PIDrawer* PIDrwTools::GetActiveDrawer()
{
if ((cwdrwt == NULL) || (mCurBW == NULL) || (cwdrwt->mNDr < 0) )  
  return(NULL);
else return(mCurBW->GetDrawer(cwdrwt->mNDr));
}

/* --Methode-- */
void PIDrwTools::UpdateActiveDrawer()
{
  if (cwdrwt && cwdrwt->IsVisible())  
    cwdrwt->UpdateControlsFromDrawer(-9);
}


/* --Methode-- */
PIDrwTools::PIDrwTools(PIApplication* par)
: PIWindow((PIMsgHandler*)par, "PIDrawerTools", 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 = (3+6*0.85)*bsy+(8+6*0.85)*spy;
SetSize(wszx, wszy);

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

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

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]->AppendItem("Violet", 117);
mOpt[0]->AppendItem("VioletRed", 118);
mOpt[0]->AppendItem("BlueViolet", 119);
mOpt[0]->AppendItem("DarkViolet", 120);
mOpt[0]->AppendItem("SkyBlue", 121);
mOpt[0]->AppendItem("RoyalBlue", 122);
mOpt[0]->AppendItem("ForestGreen", 123);
mOpt[0]->AppendItem("OrangeRed", 124);
mOpt[0]->AppendItem("Brown", 125);
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);
int kcc;
//  Groupement des tables de couleurs
mCasc[0] = new PIMenu(mOpt[1]->Menu(), "PIStd-128Col");
mCasc[1] = new PIMenu(mOpt[1]->Menu(), "PIUniCol32");
mCasc[2] = new PIMenu(mOpt[1]->Menu(), "MIDAS-CMap");

int nsct1,nsct2,nsct3,nsct4;
//  D'abord les tables standard de PI  32 couleurs
nsct1 = 5;   // Les 5 premieres tables
for(kcc=0; kcc<nsct1; kcc++) 
  mOpt[1]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(), 201+kcc);
//  Ensuite les tables standard de PI  128 couleurs
nsct2 = 9;   // Les 4 tables suivantes
for(kcc=nsct1; kcc<nsct2; kcc++) 
  mCasc[0]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(), 201+kcc);
mOpt[1]->AppendPDMenu(mCasc[0]);
nsct3 = 17;  // Les 7 tables de couleurs uniforme
for(kcc=nsct2; kcc<nsct3; kcc++) 
  mCasc[1]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(), 201+kcc);
mOpt[1]->AppendPDMenu(mCasc[1]);
//  Apres les tables importees de MIDAS
nsct4 = PIColorMap::NumberStandardColorMaps()-2; // Les reste jusqu'a l'avant derniere
for(kcc=nsct3; kcc<nsct4; kcc++) 
  mCasc[2]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(), 201+kcc);
mOpt[1]->AppendPDMenu(mCasc[2]);
// Les tables qui restent ( Col16 , ... )
for(kcc=nsct4; kcc<PIColorMap::NumberStandardColorMaps(); kcc++) 
mOpt[1]->AppendItem(PIColorMap::GetStandardColorMapName(kcc).c_str(), 201+kcc);

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("Courier", 501);
mOpt[4]->AppendItem("Helvetica", 502);
mOpt[4]->AppendItem("Times", 503);
mOpt[4]->AppendItem("Symbol-Font", 504);
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]->AppendItem("ThinDashDott", 610);
mOpt[5]->AppendItem("DashDot-Line", 611);
mOpt[5]->AppendItem("ThickDashDott", 612);
mOpt[5]->SetValue(600);
mOpt[5]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);

cpx = 2*spx;
cpy += spy+bsy;
mOpt[6] = new PIOptMenu(this, "bwt-opt-6", bsx*1.75, bsy, cpx, cpy);
mOpt[6]->AppendItem("Def.FontAtt", 700);
mOpt[6]->AppendItem("Roman-Font", 701);
mOpt[6]->AppendItem("Bold-Font", 702);
mOpt[6]->AppendItem("Italic-Font", 703);
mOpt[6]->AppendItem("BoldItalic", 704);
mOpt[6]->SetValue(700);
mOpt[6]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);

cpx += spx+1.75*bsx; 
mOpt[7] = new PIOptMenu(this, "bwt-opt-7", bsx*1.75, bsy, cpx, cpy);
mOpt[7]->AppendItem("Def.FontSz", 800);
mOpt[7]->AppendItem("Tiny FontSz", 801);
mOpt[7]->AppendItem("Small FontSz", 802);
mOpt[7]->AppendItem("Normal FontSz", 803);
mOpt[7]->AppendItem("Large FontSz", 804);
mOpt[7]->AppendItem("Huge FontSz", 805);
mOpt[7]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);

cpx = 2*spx;
cpy += spy+bsy;
// OP 03/2002

mOpt[8] = new PIOptMenu(this, "bwt-opt-8", bsx*1.75, bsy, cpx, cpy);
mOpt[8]->AppendItem("Def.ArrowMrk", 900);
mOpt[8]->AppendItem("Basic-Arrow", 901);
mOpt[8]->AppendItem("Triangle-Arrow", 902);
mOpt[8]->AppendItem("FTriangle-Arrow", 903);
mOpt[8]->AppendItem("ShapedArrow", 904);
mOpt[8]->AppendItem("FShapedArrow", 905);
mOpt[8]->SetValue(900);
mOpt[8]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);

cpx += spx+1.75*bsx; 
mOpt[9] = new PIOptMenu(this, "bwt-opt-9", bsx*1.75, bsy, cpx, cpy);
mOpt[9]->AppendItem("Arrow-1pt  ", 951);
mOpt[9]->AppendItem("Arrow-3pt ", 952);
mOpt[9]->AppendItem("Arrow-5pt", 953);
mOpt[9]->AppendItem("Arrow-7pt", 954);
mOpt[9]->AppendItem("Arrow-9pt", 955);
mOpt[9]->AppendItem("Arrow-11pt", 956);
mOpt[9]->AppendItem("Arrow-13pt", 957);
mOpt[9]->AppendItem("Arrow-15pt", 958);
mOpt[9]->AppendItem("Arrow-17pt", 959);
mOpt[9]->SetValue(952 );
mOpt[9]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);

cpx = 2*spx;
cpy += spy+bsyo;

// end OP
int kb;
bsy = bsyo; spy = spyo;
mButdr[0] = new PIButton(this, "-", 1501, bsy, bsy, cpx, cpy);
cpx += bsy+0.25*spy;
mNlb = new PILabel(this,"NumDr", 1.2*bsy, bsy, cpx, cpy);
mNlb->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
mNlb->SetLabel("");
mNDr = 0;
cpx += 1.2*bsy+0.25*spy;
mButdr[1] = new PIButton(this, "+", 1502, 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);
for(kb=0; kb<2; kb++) {
  mButdr[kb]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
  mButdr[kb]->SetUnSensitive();
}
cpx += bsy+2*spx; 
mDrName = new PILabel(this,"DrName", wszx-2*spx-cpx, bsy, cpx, cpy);
mDrName->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
mDrName->SetLabel("No-Drawer");
mDrName->SetBorderWidth(1);

cpy += bsy+spy;
cpx = 2*spx;
int butszx = bsx;
int busp = (wszx-4*spx-3*butszx)/2;
mButcf[0] = new PIButton(this, "GetAtt", 2500, butszx, bsy, cpx, cpy);
cpx += butszx+busp;
mButcf[1] = new PIButton(this, "SetAtt", 2600, butszx, bsy, cpx, cpy);
cpx += butszx+busp;
mButcf[2] = new PIButton(this, "Select", 2700, butszx, bsy, cpx, cpy);
mButcf[2]->ActivatePress(true);

butszx = 1.2*bsx;
cpx = (wszx-2*butszx-4*spx)/2;
cpy += bsy+spy;
mButcf[4] = new PIButton(this, "OptionString", 2900, butszx, bsy, cpx, cpy);
cpx += butszx+4*spx;
mButcf[3] = new PIButton(this, "ShowControl", 2800, butszx, bsy, cpx, cpy);

butszx = 1.6*bsx;
cpx = (wszx-2*butszx-4*spx)/2;
cpy += 2*spy+bsy;
mButcf[5] = new PIButton(this, "Refresh", 3000, butszx, bsyo, cpx, cpy);
cpx += butszx+4*spx;
mButcf[6] = new PIButton(this, "Dismiss", 3777, butszx, bsyo, cpx, cpy);

for(kb=0; kb<7; kb++) 
  mButcf[kb]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
for(kb=0; kb<6; kb++) 
  mButcf[kb]->SetUnSensitive();

mButSens = 0;
cwdrwt = this;

}

/* --Methode-- */
PIDrwTools::~PIDrwTools()
{
if (cwdrwt == this)  cwdrwt = NULL;
int i;
for(i=0; i<7; i++) delete mButcf[i]; 
for(i=0; i<2; i++) delete mButdr[i]; 
for(i=0; i<10 ; i++)  delete mOpt[i];
for(i=0; i<3; i++)  delete mCasc[i];
delete mNlb;
delete mDrName;
}

//  Declaration des differents attributs graphiques 
#define MYNMXCOLORS 26
static PIColors cols[MYNMXCOLORS] = { 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, PI_Violet, PI_VioletRed,
                     PI_BlueViolet, PI_DarkViolet,
		     PI_SkyBlue, PI_RoyalBlue,
		     PI_ForestGreen,
		     PI_OrangeRed, PI_Brown };

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 PILineTypes line[13] = { PI_NotDefLineAtt, PI_ThinLine, PI_NormalLine, PI_ThickLine, 
                              PI_ThinDashedLine, PI_DashedLine, PI_ThickDashedLine, 
			      PI_ThinDashDottedLine, PI_DashDottedLine, PI_ThickDashDottedLine,
                              PI_ThinDottedLine, PI_DottedLine, PI_ThickDottedLine };

static PIFontName fntname[5] = { PI_DefaultFont, PI_CourierFont, PI_HelveticaFont, 
				 PI_TimesFont, PI_SymbolFont};
static PIFontAtt fntatt[5] = { PI_NotDefFontAtt, PI_RomanFont, PI_BoldFont, 
			       PI_ItalicFont, PI_BoldItalicFont };
static PIFontSize fntsz[6] = { PI_NotDefFontSize, PI_TinySizeFont, PI_SmallSizeFont, 
			       PI_NormalSizeFont, PI_LargeSizeFont, PI_HugeSizeFont };

static PIArrowMarker arrmrk[6]= { PI_NotDefArrowMarker, PI_BasicArrowMarker, 
                     PI_TriangleArrowMarker, PI_FTriangleArrowMarker,
                     PI_ArrowShapedArrowMarker, PI_FArrowShapedArrowMarker };


/* --Methode-- */
void PIDrwTools::Show()
{
PIWindow::Show();
UpdateControlsFromDrawer(-9);
UpdateAttFromDrawer();
return;
}

/* --Methode-- */
void PIDrwTools::UpdateControlsFromDrawer(int numdr)
{
  string lstr;
  int kb;
  int butsensnew = 0;

  PIDrawer * dr = NULL;
  
  if (mCurBW != NULL) {
    if (numdr < -1) { 
      if (mCurBW->NbDrawers() > 0)  mNDr = mCurBW->GetActiveDrawerNum();
      else mNDr = -1;
    }
    else { 
      if (mCurBW->NbDrawers() > 0) {
	mNDr = numdr;
	if (mNDr < 0)  mNDr = 0;
	else if (mNDr >= mCurBW->NbDrawers()) mNDr = mCurBW->NbDrawers()-1;
      }
      else mNDr = -1;
    }
    if (mNDr >= 0)   dr = mCurBW->GetDrawer(mNDr);
    if (dr != NULL)  butsensnew = 2;
    else butsensnew = 1;
  }

  if (butsensnew == 2) {
    char strg[64];
    sprintf(strg,"%d",mNDr);
    mNlb->SetLabel(strg);
    string wdrname = mCurBW->Nom()+":"+dr->Name();
    mDrName->SetLabel(wdrname);
    if ((dr != NULL) && dr->HasSpecificControlWindow()) 
      mButcf[3]->SetSensitive(); 
    else mButcf[3]->SetUnSensitive(); 	
  }
  else if (mButSens != butsensnew) {
    if(mButSens == 2)  mNlb->SetLabel("");
    if (butsensnew == 1)   mDrName->SetLabel(mCurBW->Nom());
    else  mDrName->SetLabel("No-BaseWdg");
  }

  if (butsensnew != mButSens) {
    if (butsensnew < 2) {
      for(kb=0; kb<2;kb++)  mButdr[kb]->SetUnSensitive();
      for(kb=0; kb<5;kb++)  mButcf[kb]->SetUnSensitive();
      if (butsensnew == 0) mButcf[5]->SetUnSensitive();
      else mButcf[5]->SetSensitive();
    }
    else { 
      for(kb=0; kb<2;kb++)  mButdr[kb]->SetSensitive();
      for(kb=0; kb<3;kb++)  mButcf[kb]->SetSensitive();
      mButcf[4]->SetSensitive();
      mButcf[5]->SetSensitive();
    }
  }
  mButSens = butsensnew;
}    

/* --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);
mOpt[6]->SetValue(700);
mOpt[7]->SetValue(800);

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

if (!dr)  return;

int ii,jj,kk;
PIGraphicAtt const & gratt = dr->GetGraphicAtt();
PIColors fc = gratt.GetFgColor();
for(kk=0; kk<MYNMXCOLORS; kk++) 
  if (fc == cols[kk])  { mOpt[0]->SetValue(100+kk);  break; }    
CMapId cmi = gratt.GetColMapId();
if (cmi == CMAP_OTHER)  mOpt[1]->SetValue(200);
else for(kk=0; kk<PIColorMap::NumberStandardColorMaps(); kk++)
  if (cmi == PIColorMap::GetStandardColorMapId(kk)) { mOpt[1]->SetValue(201+kk);  break; }  
PIMarker mk = gratt.GetMarker();   
for(kk=0; kk<12; kk++) 
  if (mk == mrk[kk])   { mOpt[2]->SetValue(300+kk);  break; }
kk = gratt.GetMarkerSz();
if (kk < 1)  kk = 1;
if (kk > 15) kk = 15;
if (kk%2 == 0) kk++;
mOpt[3]->SetValue(400+kk);
PIFontName fnm = gratt.GetFontName();
PIFontAtt fat = gratt.GetFontAtt();
PIFontSize fsz = gratt.GetFontSz();

for(ii=0; ii<5; ii++)
  if (fnm ==  fntname[ii]) break;
for(kk=0; kk<5; kk++)
  if (fat ==  fntatt[kk]) break;
for(jj=0; jj<5; jj++) 
  if (fsz == fntsz[jj])  break;

if (ii >= 5) ii = 1;
if (kk >= 5) kk = 1;
if (jj >= 6) jj = 3;
mOpt[4]->SetValue(500+ii);
mOpt[6]->SetValue(700+kk);
mOpt[7]->SetValue(800+jj);

PILineAtt lat = gratt.GetLineAtt();
for(kk=0; kk<13; kk++)
  if (lat == line[kk])   { mOpt[5]->SetValue(600+kk);  break; }

PIArrowMarker arr = gratt.GetArrowMarker();
for(kk=0 ; kk<6 ; kk++)
  if(arr == arrmrk[kk]) {mOpt[8]->SetValue(900+kk);}
     
kk = gratt.GetArrowMarkerSize();
if(kk<1) kk=1;
if(kk>17) kk=17;
 kk = (kk+1)/2;
mOpt[9]->SetValue(950 + kk);

return;
}

/* --Methode-- */
void PIDrwTools::SetGraphicAtt(bool fgref)
{
  if (mCurBW == NULL)   return;
  PIDrawer* drw = mCurBW->GetDrawer(mNDr);
  if (drw == NULL)  return;
  mCurBW->SetActiveDrawer(mNDr);
  PIGraphicAtt gratt;
  int k,ii,jj,kk;
  k = mOpt[0]->GetValue()-100;
  if ( (k < 0) || (k >= MYNMXCOLORS) )  k = 0;
  gratt.SetColAtt(cols[k]);
  k = mOpt[1]->GetValue()-200;
  if (k == 0) gratt.SetColMapId(CMAP_OTHER);
  else gratt.SetColMapId(PIColorMap::GetStandardColorMapId(k-1));
  k =  mOpt[2]->GetValue()-300;
  if ( (k < 0) || (k > 11) )  k = 0;
  kk =  mOpt[3]->GetValue()-400;
  if ( (kk < 1) || (kk > 27) )  kk = 1;
  //  if ((k > 0) && (kk < 3)) {  // Protection contre Marker taille 1 autre que Dotmarker
  //    mOpt[3]->SetValue(403);
  //   kk = 3;
  //  }
  gratt.SetMarkerAtt(kk, mrk[k]);
  ii =  (mOpt[4]->GetValue()-500);
  jj =  (mOpt[6]->GetValue()-700);
  kk =  (mOpt[7]->GetValue()-800);
  gratt.SetFontAtt(fntname[ii], fntsz[kk], fntatt[jj]);

  k =  mOpt[5]->GetValue()-600;
  if ( (k < 0) || (k > 12) )  k = 0;
  gratt.SetLineAtt(PILineAtt(line[k]));

  ii=mOpt[8]->GetValue()-900;
  jj=mOpt[9]->GetValue()-950;
  
  gratt.SetArrowMarkerAtt(2*jj-1,arrmrk[ii]);
  
  drw->SetGraphicAtt(gratt);

  if (fgref)  mCurBW->Refresh();
  else drw->Refresh();
}

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

  PIMessage mod = ModMsg(msg);
  msg = UserMsg(msg);

  switch (msg) {
    case 1501 :
    case 1502 :
      if (mCurBW && (mCurBW->NbDrawers() > 0)) {
	if (msg == 1501)  UpdateControlsFromDrawer(mNDr-1);
	else UpdateControlsFromDrawer(mNDr+1);
      }
      break;

    case 2500 :
      UpdateAttFromDrawer();
      break;

    case 2600 :
      SetGraphicAtt(false);
      break;

    case 2700 :
      if ((mCurBW != NULL) && (mCurBW->GetDrawer(mNDr) != NULL) ) {
	if (mod == PIMsg_Press)  { 
	  mCurBW->GetDrawer(mNDr)->HighLight(true);
	  mCurBW->SetActiveDrawer(mNDr);
	}
	else  mCurBW->GetDrawer(mNDr)->HighLight(false);
      }
      break;

    case 2800 :
      if ((mCurBW != NULL) && (mCurBW->GetDrawer(mNDr) != NULL) ) 
	mCurBW->GetDrawer(mNDr)->ShowControlWindow(mCurBW);
      break;

    case 2900 :
      if ((mCurBW != NULL) && (mCurBW->GetDrawer(mNDr) != NULL) ) 
        PIDrwOptionStringWindow::ShowDrwOptionStringWindow(mCurBW->GetDrawer(mNDr));
      break;

    case 3000 :
      SetGraphicAtt(true);
      break;

    case 3777 :
      Hide();
      break;

      /*   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;
}


//---------------------------------------------------------------
//---------------- Classe PIDrwOptionStringWindow ---------------
//---------------------------------------------------------------

//++
// Class	PIDrwOptionStringWindow
// Lib		PI
// include	pidrwtools.h
//
//	Classe de fenêtre de dialogue permettant de modifier interactivement
//	Les attributs graphique des "Drawer" par l'appel à *DecodeOptionString()*.
//--
// Links	Parents
// PIWindow
//--
//++
// Links	Voir aussi
// PIDrawer
// PIDrwTools
//--

//++
// Titre	Méthodes statiques
//--
//++
// void  ShowDrwOptionStringWindow(PIDrawer* drw)	
//	Méthode statique permettant l'affichage de la fenêtre de changement des
//	attributs graphiques à travers *PIDrawer::DecodeOptionString()*
//	pour le drawer "drw".
// void  RemoveDrwOptionStringWindow(
//	Suppression de la fenêtre associé à "drw" (appelée par le destructeur
//	des PIDrawer)
//--

static list<PIDrwOptionStringWindow* > drwoswlist;

/* --Methode-- */
void PIDrwOptionStringWindow::ShowDrwOptionStringWindow(PIDrawer* drw)
{
  if (drw == NULL) return;
  list<PIDrwOptionStringWindow* >::iterator it;
  for(it=drwoswlist.begin(); it!= drwoswlist.end(); it++) 
    if ((*it)->GetDrawer() == drw) { 
      (*it)->Show(); 
      return; 
    }
  PIDrwOptionStringWindow* osw = 
    new PIDrwOptionStringWindow(PIApplicationGetApp(), drw);
  drwoswlist.push_back(osw);
  osw->Show();
}

/* --Methode-- */
void PIDrwOptionStringWindow::RemoveDrwOptionStringWindow(PIDrawer* drw)
{
  if (drw == NULL) return;
  list<PIDrwOptionStringWindow* >::iterator it;
  for(it=drwoswlist.begin(); it!= drwoswlist.end(); it++) 
    if ((*it)->GetDrawer() == drw) { 
      (*it)->Hide();
      delete *it;
      drwoswlist.erase(it); 
      break;
    }
  return;
}

/* --Methode-- */
PIDrwOptionStringWindow::PIDrwOptionStringWindow(PIApplication* par, PIDrawer* drw)
  : PIWindow((PIMsgHandler *)par, "DrwOptionString", PIWK_normal, 400, 200, 100, 200) 
  , mDrw(drw)
{
  int bsx, bsy;
  int tsx, tsy;
  int spx, spy;
  PIApplicationPrefCompSize(bsx, bsy);
  spx = bsx/8;   spy = bsy/6;
  tsx = 7.5*bsx+2*spx;  tsy = 6*bsy+4*spy;
  SetSize(tsx,tsy);
  int cpx = spx;
  int cpy = spy;
  mTxt[0] = new PIText(this, "drwoshelp", true, true, bsx*7.5, 4*bsy, cpx, cpy);  
  mTxt[0]->SetTextEditable(false);
  mTxt[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
  mTxt[0]->SetText("");
  cpy += 4*bsy+spy;
  mTxt[1] = new PIText(this, "drwosset", bsx*7.5, bsy, cpx, cpy);  
  mTxt[1]->SetTextEditable(true);
  mTxt[1]->SetMsg(5555);
  mTxt[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
  mTxt[1]->SetText("");
  cpy += bsy+spy;
  int lsx = tsx-4.8*bsx-6*spx;
  mLab = new PILabel(this, "drwntyp", lsx, bsy, cpx, cpy);
  mLab->SetBorderWidth(1);
  mLab->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
  mLab->SetLabel("");
  cpx += lsx+spx;
  mBut[0] = new PIButton(this, "SetOption", 555, bsx*1.2, bsy, cpx, cpy);
  mBut[0]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
  cpx += (1.2*bsx+spx);
  mBut[1] = new PIButton(this, "GetOption", 666, bsx*1.2, bsy, cpx, cpy);
  mBut[1]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
  cpx += (1.2*bsx+spx);
  mBut[2] = new PIButton(this, "Refresh", 500, bsx*1.2, bsy, cpx, cpy);
  mBut[2]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
  cpx += (1.2*bsx+spx);
  mBut[3] = new PIButton(this, "Dimiss", 777, bsx*1.2, bsy, cpx, cpy);
  mBut[3]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
}

/* --Methode-- */
PIDrwOptionStringWindow::~PIDrwOptionStringWindow()
{
  delete mTxt[0];
  delete mTxt[1];
  delete mLab;
  delete mBut[0];
  delete mBut[1];
  delete mBut[2];
  delete mBut[3];
}
/* --Methode-- */
void PIDrwOptionStringWindow::Show()
{
  if (mDrw) {
    string hs;
    mDrw->GetOptionsHelpInfo(hs);
    mTxt[0]->SetText(hs);
    mTxt[1]->SetText("");
    hs = mDrw->Nom();
    hs += " (T=";
    hs += typeid(*mDrw).name();
    hs += ")";
    mLab->SetLabel(hs);
  }
  PIWindow::Show();
}


/* --Methode-- */
void PIDrwOptionStringWindow::Process(PIMessage msg, PIMsgHandler* sender, void* data)
{
  PIMessage mod = ModMsg(msg);
  msg = UserMsg(msg);
  switch (msg) {
  case 777:
    Hide();
    break;
  case 555:
  case 500:
  case 5555:
    if (mDrw) {
      vector<string> vops;
      string ops = mTxt[1]->GetText();
      //cout << " DBG-A " << ops << endl; 
      size_t len = ops.length();
      if (len == 0) {
	if (msg == 500)	mDrw->Refresh(true);
	return;
      }
      size_t cp = ops.find_first_not_of(' ', 0);
      if ((cp < 0) || (cp >= len) ) { 
	if (msg == 500)	mDrw->Refresh(true);
	return;
      }
      size_t tp = ops.find(' ', cp);
      while ((tp > cp) && (tp < len)) {
	vops.push_back(ops.substr(cp, tp-cp));
	cp = tp+1; 
	tp = ops.find(' ', cp);
      }
      if (cp < len) vops.push_back(ops.substr(cp));
      //      cout << " DBG-B " << vops.size() << endl;
      //for(int kk=0; kk< vops.size() ; kk++) 
      //	cout << " DBG-C[" << kk << "] " << vops[kk] << endl; 
      mDrw->DecodeOptionString(vops, false);
      //      ops = "<< " + ops + " >> Decoded";
      ops = "";
      mTxt[1]->SetText(ops);
      if (msg == 500)  mDrw->Refresh(true);
      else mDrw->Refresh(false);
    }
    break;
  case 666:
    if (mDrw) {
      vector<string> vops;
      mDrw->OptionToString(vops);
      string ops;
      for(int kk=0; kk<vops.size(); kk++) {
	ops += vops[kk]; ops += ' ';
      }
      mTxt[1]->SetText(ops);
    }
    break;
  default :
    break;
      
  }
}

//++
// Class	PI
// Lib		PIDrwMgrMenu
// include	pidrwtools.h
//
//	Classe de menu (pop-up) permettant d'interagir avec les drawers
//	attachés aux "PIBaseWdg".
//--
// Links	Parents
// PIMenu
//--
//++
// Links	Voir aussi
// PIDrawer
// PIBaseWdg
//--

//------------------------------------------------------------
//------- Classe Event handler pour move/resize 
class PIDrwPosSizeEvH : public PIEventHandler {
public: 
  PIDrwPosSizeEvH(PIBaseWdgGen* bwdg, bool fgxor=true);
          void    CheckBeforeDelete();
  virtual void    ProcessEvent(); 

protected:
  void ComputeResizeZone();
  void ComputeMoveZone();
  inline void ComputeDrawerZone() 
    { x1 = _x1;  y1 = _y1; x2 = _x2-_x1;  y2 = _y2-_y1; }


  PIBaseWdgGen* mBWdg;
  bool _fgxor;
  int _x1, _y1, _x2, _y2;
  PIGrCoord x1, y1, x2, y2;
  bool _elastic;
  int _ipx, _ipy;
  int _cpx, _cpy;
  bool _defrect;  // true -> modification DefaultRectangle
  bool _rsz; // true -> resize option
  bool _okend;
  bool _rmok;
};

/* --Methode-- */
PIDrwPosSizeEvH::PIDrwPosSizeEvH(PIBaseWdgGen* bwdg, bool fgxor)
{
  mBWdg = bwdg;
  _fgxor = fgxor;
  _x1 = _y1 = _x2 = _y2 = -1;
  _ipx = _ipy = -1;
  _cpx = _cpy = -1;
  _defrect = false;
  _rsz = false;
  _okend = false;
  _rmok = false;
  if (bwdg == NULL) return;
  int aid = bwdg->GetActiveDrawerId();
  if (aid < 0) return;
  
  _elastic = false;
  if (mBWdg->IsDrawerAutoSizePos(aid)) {
    mBWdg->GetDefaultDrawRectangle(x1, y1, x2, y2, _elastic);
    _defrect = true; 
  }
  else { 
    mBWdg->GetDrawerPosition(aid, x1, y1, x2, y2, _elastic);
    _defrect = false; 
  }
    
  if (_elastic) {
    _x1 = (double)x1*(double)mBWdg->XSize();
    _x2 = (double)x2*(double)mBWdg->XSize();
    _y1 = (double)y1*(double)mBWdg->YSize();
    _y2 = (double)y2*(double)mBWdg->YSize();
  }
  else {
    _x1 = x1; _x2 = x2;
    _y1 = y1; _y2 = y2;
  }

  PIGraphic* gr = mBWdg->WindowGraphic();
  mBWdg->GetActiveDrawer()->HighLight(true);
  PIGOMode gmod =  gr->GetGOMode();
  PILineAtt gline = gr->GetLineAtt();
  PIColors gcol = gr->GetForeground();
  if (_fgxor) {
    gr->SelForeground(PI_Magenta);
    gr->SelGOMode(PI_GOXOR);
  }
  else {
    gr->SelForeground(PI_HighlightBlue);
    gr->SelGOMode(PI_GOCopy);
  }
  gr->SelLine(PI_ThinLine);
  ComputeDrawerZone();
  gr->DrawBox(x1,y1, x2, y2);
  ComputeResizeZone();
  gr->DrawFBox(x1,y1, x2, y2);
  ComputeMoveZone();
  gr->DrawBox(x1,y1, x2, y2);
  gr->SelGOMode(gmod);
  gr->SelLine(gline);
  gr->SelForeground(gcol);

//  cout << "DBG- Adding Event-Handler " << endl;
  mBWdg->AddEventHandler(this, PIEvent_But1Press|PIEvent_Ptr1Move|PIEvent_But1Release);
}
/* --Methode-- */
void PIDrwPosSizeEvH::CheckBeforeDelete()
{
  if (!_rmok) {
    PIDrawer* adrw = mBWdg->GetActiveDrawer();
    if (adrw) adrw->HighLight(true);
    mBWdg->RemoveEventHandler(this);	
  }
  _rmok = true; 
}

/* --Methode-- */
void PIDrwPosSizeEvH::ComputeResizeZone()
{
  int dx = (int)(0.05*(_x2-_x1));
  int dy = (int)(0.05*(_y2-_y1));
  int maxdx = (int)(0.20*(_x2-_x1));
  int maxdy = (int)(0.20*(_y2-_y1));
  if (dx < 20)  dx = 20;
  if (dx > maxdx) dx = maxdx;
  if (dy < 20)  dx = 20;
  if (dy > maxdy) dy = maxdy;
  int dxy = (dx < dy) ? dx : dy ;
  x1 = _x2-dxy;  y1 = _y2-dxy;
  x2 = y2 = dxy;
}

/* --Methode-- */
void PIDrwPosSizeEvH::ComputeMoveZone()
{
  int dx = (int)(0.08*(_x2-_x1));
  int dy = (int)(0.08*(_y2-_y1));
  int maxdx = (int)(0.20*(_x2-_x1));
  int maxdy = (int)(0.20*(_y2-_y1));
  if (dx < 20)  dx = 20;
  if (dx > maxdx) dx = maxdx;
  if (dy < 20)  dx = 20;
  if (dy > maxdy) dy = maxdy;
  int dxy = (dx < dy) ? dx : dy ;
  x1 = (_x1+_x2)*0.5-dxy;  
  y1 = (_y1+_y2)*0.5-dxy;    
  x2 = y2 = 2*dxy;
}

/* --Methode-- */
void PIDrwPosSizeEvH::ProcessEvent()
{
  int delx, dely;
  int ix1,iy1,ix2,iy2;
  x1 = _x1; x2 = _x2;
  y1 = _y1; y2 = _y2;
  bool fgok = false;
  int aid = -1;

  PIGraphic* gr = mBWdg->WindowGraphic();

  PIGOMode gmod =  gr->GetGOMode();
  PILineAtt gline = gr->GetLineAtt();
  PIColors gcol = gr->GetForeground();

  switch (EventType()) {
    case PIEvent_But1Press :
      // Zone de changement de taille 
      ComputeResizeZone();
      ix1 = x1;  iy1 = y1;
      ix2 = _x2;  iy2 = _y2;
      if ( (GetPosX() >= ix1) && (GetPosX() <= ix2) && 
	   (GetPosY() >= iy1) && ((GetPosY() <= iy2) ) ) 
	{ fgok = true; _rsz = true; }		 
      ComputeMoveZone();
      ix1 = x1;  iy1 = y1;
      ix2 = (int)x2+ix1;  iy2 = (int)y2+iy1;
      if ( (GetPosX() >= ix1) && (GetPosX() <= ix2) && 
	   (GetPosY() >= iy1) && ((GetPosY() <= iy2) ) ) 
	{ fgok = true; _rsz = false; }
      if (!fgok) _okend = true;
      else { 
	_cpx = _ipx = GetPosX();
	_cpy = _ipy = GetPosY();
      }
      break;

    case  PIEvent_Ptr1Move :
      if (_okend) return; 
      if (_ipx < 0)  return;
      delx = GetPosX()-_cpx;
      dely = GetPosY()-_cpy;
      _cpx = GetPosX(); 
      _cpy = GetPosY(); 
      
      if (_fgxor) {
        gr->SelForeground(PI_Magenta);
        gr->SelGOMode(PI_GOXOR);
      }
      else {
        gr->SelForeground(mBWdg->GetBackgroundColor());
        gr->SelGOMode(PI_GOCopy);
      }
      gr->SelLine(PI_ThinLine);

      ComputeDrawerZone();
      gr->DrawBox(x1,y1, x2, y2);
      ComputeResizeZone();
      gr->DrawFBox(x1,y1, x2, y2);
      ComputeMoveZone();
      gr->DrawBox(x1,y1, x2, y2);

      // Nouvelle position / taille 
      _x2 += delx;
      _y2 += dely;
      if (!_rsz) { _x1 += delx;  _y1 += dely; }

      if (!_fgxor) gr->SelForeground(PI_HighlightBlue);
      ComputeDrawerZone();
      gr->DrawBox(x1,y1, x2, y2);
      ComputeResizeZone();
      gr->DrawFBox(x1,y1, x2, y2);
      ComputeMoveZone();
      gr->DrawBox(x1,y1, x2, y2);      
      gr->SelGOMode(gmod);
      gr->SelLine(gline);
      gr->SelForeground(gcol);

      break;

    case  PIEvent_But1Release :
      if (_ipx < 0)  return;
      if (_okend) {
   // On efface de rectangle de resize/move
        if (_fgxor) {
          gr->SelForeground(PI_Magenta);
          gr->SelGOMode(PI_GOXOR);
        }       
        else {
          gr->SelForeground(mBWdg->GetBackgroundColor());
          gr->SelGOMode(PI_GOCopy);
        }
        gr->SelLine(PI_ThinLine);
	
        ComputeDrawerZone();
        gr->DrawBox(x1,y1, x2, y2);
        ComputeResizeZone();
        gr->DrawFBox(x1,y1, x2, y2);
        ComputeMoveZone();
        gr->DrawBox(x1,y1, x2, y2);
	gr->SelGOMode(gmod);
	gr->SelLine(gline);
	gr->SelForeground(gcol);
  // On enleve le handler 
//	cout << " DBG- 	mBWdg->RemoveEventHandler(this); " << endl;
        PIDrawer* adrw = mBWdg->GetActiveDrawer();
        if (adrw) adrw->HighLight(false);
	mBWdg->RemoveEventHandler(this);
        _rmok = true;
	return;
      }

      // Nouvelle position / taille 
      delx = GetPosX()-_cpx;
      dely = GetPosY()-_cpy;
      _x2 += delx;
      _y2 += dely;
      if (!_rsz) { _x1 += delx;  _y1 += dely; }
      if (_elastic) {
	x1 = (double)_x1/(double)mBWdg->XSize();
	x2 = (double)_x2/(double)mBWdg->XSize();
	y1 = (double)_y1/(double)mBWdg->YSize();
	y2 = (double)_y2/(double)mBWdg->YSize();
      }
      else {
	x1 = _x1; x2 = _x2;
	y1 = _y1; y2 = _y2;
      }
      if (_defrect) {
	mBWdg->SetDefaultDrawRectangle(x1, y1, x2, y2, _elastic);
//	cout << "DBG-SetDefaultDrawRectangle() x1,y1=" << _x1 << "," << _y1 
//     << " x2,y2=" << _x2 << "," << _y2 << endl;
      }
      else {
        aid = mBWdg->GetActiveDrawerId();
        mBWdg->MoveResizeDrawer(aid, x1, y1, x2, y2, _elastic);
//	cout << "DBG-MoveResizeDrawer() x1,y1=" << _x1 << "," << _y1 
//	     << " x2,y2=" << _x2 << "," << _y2 << endl;
      }	
      mBWdg->Refresh();

      if (_fgxor) {
        gr->SelForeground(PI_Magenta);
        gr->SelGOMode(PI_GOXOR);
      }
      else {
        gr->SelForeground(PI_HighlightBlue);
        gr->SelGOMode(PI_GOCopy);
      }
      ComputeDrawerZone();
      gr->DrawBox(x1,y1, x2, y2);
      ComputeResizeZone();
      gr->DrawFBox(x1,y1, x2, y2);
      ComputeMoveZone();
      gr->DrawBox(x1,y1, x2, y2);      

      gr->SelGOMode(gmod);
      gr->SelLine(gline);
      gr->SelForeground(gcol);

      break; 

    default :
      break;
  }
  
}

//-----------------------------------------------------------------
//------- Classe Event handler pour Mouse Select de l'active Drawer 
class PIDrwSelectEvH : public PIEventHandler {
public: 
  PIDrwSelectEvH(PIBaseWdgGen* bwdg);
          void    CheckBeforeDelete();
  virtual void    ProcessEvent(); 

protected:
//  void ComputeResizeZone();
  void ComputeOKZone();
//  inline void ComputeDrawerZone() 
//    { x1 = _x1;  y1 = _y1; x2 = _x2-_x1;  y2 = _y2-_y1; }


  PIBaseWdgGen* mBWdg;
  int _caid;
  int _x1, _y1, _x2, _y2;
  PIGrCoord x1, y1, x2, y2;
  PIGrCoord xc, yc, rc;
  bool _okend;
  bool _rmok;
};

/* --Methode-- */
PIDrwSelectEvH::PIDrwSelectEvH(PIBaseWdgGen* bwdg)
{
  mBWdg = bwdg;
  _x1 = _y1 = _x2 = _y2 = -1;
  x1 = y1 = x2 = y2 = xc = yc = rc = -1;
  _okend = false;
  _rmok = false;
  if (bwdg == NULL) return;

  int aid = bwdg->GetActiveDrawerId();
  if (aid < 0) return;
  
  mBWdg->GetActiveDrawer()->HighLight(true);
  _caid = aid;

  PIGraphic* gr = mBWdg->WindowGraphic();
  
  PIGOMode gmod =  gr->GetGOMode();
  PILineAtt gline = gr->GetLineAtt();
  PIColors gcol = gr->GetForeground();

  gr->SelForeground(PI_Magenta);
  gr->SelGOMode(PI_GOXOR);
  gr->SelLine(PI_ThinLine);

  ComputeOKZone();
  gr->DrawBox(x1,y1, x2, y2);
  gr->DrawFCircle(xc,yc,rc);

  gr->SelGOMode(gmod);
  gr->SelLine(gline);
  gr->SelForeground(gcol);

//  cout << "DBG- Adding Event-Handler " << endl;
  mBWdg->AddEventHandler(this, PIEvent_But1Press);
}
/* --Methode-- */
void PIDrwSelectEvH::CheckBeforeDelete()
{
  if (!_rmok) {
    PIDrawer* adrw = mBWdg->GetActiveDrawer();
    if (adrw) adrw->HighLight(true);
    mBWdg->RemoveEventHandler(this);	
  }
  _rmok = true; 
}


/* --Methode-- */
void PIDrwSelectEvH::ComputeOKZone()
{
  bool _elastic = false;
  int aid = mBWdg->GetActiveDrawerId();
  if (mBWdg->IsDrawerAutoSizePos(aid)) {
    mBWdg->GetDefaultDrawRectangle(x1, y1, x2, y2, _elastic);
  }
  else { 
    mBWdg->GetDrawerPosition(aid, x1, y1, x2, y2, _elastic);
  }
    
  if (_elastic) {
    _x1 = (double)x1*(double)mBWdg->XSize();
    _x2 = (double)x2*(double)mBWdg->XSize();
    _y1 = (double)y1*(double)mBWdg->YSize();
    _y2 = (double)y2*(double)mBWdg->YSize();
  }
  else {
    _x1 = x1; _x2 = x2;
    _y1 = y1; _y2 = y2;
  }

  int dx = (int)(0.06*(_x2-_x1));
  int dy = (int)(0.06*(_y2-_y1));
  if (dx < 20)  dx = 20;
  if (dy < 20)  dx = 20;
  int dxy = (dx < dy) ? dx : dy ;
  if (dxy%2 != 0) dxy++;
  _x1 = _x2-dxy;
  _y1 = _y2-dxy;
  x1 = _x1;  
  y1 = _y1;    
  x2 = y2 = dxy;
  xc = _x1+dxy/2;
  yc = _y1+dxy/2;
  rc = dxy/2-2;
}

/* --Methode-- */
void PIDrwSelectEvH::ProcessEvent()
{

  bool chgadrw = false;
  int nid = -1;

  PIGraphic* gr = mBWdg->WindowGraphic();

  PIGOMode gmod =  gr->GetGOMode();
  PILineAtt gline = gr->GetLineAtt();
  PIColors gcol = gr->GetForeground();


  switch (EventType()) {
    case PIEvent_But1Press :
      // Zone OK=Fin
      if ( (GetPosX() >= _x1) && (GetPosX() <= _x2) && 
	   (GetPosY() >= _y1) && ((GetPosY() <= _y2) ) ) _okend = true;
      else {
        nid = mBWdg->FindNearestDrawerId(GetPosX(), GetPosY());
        if (nid != _caid)  chgadrw = true;
      }
      break;

    default :
      break;
  }
  if ( _okend || chgadrw ) {
    gr->SelForeground(PI_Magenta);
    gr->SelGOMode(PI_GOXOR);
    gr->SelLine(PI_ThinLine);

    gr->DrawBox(x1,y1, x2, y2);
    gr->DrawFCircle(xc,yc,rc);

    gr->SelGOMode(gmod);
    gr->SelLine(gline);
    gr->SelForeground(gcol);

    PIDrawer* adrw = mBWdg->GetActiveDrawer();
    if (adrw) adrw->HighLight(false);
    
    if (_okend) {
      mBWdg->RemoveEventHandler(this);
      _rmok = true;
      return;
    }		 
    else { 
      mBWdg->SetActiveDrawerId(nid);
      _caid = nid;
      adrw = mBWdg->GetActiveDrawer();
      if (adrw) adrw->HighLight(true);
    
      gr->SelForeground(PI_Magenta);
      gr->SelGOMode(PI_GOXOR);
      gr->SelLine(PI_ThinLine);

      ComputeOKZone();

      gr->DrawBox(x1,y1, x2, y2);
      gr->DrawFCircle(xc,yc,rc);

      gr->SelGOMode(gmod);
      gr->SelLine(gline);
      gr->SelForeground(gcol);
    }
  }  
}



//------------------------------------------------------------
/* --Methode-- */
PIDrwMgrMenu::PIDrwMgrMenu(PIBaseWdgGen* bwdg, bool fgxor) 
  : PIMenu(bwdg, "PIDrwMgrMenu", k_PopupMenu)
{
  mBWdg = bwdg;
  mListDrw = NULL;
  mFgxor = fgxor;
  mEvH = NULL;
  mSEvH = NULL;

  if (bwdg == NULL) return;

  AppendItem("GraphicAttTools", 401);
  AppendItem("OptionStringWin", 402);
  AppendItem("ControlWin", 403);
  AppendItem("Move/ReSize", 404);
  AppendSeparator();
  AppendItem("Detach", 405);
  AppendItem("MouseSelect", 406);
  AppendItem("Refresh", 407);
  int aid = bwdg->GetActiveDrawerId();
  if (aid < 0) {
    for(int i=1; i<=6; i++)
      SetSensitivityMsg(400+i, false);
  }
  else {
    if ( !(bwdg->GetActiveDrawer()->HasSpecificControlWindow()) ) 
      SetSensitivityMsg(403, false);
    if ( bwdg->IsDrawerLockedId(aid)) 
      SetSensitivityMsg(405, false);
  }
  if (bwdg->NbDrawers() > 0) {
    AppendSeparator();
    mListDrw = new PIMenu(this, "SelActiveDrw", k_PulldownMenu);
    for(int k=0; k<bwdg->NbDrawers(); k++) {
      char buff[16];
      sprintf(buff, "%d- ", k);
      string mit = buff;
      mit += bwdg->GetDrawer(k)->Name();
      mListDrw->AppendItem(mit.c_str(), 1000+k);
      if (bwdg->GetDrawerIdFromNum(k) == aid)  
	mListDrw->SetSensitivityMsg(1000+k, false);
    }
    AppendPDMenu(mListDrw);
  }
//SUP  PIDrawer*  actdr = mBWdg->GetActiveDrawer();
//SUP  if (actdr)  actdr->HighLight(true);
}

/* --Methode-- */
PIDrwMgrMenu::~PIDrwMgrMenu() 
{
  if (mListDrw) delete mListDrw;
  if (mEvH) { 
    mEvH->CheckBeforeDelete();
    delete mEvH;
  }
  if (mSEvH) { 
    mSEvH->CheckBeforeDelete();
    delete mSEvH;
  }
}

/* --Methode-- */
void PIDrwMgrMenu::Process(PIMessage msg, PIMsgHandler* sender, void* data)
{  
  if (mBWdg == NULL) return;
  int aid = mBWdg->GetActiveDrawerId();
  PIDrawer* actdrw = mBWdg->GetActiveDrawer();
  PIMessage mod = ModMsg(msg);
  msg = UserMsg(msg);
  switch (msg) {
    case 401 :
      if (aid >= 0)  PIDrwTools::ShowPIDrwTools(mBWdg);
      break;
    case 402 :
      if (actdrw != NULL) { 
	PIDrwOptionStringWindow::ShowDrwOptionStringWindow(actdrw);
	actdrw->HighLight(false);
      }
      break;
    case 403 :
      if (actdrw != NULL) { 
	actdrw->ShowControlWindow(mBWdg);
      }
      break;
    case 404 :
      if (mEvH) { 
	mEvH->CheckBeforeDelete();	
	delete mEvH;
      }
      mEvH = new PIDrwPosSizeEvH(mBWdg, mFgxor);
      break;
    case 405 :
      if (aid >= 0) { 
	mBWdg->RemoveDrawer(aid);
	mBWdg->Refresh();
      }
      break;
    case 406 :
      if (mSEvH) { 
	mSEvH->CheckBeforeDelete();	
	delete mSEvH;
      }
      mSEvH = new PIDrwSelectEvH(mBWdg);
      break;
    case 407 :
      mBWdg->Refresh();
      break;
    default :
      if (actdrw != NULL) actdrw->HighLight(false);
      if (msg >= 1000)
	mBWdg->SetActiveDrawer(msg-1000);
      break;
  }

}
