#include "machdefs.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include <typeinfo>

#include <string>
#include <vector>

#include "strutil.h"
#include "timing.h"
#include "perrors.h"
#include "ctimer.h"

#include "psighand.h"

#include "cimage.h" // pour pouvoir faire extract 

#include "pistdimgapp.h"
#include "pihisto2d.h"
#include "psfile.h"
#include "piimgtools.h"
#include "pidrwtools.h"
#include "piaxestools.h"

#include "pistzwin.h"

#include "piinit.h"
#include "piversion.h"
#include "piaversion.h"


static char ImgDir[256];
static char WorkDir[256];
// Initialiseur
static PIAppInitiator * glst_piai = NULL; 

// Pour la creation de fenetre info (about piapp)
static void createInfoWindow(PIStdImgApp* app);
static void deleteInfoWindow();
static void showInfoWindow(PIStdImgApp* app);
static void hideInfoWindow(PIStdImgApp* app);

/* ........................................................... */
/*                    Classe PIStdImgApp                         */
/* ........................................................... */

/* --Methode-- */
PIStdImgApp::PIStdImgApp(int narg, char* arg[])
: PIApplication(420, 320, narg, arg)
{

// Les menus
m[0] = new PIMenu(Menubar(),"Fichier");
m[0]->AppendItem("About piapp", 10150);
m[0]->AppendItem("Open-Fits", 10120);
m[0]->AppendItem("Open-PPF", 10130);
// m[0]->AppendItem("Options", 10101);
m[0]->AppendItem("Help", 10100);
m[0]->AppendSeparator();
m[0]->AppendItem("Exit", 10105);

m[1] = new PIMenu(Menubar(),"Objets");
m[1]->AppendItem("ObjectManager", 10201);
m[1]->AppendItem("OpenOutPPF", 10220);
m[1]->AppendItem("CloseOutPPF", 10230);
m[1]->AppendItem("Delete CurWdg", 10270);

m[2] = new PIMenu(Menubar(),"Tools");
m[2]->AppendItem("Show ImageTools", 10301);
m[2]->AppendItem("Show DrawerTools", 10302);
m[2]->AppendItem("Show AxesTools", 10303);
m[2]->AppendItem("CxxExecutorWindow", 10304);
m[2]->AppendItem("Ext.Pave", 10311);
m[2]->SetSensitivityMsg(10311, false);
m[2]->AppendItem("Ext.Pave+Org", 10312);
m[2]->SetSensitivityMsg(10312, false);
m[2]->AppendItem("Cuts X,Y", 10313);
m[2]->SetSensitivityMsg(10313, false);
mc = new PIMenu(m[2], "StackTools");
mc->AppendItem("DispNext", 10320);
mc->AppendItem("Blink 0.5s", 10321);
mc->AppendItem("Blink 1s", 10322);
mc->AppendItem("Blink 2s", 10324);
mc->AppendItem("Stop Blink", 10329);
mc->AppendItem("RemoveCurrent", 10330);
m[2]->AppendPDMenu(mc);
m[2]->SetSensitivity("StackTools", false);

m[3] = new PIMenu(Menubar(),"Window");
m[3]->AppendItem("StackWindow", 10400);
m[3]->AppendItem("Window", 10411);
m[3]->AppendItem("Window 2x1", 10421);
m[3]->AppendItem("Window 1x2", 10412);
m[3]->AppendItem("Window 2x2", 10422);
m[3]->AppendItem("Window 3x1", 10431);
m[3]->AppendItem("Window 3x3", 10433);
m[3]->AppendItem("Cur->LastWdg", 10441);
m[3]->AppendItem("Close CurWin", 10460);

m[4] = new PIMenu(Menubar(),"PostScript");
m[4]->AppendItem("OpenPS", 10501);
m[4]->AppendItem("ClosePS", 10505);
m[4]->AppendItem("Window->PS", 10511);
m[4]->AppendItem("Image->PS", 10515);
m[4]->AppendItem("Window->EPS", 10512);
m[4]->AppendItem("Image->EPS", 10516);
m[4]->SetSensitivityMsg(10515, false);
m[4]->SetSensitivityMsg(10516, false);

m[5] = new PIMenu(Menubar(),"Special");
m[5]->AppendItem("CloseAll", 10601);
m[5]->AppendCheckItem("Red.Out/Err", 10602);
m[5]->AppendCheckItem("Catch SigFPE", 10603);
m[5]->AppendCheckItem("Catch SigSEGV", 10604);
m[5]->AppendCheckItem("ObjMgr Verb", 10605);
m[5]->AppendItem("CxxExecOption", 10606);

m[6] = new PIMenu(Menubar(),"Modules");

AppendMenu(m[0]);
AppendMenu(m[1]);
AppendMenu(m[2]);
AppendMenu(m[3]);
AppendMenu(m[4]);
AppendMenu(m[5]);
// AppendMenu(m[6]);  Menu Modules vide pour le moment 

int scsx, scsy;
ScreenSize(scsx, scsy);
if (scsy <= 600)  mFgScSz = 0;
else if (scsy <= 800)  mFgScSz = 1;
else if (scsy <= 1024)  mFgScSz = 2;
else   mFgScSz = 3;
int msx = 420+mFgScSz*60;
int msy = 320+mFgScSz*40;
MainWin()->SetSize(msx, msy);

int bss = 100+mFgScSz*15;
gimv = new PIPixmap(MainWin(), "GloV", bss, bss, 5, 5);
gimv->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_free, PIBK_free); 
zoom = new PIPixmap(MainWin(), "Zoom", bss, bss, bss+10, 5);
zoom->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_free, PIBK_free); 
cmapv = new PICMapView(MainWin(), "CMapView", msx-10, 14+mFgScSz*2, 5, bss+10); 
cmapv->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_fixed, PIBK_free); 

int cpy = bss+10+14+mFgScSz*2+5;

// Creation d'une console avec gestion des commandes  
mCons = new PIConsole(MainWin(), "Console", 30200, 512, 132, msx, msy-cpy, 0, cpy );
mCons->SetBinding(PIBK_fixed,PIBK_fixed,PIBK_fixed, PIBK_fixed); 
mCons->AcceptCmd(true, 50);
redirecout = false;
// RedirectStdOutErr(true);  pas par defaut 
 
mObjMgr = new NamedObjMgr;
mCmd = new PIACmd(mObjMgr, this);

// Pas trop de message de la part de NamedObjMgr
m[5]->SetStateMsg(10605, false);
mObjMgr->SetVerbose(false);

char* varenv;
ImgDir[0] = WorkDir[0] = '\0';
if ( (varenv=getenv("PEIDA_IMAGES")) != NULL )   strncpy(ImgDir, varenv, 256);
if ( (varenv=getenv("PEIDA_WORK")) != NULL )  strncpy(WorkDir, varenv, 256);

pfc_fits = new PIFileChooser(this,"FITS-FileChooser", 10125); 
pfc_ppf = new PIFileChooser(this,"PPF-FileChooser", 10135); 
pfc_ps = new PIFileChooser(this,"PS-FileChooser", 10525); 

mObjmgrw = new ObjMgrWind(this);
mPpinmgrw = new PPInMgrWind(this);

// Attention : A faire apres creation de ObjMgrWind !!! 
mObjMgr->SetImgApp(this);

// Gestion des feneteres widgets et drawers
mWId = mDId = mBWId = 0;
mCurWin = NULL;  
mCurWdg = NULL;
mLastWdg = NULL;
mGrW = NULL;
mStW = NULL;
mGrIdx = mStIdx = -1;

mFCMsg = 0;
mFgCWImg = false;

// Gestion fichiers PS
num_eps = 0;
name_ps = "";
name_ps = "pia.ps";
mpsfile = new PSFile(name_ps.c_str(),PI_Portrait, PI_A4, 2., 2.);

// Gestion OUT-PPF
mPpfout = NULL;
name_outppf = "";

// Attributs graphiques courants
mFCol = mBCol = PI_NotDefColor;
mLAtt = PI_NotDefLineAtt;
mFName = PI_DefaultFont;   
mFSz = PI_NotDefFontSize;
mFAtt = PI_NotDefFontAtt;
mMSz = -1;
mMrk = PI_NotDefMarker;
mCmapid = CMAP_OTHER;
mRevCmap = false; 
mZoom = 0;
mAxesFlags = kBoxAxes | kExtTicks | kLabels;
SetXYLimits(-1, 1., -1., 1.);
mFXYlim = false;
SetInsetLimits(0.4, 0.6, 0.4, 0.6);
SetImageCenterPosition(-1,-1);
mFImgCenter = false;
maXlog = maYlog = false;
mAddTitle = true;
SaveGraphicAtt();

// Initialisation 
glst_piai = new PIAppInitiator(this);

char buff[128];
mCons->AddStr("  ............  starting piapp .............\n", PIVA_Blue );
#ifdef SANS_EVOLPLANCK
sprintf(buff, "Version: piapp=%g  PI=%g  PEIDA=%g \n", (double)PIAPP_VERSIONNUMBER, 
              (double)PI_VERSIONNUMBER, (float)PeidaVersion());
#else
sprintf(buff, "Version: piapp=%g  PI=%g  SOPHYA=%g \n", (double)PIAPP_VERSIONNUMBER, 
              (double)PI_VERSIONNUMBER, glst_piai->Version());
#endif
mCons->AddStr(buff, PIVA_Blue );
mCons->AddStr("  ..........................................\n", PIVA_Blue );
// PrintPeidaVersion();

pfc_fits->SetPath(ImgDir);
pfc_ppf->SetPath(WorkDir);
pfc_ps->SetPath(WorkDir);

SetReady();
}

/* --Methode-- */
PIStdImgApp::~PIStdImgApp()
{
int i;

// On inactive la fenetre principale
//  Sinon, ca peut provoquer un SEGV ds delete de console ?? - Reza 07/2000
MainWin()->Hide();  

// Destrucion de tous les objets de NameObjMgr
string patt = "/*/*";
mObjMgr->DelObjects(patt, true);

delete mc;
for(i=0; i<7; i++)  
  if (m[i]) delete m[i];

WindMList::iterator it;
for(it = mWList.begin(); it != mWList.end(); it++)  delete (*it).second;

delete mObjMgr;
delete mCmd;

delete zoom;
delete gimv;
delete cmapv;

delete pfc_fits;
delete pfc_ppf;
delete pfc_ps;

delete mCons;

delete mObjmgrw;
delete mPpinmgrw;

deleteInfoWindow();

// Les fichiers 
if (mpsfile) delete mpsfile;
if (mPpfout) delete mPpfout;

if (glst_piai) delete glst_piai;   glst_piai = NULL;
}  

/* --Methode-- */
void PIStdImgApp::Process(PIMessage msg, PIMsgHandler* sender, void* data)
{
PIWdg *sndw;
PIMessage tmsg, smm;

tmsg = msg;
msg = UserMsg(msg);
smm = ModMsg(tmsg);

//printf("SuperDebug: msg=%d Mod=%d  State=%d\n", (int)msg, (int)smm, (int)GetState());
if  ((GetState()) && (msg != mFCMsg)) { PIBeep(); return; }

//   Messages active-window
if (smm == PIMsg_Active)
  {
  sndw = dynamic_cast<PIWdg *>(sender);
  switch(sndw->kind())
    {
    case PIWindow::ClassId :
      mCurWin = dynamic_cast<PIWindow *>(sndw);
      break;

    case PIScDrawWdg::ClassId :
    case PIDraw3DWdg::ClassId :
      mCurWdg = dynamic_cast<PIBaseWdg *>(sender);
//      cerr << "*DBG11* ImgTools -> NonSensitive " << sndw->kind() << endl;
      if (mFgCWImg) {
//        cerr << "*DBG* ImgTools -> NonSensitive " << endl;
        m[2]->SetSensitivityMsg(10311, false);
        m[2]->SetSensitivityMsg(10312, false);
        m[2]->SetSensitivityMsg(10313, false);
        m[4]->SetSensitivityMsg(10515, false);
        m[4]->SetSensitivityMsg(10516, false);
        mFgCWImg = false;
        }
      break;
    case PIImage::ClassId :
      mCurWdg = dynamic_cast<PIBaseWdg *>(sender);
      if (!mFgCWImg) {
//        cerr << "*DBG* ImgTools -> Sensitive " << endl;
        m[2]->SetSensitivityMsg(10311, true);
        m[2]->SetSensitivityMsg(10312, true);
        m[2]->SetSensitivityMsg(10313, true);
        m[4]->SetSensitivityMsg(10515, true);
        m[4]->SetSensitivityMsg(10516, true);
        mFgCWImg = true;
        }
      break;
      /*
    default :
      mCurWdg = NULL;
      if (mFgCWImg) {
        m[2]->SetSensitivityMsg(10311, false);
        m[2]->SetSensitivityMsg(10312, false);
        m[2]->SetSensitivityMsg(10313, false);
        m[4]->SetSensitivityMsg(10515, false);
        m[4]->SetSensitivityMsg(10516, false);
        mFgCWImg = false;
        }
      break;
      */
    }
  }
//  Message window-close
else if (smm == PIMsg_Close)
  {
  sndw = (PIWdg *)sender;
  if(sndw->kind() == PIWindow::ClassId)
    {
    mCurWin = (PIWindow *)sender;
    if (mCurWin == mStW) m[2]->SetSensitivity("StackTools", false); 
    DeleteWindow(mCurWin);
    }
  else  
    printf("PIStdImgApp/Bug ? CloseMsd received from NonWindow (%d %d %lx) \n",
           (int)tmsg,  (int)sndw->kind(), (long)sender);       
  }

// Traitement des messages des menus 
else if ( (msg >= 10100) && (msg < 10200) )  MBProcess1(msg, sender, data);
else if ( (msg >= 10200) && (msg < 10300) )  MBProcess2(msg, sender, data);
else if ( (msg >= 10300) && (msg < 10400) )  MBProcess3(msg, sender, data);
else if ( (msg >= 10400) && (msg < 10500) )  MBProcess4(msg, sender, data);
else if ( (msg >= 10500) && (msg < 10600) )  MBProcess5(msg, sender, data);
else if ( (msg >= 10600) && (msg < 10700) )  MBProcess6(msg, sender, data);
else if ( msg == 30200  ) {    // Objet PIConsole 
  string s = mCons->GetCmdString();
  //  string s2 = "\nExecuting " + s + "\n";
  mCons->AddStr("Cmd> ", PIVA_Blue, false);
  //  s2 = s + "\n";
  mCons->AddStr(s.c_str(), PIVA_Blue|PIVA_Bold, false);
  mCons->AddChar('\n', PIVA_Def, true);
  SetBusy();
#ifdef SANS_EVOLPLANCK
  TRY {
    mCmd->Interpret(s);
    }  CATCH(merr) { 
    fflush(stdout); 
    cout << endl; 
    cerr << endl;
    string es = PeidaExc(merr);
    cerr << "PIStdImgApp::Process()/ Cmd->Do() Exception :" << es << " (" << merr << ")" << endl ;
    }
#else
  try {
    mCmd->Interpret(s);
    }  
  catch ( PThrowable & exc ) {
    cerr << "\n PIStdImgApp::Process()/ Cmd->Interpret() Exception :" 
	 << (string)typeid(exc).name() << " Msg= " 
	 << exc.Msg() << endl;
    cout << endl; 
  }
  catch ( ... ) {
    cerr << "\n PIStdImgApp::Process()/ Cmd->Interpret() Catched Exception ..." 
	 << endl;
    cout << endl; 
  }

#endif
  SetReady();
  }

else printf("PIStdImgApp::Process() BUG?? Msg %d (%d-%d) \n", 
            (int)tmsg,(int)msg,(int)smm);


return;
}

/* --Methode-- */
void PIStdImgApp::SetReady()
{
mCons->SetSensitive();
gimv->SetSensitive();
PIApplication::SetReady();
}

/* --Methode-- */
void PIStdImgApp::SetBusy()
{
mCons->SetUnSensitive();
gimv->SetUnSensitive();
PIApplication::SetBusy();
// Attention : Appel XSync specifique X11 -  en attendant multi-thread
XSync(PIXDisplay(), False);  
}

/* --Methode-- */
void PIStdImgApp::SetBlocked()
{
mCons->SetUnSensitive();
gimv->SetUnSensitive();
PIApplication::SetBlocked();
// Attention : Appel XSync specifique X11 -  en attendant multi-thread
XSync(PIXDisplay(), False);  
}


/* --Methode-- */
int PIStdImgApp::DispImage(P2DArrayAdapter* nouv, string const & name, int opt, int oid)
{
PIImage* pii;
PIWindow* win;
int sx, sy, px, py, flag;

if (nouv == NULL)
  {
  printf("PIStdImgApp::DispImage_Error  Cannot Display  NULL image \n");
  return(-1);
  }

if ( (nouv->XSize() <= 0)  || (nouv->YSize() <= 0))
  {
  printf("PIStdImgApp::DispImage_Error Pb Size Sz=%d*%d  \n", 
          nouv->XSize(), nouv->YSize());
  return(-1);
  }

int zm = 1;
if (mZoom == 0) {  // Facteur de zoom auto 
  zm = (nouv->XSize() > nouv->YSize()) ? nouv->XSize() :  nouv->YSize();
  zm = (zm >= 250) ? 250/zm : 1;
  }
else zm = mZoom;

if (zm == 0)  zm = 1;
if (zm < -10)  zm = -10; 
if (zm > 10)  zm = 10;

if (zm > 0)  { sx = nouv->XSize()*zm;  sy = nouv->YSize()*zm; }
else  { 
  sx = (int)((float)nouv->XSize()*(-1./float(zm)));  
  sy = (int)((float)nouv->YSize()*(-1./float(zm))); 
  } 
if (sx > 400+mFgScSz*100) sx = 400+mFgScSz*100;
if (sy > 400+mFgScSz*100) sy = 400+mFgScSz*100;
px = py = 0;
win = GetWindow(opt, sx, sy, px, py, flag, (char *)name.c_str());
pii = new PIImage(win, (char *)name.c_str(), sx, sy, px,py);
pii->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
pii->SetZoomWin(zoom, false);
pii->SetGloVWin(gimv, false);
pii->SetCMapWin(cmapv, false);
pii->SetZoom(zm, false);
if ( mCmapid != CMAP_OTHER ) pii->SetColMapId(mCmapid, mRevCmap, false);
pii->ShowCursor(true);
pii->SetUserData(NULL, oid);
// Centrage eventuel du pave
if (mFImgCenter && (mXImgCenter > 0) && (mYImgCenter > 0)) {
  pii->SetImage(nouv, false);
  pii->SetPave(mXImgCenter, mYImgCenter, true, true);
  }
else pii->SetImage(nouv, true);
// printf("!!DBG!! PIImage Pos= %d %d  Size= %d %d \n", pii->XPos(), pii->YPos(), pii->XSize(), pii->YSize()   );
mCurWin = win;
mCurWdg = pii;
mLastWdg = pii;
mBWId++;
mBWList[mBWId] = pii;
return(mBWId); 
}


/* --Methode-- */
int PIStdImgApp::DispScDrawer(PIDrawer* scd, string const & name, int opt, string title, int oid)
{
if (scd == NULL)
  {
  printf("PIStdImgApp::DispScDrawer_Error  Cannot Add NULL ScDrawer \n");
  return(-1);
  }

// Changement d'attributs graphiques courants du drawer
if (mFCol != PI_NotDefColor) scd->SetColAtt(mFCol, mBCol);
if (mLAtt != PI_NotDefLineAtt) scd->SetLineAtt(mLAtt);
if ( (mFSz != PI_NotDefFontSize) && (mFAtt != PI_NotDefFontAtt) ) scd->SetFontAtt(mFSz, mFAtt); 
if ( mFName != PI_DefaultFont ) scd->SetFont(mFName, scd->GetFontSz(), scd->GetFontAtt());
if ( (mMrk != PI_NotDefMarker) && (mMSz >= 0) ) scd->SetMarkerAtt(mMSz, mMrk);
if ( mCmapid != CMAP_OTHER ) scd->SetColMapId(mCmapid);


if ( (!mLastWdg) && ( (opt == Disp_Same) || (opt == Disp_Inset) ) )  opt = Disp_Next;
// Trace en superpoistion
if ( (opt == Disp_Same) && (mLastWdg) ) {  
  if (mLastWdg->kind() == PIScDrawWdg::ClassId)  ((PIScDrawWdg*)mLastWdg)->AddScDrawer(scd, true);
  else mLastWdg->AddDrawer(scd, true, true, true);
  scd->Refresh(); 
  mDId++;
  mDrwList[mDId] = scd;
  return(-mDId);   
}
// Trace en medaillon
else if ( (opt == Disp_Inset) && (mLastWdg) ) {
  PIGrCoord x1, x2, y1, y2;
  x1 = mIXmin;  x2 = mIXmax;
  y2 = 1.-mIYmin;  y1 = 1.-mIYmax;
  scd->SetAxesFlags(mAxesFlags);
  if (maXlog || maYlog)  scd->SetLogScale(maXlog, maYlog);  // Echelle log
  if (mFXYlim)  // Forcage limites XY 
    scd->SetLimits(mXmin, mXmax, mYmin, mYmax);  
  else scd->UpdateLimits();
  mLastWdg->AddDrawer(scd, x1, y1, x2, y2, true, false, true);
  scd->Refresh();
  mDId++;
  mDrwList[mDId] = scd;
  return(-mDId);   
}

PIWindow* win;
PIScDrawWdg* scw;
int sx, sy, px, py, flag;
sx = 200+mFgScSz*100;
sy = 200+mFgScSz*100;
win = GetWindow(opt, sx, sy, px, py, flag, (char *)name.c_str());
if (typeid(*scd) != typeid(PIHisto2D)) 
   scw = new PIScDrawWdg(win, (char *)name.c_str(), sx, sy, px, py);
else scw = new PIH2DWdg(win, (char *)name.c_str(), sx, sy, px, py);
scw->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
scw->SetUserData(NULL, oid);
if (maXlog || maYlog)  scw->SetLogScale(maXlog, maYlog);  // Echelle log
if (mFXYlim)  // Forcage limites XY 
  scw->SetLimits(mXmin, mXmax, mYmin, mYmax);
scw->SetAxesFlags(mAxesFlags);
// Fonte de trace d'axe
scw->BaseDrawer()->SetFont(mFName, mFSz, mFAtt);

if (typeid(*scd) != typeid(PIHisto2D)) scw->AddScDrawer(scd, true);
else ((PIH2DWdg*)scw)->SetPIHisto((PIHisto2D*)scd);
//   Titre du plot
if (mAddTitle) {
  if (title.length() <= 0)  title = name;  string t2="";   
  scw->SetTitles(title, t2);    
}

// scw->Refresh();   ? Pas necessaire  Reza 19/08/98, 05/05/99 $CHECK$ 
mCurWin = win;
mCurWdg = scw;
mLastWdg = scw;
mBWId++;
mBWList[mBWId] = scw;
return(mBWId); 
}

/* --Methode-- */
int PIStdImgApp::Disp3DDrawer(PIDrawer3D* dr3, string const & name, int opt, string title, int oid)
{
if (dr3 == NULL)
  {
  printf("PIStdImgApp::Disp3DDrawer_Error  Cannot Add NULL 3DDrawer \n");
  return(-1);
  }

// Changement d'attributs graphiques courants du drawer
if (mFCol != PI_NotDefColor) dr3->SetColAtt(mFCol, mBCol);
if (mLAtt != PI_NotDefLineAtt) dr3->SetLineAtt(mLAtt);
if ( (mFSz != PI_NotDefFontSize) && (mFAtt != PI_NotDefFontAtt) ) dr3->SetFontAtt(mFSz, mFAtt); 
if ( mFName != PI_DefaultFont ) dr3->SetFont(mFName, dr3->GetFontSz(), dr3->GetFontAtt());
if ( (mMrk != PI_NotDefMarker) && (mMSz >= 0) ) dr3->SetMarkerAtt(mMSz, mMrk);
if ( mCmapid != CMAP_OTHER ) dr3->SetColMapId(mCmapid);

if ( (!mLastWdg) && ( (opt == Disp_Same) || (opt == Disp_Inset) ) )  opt = Disp_Next;
// Trace en superpoistion
if ( (opt == Disp_Same) && (mLastWdg) ) {
  if (mLastWdg->kind() == PIDraw3DWdg::ClassId)  ((PIDraw3DWdg*)mLastWdg)->AddDrawer3D(dr3, true);
  else mLastWdg->AddDrawer(dr3, true, true, true);
  dr3->Refresh();
  mDId++;
  mDrwList[mDId] = dr3;
  return(-mDId);   
}
// Trace en medaillon
else if ( (opt == Disp_Inset) && (mLastWdg) ) {
  PIGrCoord x1, x2, y1, y2;
  x1 = mIXmin;  x2 = mIXmax;
  y2 = 1.-mIYmin;  y1 = 1.-mIYmax;
  dr3->SetAxesFlags(mAxesFlags);
  dr3->UpdateLimits();
  mLastWdg->AddDrawer(dr3, x1, y1, x2, y2, true, false, true);
  dr3->Refresh();
  mDId++;
  mDrwList[mDId] = dr3;
  return(-mDId);   
}


PIWindow* win;
int sx, sy, px, py, flag;
sx = 200+mFgScSz*100;
sy = 200+mFgScSz*100;
win = GetWindow(opt, sx, sy, px, py, flag, (char *)name.c_str());
PIDraw3DWdg* wd3 = new PIDraw3DWdg(win, (char *)name.c_str(), sx, sy, px, py);
wd3->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic, PIBK_elastic);
wd3->SetUserData(NULL, oid);
wd3->AddDrawer3D(dr3, true);
//   Titre du plot
if (mAddTitle) {
  if (title.length() <= 0)  title = name;  string t2="";   
  wd3->SetTitles(title, t2);    
}
// wd3->Refresh();   ?Pas necessaire   $CHECK$ 05/05/99
mCurWin = win;
mCurWdg = wd3;
mLastWdg = wd3;
mBWId++;
mBWList[mBWId] = wd3;
return(mBWId); 
}

/* --Methode-- */
void PIStdImgApp::AddText(string const & txt, double xp, double yp)
{
PIElDrawer *eld=CurrentElDrawer();
if (eld == NULL) return;

if ( (mFSz != PI_NotDefFontSize) && (mFAtt != PI_NotDefFontAtt) ) 
  eld->SetFontAtt(mFSz, mFAtt); 
if ( mFName != PI_DefaultFont ) 
  eld->SetFont(mFName, eld->GetFontSz(), eld->GetFontAtt());
eld->ElAddText(xp,yp,txt.c_str(),mFCol);
eld->Refresh();
}

/* --Methode-- */
void PIStdImgApp::AddLine(double xp1, double yp1, double xp2, double yp2)
{
PIElDrawer *eld=CurrentElDrawer();
if (eld == NULL) return;

eld->ElAddLine(xp1, yp1, xp2, yp2, mFCol);
eld->Refresh();
}

/* --Methode-- */
void PIStdImgApp::AddRectangle(double xp1, double yp1, double xp2, double yp2, bool fgfill)
{
PIElDrawer *eld=CurrentElDrawer();
if (eld == NULL) return;

double xp,yp;
double dx, dy;
if (xp1 < xp2) {
  xp = xp1; dx = xp2-xp1;
}
else {
  xp = xp2; dx = xp1-xp2;
}
if (yp1 < yp2) {
  yp = yp1; dy = yp2-yp1;
}
else {
  yp = yp2; dy = yp1-yp2;
}
if (fgfill) eld->ElAddFRect(xp, yp, dx, dy, mFCol);
else eld->ElAddRect(xp, yp, dx, dy, mFCol);
eld->Refresh();
}

/* --Methode-- */
void PIStdImgApp::AddCircle(double xc, double yc, double r, bool fgfill)
{
PIElDrawer *eld=CurrentElDrawer();
if (eld == NULL) return;

if (fgfill) eld->ElAddFCirc(xc, yc, r, mFCol);
else eld->ElAddCirc(xc, yc, r, mFCol);
eld->Refresh();
}

/* --Methode-- */
void PIStdImgApp::SetTitle(string const & titletop, string const & titlebottom)
{
PIElDrawer *eld=CurrentElDrawer();
if (eld == NULL) return;

if ( (mFSz != PI_NotDefFontSize) && (mFAtt != PI_NotDefFontAtt) ) 
  eld->SetFontAtt(mFSz, mFAtt); 
if ( mFName != PI_DefaultFont ) 
  eld->SetFont(mFName, eld->GetFontSz(), eld->GetFontAtt());
eld->SetTitles(titletop, titlebottom);
eld->Refresh();
}

/* --Methode-- */
PIElDrawer* PIStdImgApp::CurrentElDrawer()
{
PIElDrawer *eld=NULL;
if (!mLastWdg)  return(eld);
PIScDrawWdg* sdw=NULL;
PIDraw3DWdg* w3d=NULL;
PIImage* imgw;
switch(mLastWdg->kind()) {
  case PIScDrawWdg::ClassId :
    sdw = dynamic_cast<PIScDrawWdg *>(mLastWdg);
    if (sdw) eld = sdw->BaseDrawer();
    break;
  case PIDraw3DWdg::ClassId :
    w3d = dynamic_cast<PIDraw3DWdg *>(mLastWdg);
    if (w3d) eld = w3d->BaseDrawer();
    break;
  case PIImage::ClassId :
    imgw = dynamic_cast<PIImage *>(mLastWdg);
    if (imgw) eld = imgw->BaseDrawer();
    break;
  default :
    break;
  }
return(eld);
}

/* --Methode-- */
void PIStdImgApp::CreateGraphWin(int nx, int ny, int sx, int sy)
{
if (nx < 1)  nx = 1;
if (ny < 1)  ny = 1;
if (nx > 8)  nx = 8;    
if (ny > 8)  ny = 8;
if ( (sx < 50) && (sy < 50) )   sx = sy = 400+mFgScSz*100; 
char buff[64];
mWId++;
int px, py; 
MainWin()->GetScreenPos(px, py);
sprintf(buff, "PI-GraphicWin (%d)",mWId);
PIZoneWindow* win = new PIZoneWindow(this,  buff, PIWK_normal, nx, ny, sx, sy, px+MainWin()->XSize()+30, 0);
win->SetUserData(NULL, ny*10+nx);  // UserFlag= nY*10 + nX  
mWList[mWId*10+1] = (PIWindow*)win;
win->SetAutoDelChilds(true);
// win->Show();
mGrW = win; 
mGrIdx = 0;
}

/* --Methode-- */
void PIStdImgApp::CreateStackWin(int sx, int sy)
{
if ( (sx < 50) && (sy < 50) )   sx = sy = 300+mFgScSz*100; 
char buff[64];
mWId++;
int px, py; 
MainWin()->GetScreenPos(px, py);
sprintf(buff, "PI-StackWin (%d)",mWId); 
PIStackWindow* win = new PIStackWindow(this,  buff, PIWK_normal, sx, sy, px+MainWin()->XSize()+30, 100);
win->SetUserData(NULL, 9999);  // UserFlag= 9999 
mWList[mWId*10+2] = (PIWindow*)win;
win->SetAutoDelChilds(true);
// win->Show();
mStW = win;
m[2]->SetSensitivity("StackTools", true); 
mStIdx = 0;
}

/* --Methode-- */
PIWindow* PIStdImgApp::GetWindow(int typ, int& sx, int& sy, int& px, int& py, int& flag, char * nom)
{
PIWindow* rw;

switch (typ) {
  case Disp_Next :  // Fenetre graphique courante
    {
    if (mGrW == NULL) CreateGraphWin();
    int nx, ny;
    mGrW->NbZone(nx, ny);
    PIWdg* nw = mGrW->NextChildPosSize(px, py, sx, sy);
//    cerr << "**DBG** PIStdImgApp::GetWindow() DispNext : nw = " << (long)nw << endl;
    if (nw) DeleteBaseWidget((PIBaseWdg*)nw, false, false);
    flag = mGrIdx;
    mGrIdx = (mGrIdx+1)%(nx*ny);
    rw = mGrW;
    break;
    }

  case Disp_Stack :  // Fenetre de type stack (empilement)
    {
    if (mStW == NULL) CreateStackWin(sx, sy);
    px = py = 0;
    sx = mStW->XSize();
    sy = mStW->YSize();
    flag = mStIdx;
    mStIdx++;
    rw = mStW;
    }
    break;

  default :      // Fenetre ordinaire
    {
    int pwx, pwy; 
    MainWin()->GetScreenPos(pwx, pwy);
    if ( (sx < 50) && (sy < 50) )   sx = sy = 300+mFgScSz*100; 
    rw = new PIWindow(this,  nom, PIWK_normal, sx, sy, pwx+MainWin()->XSize()+30, 300);
    rw->SetUserData(NULL, 0);  // UserFlag= 0 
    mWId++;
    mWList[mWId*10] = rw;
    rw->SetAutoDelChilds(true);
    //    rw->Show();
    px = py = 0;
    flag = 0;
    break;
    }
  }

rw->Show();
mCurWin = rw;
return(rw);
}

/* --Methode-- */
void PIStdImgApp::SetZone(int nzx, int nzy)
{
if (!mGrW) CreateGraphWin(nzx, nzy);
else { 
  int k;
  PIWdg* cwd;
  for(k=0; k<mGrW->NbChilds(); k++) {
    if ((cwd = mGrW->GetChild(k)) == NULL)  continue; 
    DeleteBaseWidget((PIBaseWdg*)cwd, false, false);
    }
  mGrW->SetZone(nzx, nzy);
  }
}

/* --Methode-- */
void PIStdImgApp::StackWinNext()
{
if (mStW)  mStW->DispNext();
}

/* --Methode-- */
void PIStdImgApp::DeleteWindow(PIWindow* w)
{
if (w == NULL)  return;
w->Hide();
bool ownwindow=false;  // To Check if this is one of our windows
WindMList::iterator it;
for(it = mWList.begin(); it != mWList.end(); it++) 
  if ((*it).second == w)  { mWList.erase(it);  ownwindow = true; break; }
if (w == mGrW) { mGrW = NULL;  mGrIdx = -1; }
if (w == mStW) { mStW = NULL;  mStIdx = -1; m[2]->SetSensitivity("StackTools", false); }
if (w == mCurWin) mCurWin = NULL;

if (!ownwindow) return; // We do nothing if this is not a window we have created ...

int k;
PIWdg* cwd;
for(k=0; k<w->NbChilds(); k++) {
  if ((cwd = w->GetChild(k)) == NULL)  continue; 
  DeleteBaseWidget((PIBaseWdg*)cwd,false,false);
  }
delete w;
return;
}

/* --Methode-- */
void PIStdImgApp::DeleteBaseWidget(PIBaseWdg* w, bool dw, bool dwin)
{
if (w == NULL)  return;
BWMList::iterator it;
for(it = mBWList.begin(); it != mBWList.end(); it++) 
  if ((*it).second == w)  { mBWList.erase(it);  break; }
int k;
PIDrawer* drw;
for(k=0; k<w->NbDrawers(); k++) {
  if ((drw = w->GetDrawer(k)) == NULL)  continue; 
  DrwMList::iterator itt;
  for(itt = mDrwList.begin(); itt != mDrwList.end(); itt++) 
    if ((*itt).second == drw)  { mDrwList.erase(itt);  break; }
  }

if (w == mCurWdg) {  
  mCurWdg = NULL;
  if (mFgCWImg) {
    m[4]->SetSensitivityMsg(10515, false);
    m[4]->SetSensitivityMsg(10516, false);
    mFgCWImg = false;
    }
  }

if (w == mLastWdg)  mLastWdg = NULL;

PIWdg* pw=NULL;
if (dwin)  pw = (PIWdg*)(w->Parent());
//DBG printf("DeleteBaseWidget(%lx)-DBG kind = %d - %d %d \n", (long)w, w->kind(), (int)dw, (int)dwin); 
if (dw) delete w;
if (pw && (pw->kind() == PIWindow::ClassId )) {
 PIWindow* pww = (PIWindow*) pw;
 if ((pww != (PIWindow*)mGrW) && (pww != (PIWindow*)mStW) && (pww->NbChilds()==0)) 
    DeleteWindow((PIWindow*)pw);
 } 
return;
}



/* --Methode-- */
void PIStdImgApp::DelWRsId(int k)
{
//DBG cerr << "-DBG- PIStdImgApp::DelWRsId(" << k << ")" << endl; 
if (k > 0) { // C'est un BaseWidget
  BWMList::iterator it;
  it  = mBWList.find(k);
  if (it == mBWList.end())  return;
  PIBaseWdg* wd = (*it).second;
//DBG cerr << "-DBG- PIStdImgApp::DelWRsId Deleting BaseWidget " << (long)(wd) << endl ; 
  DeleteBaseWidget(wd, true, true);
  }
else {  // C'est un drawer
  DrwMList::iterator it;
  it  = mDrwList.find(-k);
  if (it == mDrwList.end())  return;
  delete (*it).second;  
  mDrwList.erase(it);
//  cerr << "+DBG+ PIStdImgApp::DelWRsId Deleting Drawer " << (long)((*it).second) << endl ; 
  }
}
/* --Methode-- */
bool PIStdImgApp::CheckWRsId(int k)
{
if (k > 0) { // C'est un BaseWidget
  BWMList::iterator it;
  it  = mBWList.find(k);
  if (it == mBWList.end())  return(false);
  else return(true);
  }
else {  // C'est un drawer
  DrwMList::iterator it;
  it  = mDrwList.find(-k);
  if (it == mDrwList.end())  return(false);
  else return(true);
  }
}


/* --Methode-- */
void PIStdImgApp::RedirectStdOutErr(bool fg)
{
if (fg) { 
  RedirectOutStream(mCons);
  RedirectErrStream(mCons);
  m[5]->SetStateMsg(10602, true);
  redirecout = true;
  }
else {
  RedirectOutStream(NULL);
  RedirectErrStream(NULL);
  m[5]->SetStateMsg(10602, false);
  redirecout = false;
  }
return;
}

/* --Methode-- */
void PIStdImgApp::CatchSignals(bool fgfpe, bool fgsegv)
{    
#ifdef SANS_EVOLPLANCK
PeidaConfigureSignalhandling(fgfpe, fgsegv, true, true);  
#else
SophyaConfigureSignalhandling(fgfpe, fgsegv, true, true);  
#endif
m[5]->SetStateMsg(10603, fgfpe);
m[5]->SetStateMsg(10604, fgsegv);
}

/* --Methode-- */
void PIStdImgApp::CloseAllWindows()
{
WindMList::iterator it;
for(it = mWList.begin(); it != mWList.end(); it++)   delete (*it).second;
mWList.clear();
mBWList.clear();
mDrwList.clear(); 
mGrW = NULL;
mStW = NULL;
mCurWin = NULL;
mCurWdg = NULL;
mLastWdg = NULL;
m[4]->SetSensitivityMsg(10515, false);
m[4]->SetSensitivityMsg(10516, false);
}

/* --Methode-- */
void PIStdImgApp::MBProcess1(PIMessage msg, PIMsgHandler* /*sender*/, void* data)
{

  switch(msg)
    {
    case 10150 :
      showInfoWindow(this);
      break;

    case 10155 :
      hideInfoWindow(this);
      break;

    case 10100 :
      mCmd->ShowHelpWindow();
      break;

    case 10120 :
      pfc_fits->AcceptNewFile(false);
      mFCMsg = 10125; 
      pfc_fits->SetMsg(mFCMsg);
      SetBlocked();
      pfc_fits->Show();
      break;

    case 10125 :
      SetBusy();
      if (data)  { 
        string nomobj="";
        ObjMgr()->ReadFits(pfc_fits->GetFileName(), nomobj);
        ObjMgr()->DisplayObj(nomobj, "win");
      }
      mFCMsg = 0;
      SetReady();
      break;

    case 10130 :
      pfc_ppf->AcceptNewFile(false); 
      mFCMsg = 10135; 
      pfc_ppf->SetMsg(mFCMsg);
      SetBlocked();
      pfc_ppf->Show();
      break;

    case 10135 :
      mFCMsg = 0;
      if (data)  { 
        PPInMgrW()->SetFile(pfc_ppf->GetFileName());
        PPInMgrW()->Show();
      }
      SetReady();
      break;
        
    case 10105:
      Stop();
      break;

  }
return;
}



/* --Methode-- */
void PIStdImgApp::MBProcess2(PIMessage msg, PIMsgHandler* /*sender*/, void* data)
{

switch (msg)  { 
  case 10201 :
     ObjMgrW()->Show();
     break;

  case 10220 :
     pfc_ppf->AcceptNewFile(true);
     mFCMsg = 10225;
     pfc_ppf->SetMsg(mFCMsg);
     SetBlocked();
     pfc_ppf->Show();
     break;

   case 10225 :
     SetBusy();
     if (data) {
       if (mPpfout) {  
         printf("PIStdImg/Info: Closing POutPersist-File %s \n", name_outppf.c_str());
         delete mPpfout;  
       }
       name_outppf = pfc_ppf->GetFileName();
       mPpfout = NULL;
       printf("PIStdImg/Info: Opening POutPersist-File %s \n", name_outppf.c_str());
       mPpfout = new POutPersist(name_outppf);
    }
    mFCMsg = 0;
    SetReady();
    break;

  case 10230 :
    if (!mPpfout)  break;
    printf("PIStdImg/Info: Closing POutPersist-File %s \n", name_outppf.c_str());
    delete mPpfout;  
    name_outppf = "";
    mPpfout = NULL;
    break;

  case 10270 :
    if (mCurWdg) {
      int oid = mCurWdg->UserFlag();
      DeleteBaseWidget(mCurWdg);
      mObjMgr->DelObj_Id(oid);
      }
    break;

  default:
    cerr << "PIStdImgApp::MBProcess2() BUG?? Msg= " <<  msg << endl;    
    break;
}

return;
}

/* --Methode-- */
void PIStdImgApp::MBProcess3(PIMessage msg, PIMsgHandler* /*sender*/, void* /*data*/)
{

switch (msg)  { 
  case 10301 :
    PIImgTools::ShowPIImgTools();
    break; 
  case 10302 :
    PIDrwTools::ShowPIDrwTools();
    break;
  case 10303 :
    PIAxesTools::ShowPIAxesTools();
    break;

  case 10304 :
    mCmd->ShowCxxExecWindow();
    break;

  case 10311 :
  case 10312 :
    {
    PIImage* curpimg = NULL;
    if (!mCurWdg)  return;
    if (mCurWdg->kind() != PIImage::ClassId)  return;
    curpimg = (PIImage*)mCurWdg;
    if (curpimg == NULL)   return;
    P2DArrayAdapter* img = curpimg->Image();
    if (img == NULL) return;
    int dx = curpimg->XSzPave();
    int dy = curpimg->YSzPave();  
    int x0 = curpimg->XPave()-dx/2;
    int y0 = curpimg->YPave()-dy/2;
    if (x0 < 0)  x0 = 0;
    if (y0 < 0)  y0 = 0;
    int x1 = x0+dx;
    int y1 = y0+dy;
    if (x1 > img->XSize()) x1 = img->XSize();
    if (y1 > img->YSize()) y1 = img->YSize();
    dx = x1-x0;  dy = y1-y0;
    ImageR4* pim = new ImageR4(dx, dy); 
    int ii, jj;
    for(jj=0; jj<dy; jj++) 
      for(ii=0; ii<dx; ii++) (*pim)(ii,jj) = (*img)(ii+x0, jj+y0);
    if (msg == 10305) {  // Calcul des coordonnees du sous-pave
      double xc1, yc1;
      img->Coord(x0, y0, xc1, yc1);
      pim->SetOrg((int)xc1, (int)yc1);
    }
    string nom = mCurWdg->Nom() + "_pave";
    ObjMgr()->AddObj(pim, nom);
    ObjMgr()->DisplayObj(nom, "w");
    break;
    }

  case 10313 :
    {
    PIImage* curpimg = NULL;
    if (!mCurWdg)  return;
    if (mCurWdg->kind() != PIImage::ClassId)  return;
    curpimg = (PIImage*)mCurWdg;
    if (curpimg == NULL)   return;
    curpimg->ShowCuts(true);
    break;
    }

  case 10320 :
    if (mStW)  mStW->DispNext();
    break;

  case 10321 :
  case 10322 :
  case 10324 :
//  case 10328 :
    if (mStW) mStW->StartAutoDisp((msg-10320)*500);
    break;

  case 10329 :
    if (mStW) mStW->StopAutoDisp();
    break;

  case 103330 :
    if (mStW) {
      PIWdg* cw =  mStW->CurrentWdg();
      if (cw) DeleteBaseWidget((PIBaseWdg*)cw);
      }
    break;

  default:
    cerr << "PIStdImgApp::MBProcess3() BUG?? Msg= " <<  msg << endl;    
    break;
  }
return;
}

/* --Methode-- */
void PIStdImgApp::MBProcess4(PIMessage msg, PIMsgHandler* /*sender*/, void* /*data*/)
{

switch (msg)  { 

  case 10400 :
    CreateStackWin();
    break;

  case 10411 :
    CreateGraphWin(1,1);
    break;
  case 10421 :
    CreateGraphWin(1,2);
    break;
  case 10412 :
    CreateGraphWin(2,1);
    break;
  case 10422 :
    CreateGraphWin(2,2);
    break;
  case 10431 :
    CreateGraphWin(1,3);
    break;
  case 10433 :
    CreateGraphWin(3,3);
    break;
  case 10441 :
    if (mCurWdg)  { 
      mLastWdg = mCurWdg;
      cout << " Using current widget as last-widget (display same) " << endl;
      }
    else  cout << " No current widget - select widget with mouse " << endl;
    break;
    case 10460 :
      DeleteWindow(mCurWin);
      break;
  default:
    cerr << "PIStdImgApp::MBProcess4() BUG?? Msg= " <<  msg << endl;    
    break;
  }
return;
}


/* --Methode-- */
void PIStdImgApp::MBProcess5(PIMessage msg, PIMsgHandler* /*sender*/, void* data)
{
char nomps[64],strg[512];
PSFile *mps;
int sxt, syt, syo, syo1, sx[4], sy[4];

switch (msg)
  { 
  case 10501 :
     pfc_ps->AcceptNewFile(true); 
     mFCMsg = 10525; 
     pfc_ps->SetMsg(mFCMsg);
     SetBlocked();
     pfc_ps->Show();
     break;

   case 10525 :
     SetBusy();
     if (data) {
       if (mpsfile) {  
         printf("PIStdImg/Info: Closing PS-File %s \n", name_ps.c_str());
         delete mpsfile;  
         }
        name_ps = pfc_ps->GetFileName();
        printf("PIStdImg/Info: Opening PS-File %s \n", name_ps.c_str());
        mpsfile = new PSFile(name_ps.c_str(), PI_Portrait, PI_A4, 2., 2.);
        }
      mFCMsg = 0;
      SetReady();
      break;

  case 10505 :
    if (!mpsfile)  break;
    printf("PIStdImg/Info: Closing PS-File %s \n", name_ps.c_str());
    delete mpsfile;
    mpsfile = NULL;
    name_ps = "";
    break;

  case 10511 :     // Window -> PS
  case 10512 :     // Window -> EPS 
    if (CurrentWindow() == NULL)  break;
    if (msg == 10512) 
      { 
      num_eps++;
      sprintf(nomps,"pia%d.eps", num_eps);
      printf("PIStdImg/Info: Creating EPSFile %s (CurWin-> EPS) \n", nomps);
      mps = new PSFile(nomps);
      }
    else {
      if (mpsfile == NULL) {
        name_ps = "pia.ps";
        mpsfile = new PSFile(name_ps.c_str(), PI_Portrait, PI_A4, 0., 0.);
        printf("PIStdImg/Info: File PS %s opened \n", name_ps.c_str());
      }
      printf("PIStdImg/Info: CurWin-> PSFile %s\n", name_ps.c_str());      
      mps = mpsfile; 
      }
    CurrentWindow()->PSPrint(mps,0,0);

    if (msg == 10512)   delete mps;   // fichier eps
    break;

  case 10515 :    // Image -> PS
  case 10516 :    // Image -> EPS 
     {
     PIImage* curpimg = NULL;
     if (!mCurWdg)  return;
     if (mCurWdg->kind() != PIImage::ClassId)  return;
     curpimg = (PIImage*)mCurWdg;
     if (curpimg == NULL)   return;
     if (msg == 10516) 
      { 
      num_eps++;
      sprintf(nomps,"pia%d.eps", num_eps);
      printf("PIStdImg/Info: Creating EPSFile %s (CurImage-> EPS)\n", nomps);
      mps = new PSFile(nomps);
      }
    else {
      if (mpsfile == NULL) {
        name_ps = "pia.ps";
        mpsfile = new PSFile(name_ps.c_str(),PI_Portrait, PI_A4, 2., 2.);
        printf("PIStdImg/Info: File PS %s opened \n", name_ps.c_str());
      }
      printf("PIStdImg/Info: CurImage-> PSFile %s\n", name_ps.c_str());       
      mps = mpsfile; 
      }

    sx[0] = gimv->XSize(); 
    sy[0] = gimv->YSize();
    sx[1] = zoom->XSize(); 
    sy[1] = zoom->YSize();
    sx[2] = cmapv->XSize(); 
    sy[2] = cmapv->YSize();
    sx[3] = curpimg->XSize(); 
    sy[3] = curpimg->YSize();
    if (sy[1] > sy[0])  { syo1 = sy[1]+50;  syo = sy[1]+sy[2]+60; }
    else  { syo1 = sy[0]+50;  syo = sy[0]+sy[2]+60; }
    syt = sy[3]+syo;
    sxt = sx[3];
    if (sxt < (sx[0]+sx[1]+20))  sxt = sx[0]+sx[1]+20;
    if (sxt < sx[2])  sxt = sx[2];

    // Pour ecrire le titre 
    mps->NewPage((float)sxt, (float)syt, PI_Portrait);
    mps->NewBloc(0,0, (float)sxt, 30., (float)sxt, 30.);
    sprintf(strg,"Image: %s -  Pave %d %d \n",  curpimg->Nom().c_str(), 
            curpimg->XPave(),  curpimg->YPave());     
    mps->DrawString(10., 25., strg, PI_Black, PI_DefaultFont, PI_BoldFont, 20);
    mps->EndBloc();

    // Les quatre fenetres glovimage, zoom, cmap, image 
    gimv->PSPrint(mps, -gimv->XPos(), -gimv->YPos()+40);
    zoom->PSPrint(mps, -zoom->XPos()+sx[0]+20, -zoom->YPos()+40);
    cmapv->PSPrint(mps, -cmapv->XPos(), -cmapv->YPos()+syo1);
    curpimg->PSPrint(mps, -curpimg->XPos(), -curpimg->YPos()+syo);
     
    if (msg == 10516)   delete mps;    // fichier eps
    break;
    }

  default:
    cerr << "PIStdImgApp::MBProcess5() BUG?? Msg= " <<  msg << endl;    
    break;
  }

}


/* --Methode-- */
void PIStdImgApp::MBProcess6(PIMessage msg, PIMsgHandler* /*sender*/, void* data)
{
switch (msg)  { 
  case 10601:
    CloseAllWindows();
    break;
  case 10602:
    RedirectStdOutErr(*((bool*)data));
    break;
  case 10603:
  case 10604:
    CatchSignals(m[5]->GetStateMsg(10603), m[5]->GetStateMsg(10604));
    break;
  case 10605:
    mObjMgr->SetVerbose(m[5]->GetStateMsg(10605));
    break;
  case 10606:
    mCmd->ShowCxxOptionWindow();
    break;
  default:
    cerr << "PIStdImgApp::MBProcess6() BUG?? Msg= " <<  msg << endl;    
    break;
  }
return;
}


/* --Methode-- */
void PIStdImgApp::SetColAtt(PIColors fg, PIColors bg)
{
  mFCol = fg;
  mBCol = bg;
}
/* --Methode-- */
void PIStdImgApp::SetLineAtt(PILineAtt lat)
{
  mLAtt = lat;
}

/* --Methode-- */
void PIStdImgApp::SetFontName(PIFontName fn)
{
  mFName = fn;
}

/* --Methode-- */
void PIStdImgApp::SetFontAtt(PIFontSize fsz, PIFontAtt fat)
{
  mFSz = fsz;
  mFAtt = fat;
}
/* --Methode-- */
void PIStdImgApp::SetMarkerAtt(int sz, PIMarker mrk)
{
  mMSz = sz;
  mMrk = mrk;
}

/* --Methode-- */
void PIStdImgApp::SetZoomAtt(int zoom)
{
  if ( (zoom > 10) || (zoom < -10) ) zoom = 0;
  mZoom = zoom;
}
/* --Methode-- */
void PIStdImgApp::SetAxesAtt(unsigned int axfl)
{
  mAxesFlags = axfl; 
}
/* --Methode-- */
void PIStdImgApp::SetXYLimits(double xmin, double xmax, double ymin, double ymax)
{
  mXmin = xmin;  mXmax= xmax;
  mYmin = ymin;  mYmax= ymax;
}
/* --Methode-- */
void PIStdImgApp::SetInsetLimits(double xmin, double xmax, double ymin, double ymax)
{
  mIXmin = xmin;  mIXmax= xmax;
  mIYmin = ymin;  mIYmax= ymax;
}
/* --Methode-- */
void PIStdImgApp::SetImageCenterPosition(int x, int y)
{
  mXImgCenter = x;  mYImgCenter = y;
}

/* --Methode-- */
void PIStdImgApp::SaveGraphicAtt()
{
  mSFCol = mFCol;
  mSBCol = mBCol;
  mSLAtt = mLAtt;
  mSFName = mFName;
  mSFSz = mFSz;
  mSFAtt = mFAtt;
  mSMSz = mMSz;
  mSMrk = mMrk;
  mSCmapid = mCmapid;
  mSRevCmap = mRevCmap;
  mSZoom = mZoom;
  mSAxesFlags = mAxesFlags;
  mSXmin = mXmin;  mSXmax = mXmax;
  mSYmin = mYmin;  mSYmax = mYmax;
  mSIXmin = mIXmin;  mSIXmax = mIXmax;
  mSIYmin = mIYmin;  mSIYmax = mIYmax;
  mSFXYlim = mFXYlim;
  mSXImgCenter = mXImgCenter;
  mSYImgCenter = mYImgCenter;
  mSFImgCenter = mFImgCenter;
  mSaXlog = maXlog;
  mSaYlog = maYlog;
  mSAddTitle = mAddTitle;
}

/* --Methode-- */
void PIStdImgApp::RestoreGraphicAtt()
{
  mFCol = mSFCol;
  mBCol = mSBCol;
  mLAtt = mSLAtt;
  mFName = mSFName;
  mFSz = mSFSz;
  mFAtt = mSFAtt;
  mMSz = mSMSz;
  mMrk = mSMrk;
  mCmapid = mSCmapid;
  mRevCmap = mSRevCmap;
  mZoom = mSZoom;
  mAxesFlags = mSAxesFlags;
  mXmin = mSXmin;  mXmax = mSXmax;
  mYmin = mSYmin;  mYmax = mSYmax;
  mIXmin = mSIXmin;  mIXmax = mSIXmax;
  mIYmin = mSIYmin;  mIYmax = mSIYmax;
  mFXYlim = mSFXYlim;
  mXImgCenter = mSXImgCenter;
  mYImgCenter = mSYImgCenter;
  mFImgCenter = mSFImgCenter;
  maXlog = mSaXlog;
  maYlog = mSaYlog;
  mAddTitle = mSAddTitle;
}

//  -------------------------------------------------
//        Fenetre info piapp (About piapp) 
//  -------------------------------------------------
static PIWindow* infow_win = NULL;
static PIText* infow_txt = NULL;
static PICMapView* infow_cmap = NULL;
static PIButton* infow_but = NULL;

/* Nouvelle-Fonction */
static void createInfoWindow(PIStdImgApp* app)
{
if (infow_win) return;

int bsx, bsy;
PIApplicationPrefCompSize(bsx, bsy);
int spx, spy;
spx = bsx/6;   spy = bsy/6;

infow_win = new PIWindow((PIMsgHandler *)app, "About piapp", 
                         PIWK_dialog, bsx*5+3*spx, bsy*4+spy*3, 200, 200);
infow_win->SetAutoDelChilds(true);
infow_txt = new PIText(infow_win,"about_piapp_text", bsx*5+spx, bsy*3, spx, spy);
infow_txt->SetMutiLineMode(true);
infow_txt->SetTextEditable(false);
infow_txt->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
infow_cmap = new PICMapView(infow_win, "about_piapp_cmap", bsx*4, bsy*0.7, spx, 2*spy+bsy*3.15); 
infow_cmap->SetColMapId(CMAP_COLBR32, 1., -1., false); 
infow_cmap->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
infow_but = new PIButton(infow_win,"OK", 10155, bsx, bsy, bsx*4+2*spx, 2*spy+bsy*3);
infow_but->SetMsgParent((PIMsgHandler *)app);
infow_but->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
char buff[128];
#ifdef SANS_EVOLPLANCK
sprintf(buff, "Version: piapp=%g  PI=%g  PEIDA=%g \n", (double)PIAPP_VERSIONNUMBER, 
              (double)PI_VERSIONNUMBER, (float)PeidaVersion());
#else
{
sprintf(buff, "Version: piapp=%g  PI=%g  SOPHYA=%g \n", (double)PIAPP_VERSIONNUMBER, 
              (double)PI_VERSIONNUMBER, glst_piai->Version());
}
#endif
string info = "piapp : Interactive analysis program\n";
info += buff;
info += "(C) LAL-IN2P3/CNRS  1996-2000\n";
info += "(C) SPP-DAPNIA/CEA  1996-2000\n";
infow_txt->SetText(info);
}

/* Nouvelle-Fonction */
static void showInfoWindow(PIStdImgApp* app)
{
if (!infow_win) createInfoWindow(app);
if (infow_win) infow_win->Show();
}
/* Nouvelle-Fonction */
static void hideInfoWindow(PIStdImgApp* app)
{
if (infow_win) infow_win->Hide();
}

/* Nouvelle-Fonction */
static void deleteInfoWindow()
{
if (!infow_win) return;
delete infow_win;
infow_win = NULL;
infow_txt = NULL;
infow_cmap = NULL;
infow_but = NULL;
}

