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

#include <typeinfo>

#include "perrors.h"
#include "ctimer.h"

#include "nbmath.h"

#include "pistdimgapp.h"
#include "nobjmgr.h"
#include "servnobjm.h"



/* ........................................................... */
/*  Classe ObjMgrWind  interface de gestion d'objets nommes    */
/* ........................................................... */

/* --Methode-- */
ObjMgrWind::ObjMgrWind(PIStdImgApp *par)
: PIWindow((PIMsgHandler *)par, "objmgr", PIWK_normal, 
           400, 300, 250, 250)
{
int i;
dap = par;

int bsx, bsy;
int tsx, tsy;
int spx, spy;
// On definit la taille a partir de la taille par defaut des composantes 
PIApplicationPrefCompSize(bsx, bsy);
spx = bsx/4;   spy = bsy/4;
tsx = 4.0*bsx+3*spx;  tsy = 6*bsy+7*spy;
SetSize(tsx,tsy);
dirlist = new PIOptMenu(this, "dirlist", 2.5*bsx, bsy, spx+0.25*bsx, spy); 
dirlist->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
objlist = new PIList(this, "objlist", 3*bsx, tsy-3*spy-bsy, spx, 2*spy+bsy);
objlist->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
// objlist->SetBorderWidth(2);

int py = spy;
int px = 2*spx+3*bsx;
mBut[0] = new PIButton(this, "SetCurObj", 10, bsx, bsy, px, py);   py += (bsy+spy);
mBut[1] = new PIButton(this, "Display", 20, bsx, bsy, px, py);   py += (bsy+spy);
mBut[2] = new PIButton(this, "Print",   30, bsx, bsy, px, py);   py += (bsy+spy);
mBut[3] = new PIButton(this, "SavePPF", 40, bsx, bsy, px, py);   py += (bsy+spy);
mBut[4] = new PIButton(this, "Delete",  50, bsx, bsy, px, py);   py += (bsy+spy);
mBut[5] = new PIButton(this, "Dismiss", 90, bsx, bsy, px, py);   py += (bsy+spy);

for(i=0; i<6; i++)
  mBut[i]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);

// FinishCreate(); pas necessaire ?
}

/* --Methode-- */
ObjMgrWind::~ObjMgrWind()
{
int i;
delete dirlist;
delete objlist;
for(i=0; i<6; i++)  delete mBut[i];
}

/* --Methode-- */
void ObjMgrWind::Show()
{
// dap->SetBlocked();  Ce n'est plus necessaire - Reza 11/12/99
string cdir;
dap->ObjMgr()->GetCurrentDir(cdir);
cdir = '/' + cdir;
dirlist->SetValueStr(cdir);
dap->ObjMgr()->UpdateObjMgrWindow(dirlist->GetValue()-30000);
PIWindow::Show();
return;
}


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

if (sender == objlist)  return; // Changement de selection d'objet - on ne fait rien
  // PIMessage ssg = ModMsg(msg);
msg = UserMsg(msg);
if (msg == 90)  {
  dap->SetReady();
  this->Hide();
  return;
  }
else if (msg >= 30000) {
  dap->ObjMgr()->UpdateObjMgrWindow(msg-30000);
  return;
  }
/*
 else if (msg == 10) {
  string cdir = dirlist->GetValueStr();
  dap->ObjMgr()->SetCurrentDir(cdir);
  return;
  }
*/

string nom = "";
string sel = "";
if ( (msg == 10) || (msg == 20) || (msg == 30) || (msg == 40) || (msg == 50) ) {
  sel = objlist->GetSelectionStr();
  //  size_t p = sel.find_first_not_of(" \t");
  //  if (p<0) p = 0;
  size_t l = sel.length(); 
  size_t q = sel.find_first_of(" \t");
  if (q > l)   q = l; 
  nom = dirlist->GetValueStr() + '/' + sel.substr(0, q);
  }

NamedObjMgr* om = dap->ObjMgr();
if (om == NULL)  return;
if (sel.length() < 1)  return;
if (nom.length() < 1)  return;

switch (msg)
  {
  case 10:
    {
    string cmd = "set cobj " + nom ;
    cout << " Setting current object ($cobj) to " << nom << endl;
    dap->CmdInterpreter()->Interpret(cmd);
    }
    break;
  case 20:
    om->DisplayObj(nom);
    break;
  case 30:
    om->PrintObj(nom);
    break;
  case 40:
    if (dap->mPpfout)  om->SaveObj(nom, *(dap->mPpfout), false);
    break;
  case 50:
    om->DelObj(nom);
    //    objlist->DeleteItemMsg(objlist->GetSelection());
    //    dap->ObjMgr()->UpdateObjMgrWindow(dirlist->GetValue()-30000);
    break;

  default:    
    //    printf("DEBUG/ObjMgrW::Process %d %d \n", (int)msg, (int)ssg); 
    break;
  }
    
return;
}

/* --Methode-- */
void ObjMgrWind::UpdateList(int did)
{
if (!Visible()) return;
if (did != (dirlist->GetValue()-30000) )  return;
dap->ObjMgr()->UpdateObjMgrWindow(did);
return;
}

/* --Methode-- */
void ObjMgrWind::AddObjList(int did, const char * objn, int oid)
{
if (!Visible()) return;
if (did != (dirlist->GetValue()-30000) )  return;
mNitem++;  objlist->AppendItem(objn, oid);
}

/* --Methode-- */
void ObjMgrWind::DelObjList(int did, int oid)
{
if (!Visible()) return;
//DBG printf("DBG-DelObjList %d , %d , (%d) \n", did, dirlist->GetValue()-30000, oid);
if (did != (dirlist->GetValue()-30000) )  return;
objlist->DeleteItemMsg(oid);
}

/* ........................................................... */
/*  Classe PPInMgrWind  interface de gestion d'objets nommes    */
/* ........................................................... */

/* --Methode-- */
PPInMgrWind::PPInMgrWind(PIStdImgApp *par)
: PIWindow((PIMsgHandler *)par, "PPF-FileManager", PIWK_dialog, 
           400, 300, 250, 250)
{
int i;
dap = par;

int bsx, bsy;
int tsx, tsy;
int spx, spy;
// On definit la taille a partir de la taille par defaut des composantes 
PIApplicationPrefCompSize(bsx, bsy);
spx = bsx/4;   spy = bsy/3;
bsx *= 1.25;
ttx = tsx = 3*bsx+8*spx;   tty = tsy = 7*bsy+5*spy;
SetSize(tsx,tsy);

mLab[0] = new PILabel(this, "filename", tsx-spx, bsy-spy, spx/2, spy/2);
mLab[0]->SetLabel("");
mLab[0]->SetBinding(PIBK_elastic, PIBK_elastic, PIBK_elastic,PIBK_elastic);
mLab[0]->SetBorderWidth(1);

polx = spx/2;  poly = bsy+1.5*spy;
tolx = tsx-spx;   toly = tsy-2*bsy-5*spy;
int py = tsy-2*spy-bsy;
int px = 2*spx;
mBut[0] = new PIButton(this, "Read", 2500, bsx, bsy, px, py);   px += (bsx+2*spx);
mBut[1] = new PIButton(this, "ReadAll", 2600, bsx, bsy, px, py);   px += (bsx+2*spx);
mBut[2] = new PIButton(this, "Close", 2700, bsx, bsy, px, py);   px += (bsx+2*spx);

for(i=0; i<3; i++)
  mBut[i]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
  
objlist = NULL;
mLab[1] = NULL;
mPin = NULL;

//   FinishCreate(); pas necessaire 
}

/* --Methode-- */
PPInMgrWind::~PPInMgrWind()
{
int i;
if (objlist) delete objlist;
delete mLab[0];
for(i=0; i<3; i++)  delete mBut[i];
}

/* --Methode-- */
void PPInMgrWind::SetFile(string flnm)
{
char strg[128];
char* nom;
char  noms[32];
int i, cid, key, ln;

bool ok = true;
#ifdef SANS_EVOLPLANCK
TRY {
  mPin = new PInPersist(flnm);
}  CATCH(merr) 
  { printf("ObjMgrWind::SetFile Exception= %ld (%s) \n", (long)merr, PeidaExc(merr)); 
  ok = false; } ENDTRY;
#else
try {
  mPin = new PInPersist(flnm);
  }
catch (IOExc iox) {
  cerr << "ObjMgrWind::SetFile/Error Exception - Msg= " << iox.Msg() << endl;
  ok = false;
  }
#endif

if (!ok) { mPin = NULL;  dap->SetReady(); return; }

if (mPin->NbTags() < 1) {
  delete mPin;   mPin = NULL;
  string no="";
  dap->ObjMgr()->ReadObj(flnm,no);
  return;
}
if (objlist)  delete objlist;
SetSize(ttx,tty);
mLab[0]->SetLabel(flnm);
objlist = new PIList(this, "infileobjlist", tolx, toly, polx, poly);
objlist->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
objlist->SetBorderWidth(2);


#ifdef SANS_EVOLPLANCK
for(i=0; i<mPin->NbTags(); i++) {
  key = mPin->TagKey(i, cid, ln);  // $CHECK$ non-const & reference initialized to temporary, car int -> long&
  if (ln <= 0)  nom = "?";
  else { strncpy(noms, mPin->TagName(i).c_str(), 31);  noms[31] = '\0'; nom = noms; }
  sprintf(strg, "%s  (T=%s, Key=%d)",  nom, dap->ObjMgr()->GetServiceObj()->PClassIdToClassName(cid), key);
  //  sprintf(strg, "%s  (T=%s, Key=%d)",  nom, " DataObject ?", key);  Attention SANS_EVOLPLANCK
  objlist->AppendItem(strg, 5000+i);
}
#else
string tn;
for(i=0; i<mPin->NbTags(); i++) {
  tn = mPin->GetTagName(i);
  objlist->AppendItem(tn.c_str(), 5000+i);
}
#endif

}

/* --Methode-- */
void PPInMgrWind::Show()
{
if (mPin == NULL)   return;
dap->SetBlocked();
PIWindow::Show();
return;
}

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

int sel;
msg = UserMsg(msg);

if (msg == 2700)  {
  delete mPin;  mPin = NULL;
  delete objlist; objlist = NULL;
  dap->SetReady();
  this->Hide();
  return;
}

NamedObjMgr* om = dap->ObjMgr();
switch (msg)
  {
  case 2500:
    sel = (PIMessage)objlist->GetSelection() - 5000;
    if (sel >= 0) om->ReadObj((*mPin), sel);
    break;
  case 2600:
    om->ReadObj((*mPin), -1);
    dap->SetReady();
    this->Hide();
    break;

  default:    
    break;
  }
    
return;
}
