// Classe CxxExecWindow : Control Window for CxxExecutor
// Classe CxxExecOptWindow : Option Window for CxxExecutor
// (c) DAPNIA (CEA)                 LAL (IN2P3/CNRS)
//                           R. Ansari  C.Magneville 10/2000

#include "sopnamsp.h"
#include "cxxexecutor.h"
#include "cxxexecwin.h"

// --------------------------------------------------------------------
// --------------------------------------------------------------------
// ------------- Fenetre dde commande pour le CxxExecutor -------------
// --------------------------------------------------------------------
// --------------------------------------------------------------------

/* --Methode-- */
CxxExecWind::CxxExecWind(PIStdImgApp* par, CxxExecutor * cxxexec)
: PIWindow((PIMsgHandler *)par, "CxxExecutor", PIWK_normal, 400, 300, 150, 150)
{
  dap = par;
  cxxex = cxxexec;
  mFName[0] = "";
  mFName[1] = "";

  int bsx, bsy, szx, szy;
  int px, py, spx, spy;
  int xtext, ytext;

  ////////////////////////////////////
  //       Window Definition        //
  ////////////////////////////////////

  // On definit la taille a partir de la taille par defaut des composantes 
  PIApplicationPrefCompSize(bsx, bsy);
  // On redefinit la taille de la fenetre
  spx = bsx/6;
  spy = bsy/6;
  xtext = 8*bsx;
  ytext = 8*bsy;
  szx = xtext+2*spx;   
  szy = 2*ytext+5*bsy+10*spy;
  SetSize(szx, szy);

  ////////////////////////////////////
  //       User Function Code       //
  ////////////////////////////////////

// Creation du champ texte 
  px = spx;
  py = spy;
  mText[0] = new PIText(this,"helptext",true,true,xtext,0.75*ytext,px,py);
  mText[0]->SetTextEditable(true);
  mText[0]->SetText("");

// Creation du champ titre, des boutons d'action et label fichier
  px = spx;
  py += (int)(spy+0.75*ytext);
  mLab[3] = new PILabel(this,"FileFunc",xtext,bsy,px,py);
  mLab[3]->SetLabel("");
  mLab[3]->SetBorderWidth(1);
  px = spx;
  py += spy+bsy;
  mLab[0] = new PILabel(this,"Function",2*bsx,bsy,px,py);
  mLab[0]->SetLabel("User Function Code");
  mLab[0]->SetBorderWidth(1);
  px += spx+2*bsx;
  mBut[0] = new PIButton(this,"Open",500,bsx,bsy,px,py);
  px += bsx+spx;
  mBut[1] = new PIButton(this,"Save",510,bsx,bsy,px,py);
  px += bsx+spx;
  mBut[2] = new PIButton(this,"Save As",520,bsx,bsy,px,py);
  px += bsx+spx;
  mBut[3] = new PIButton(this,"Reset Name",530,1.5*bsx,bsy,px,py);

  ////////////////////////////////////
  //           User Code            //
  ////////////////////////////////////

// Creation du champ texte 
  px = spx;
  py += 2*spy+bsy;
  mText[1] = new PIText(this,"helptext",true,true,xtext,1.25*ytext,px,py);
  mText[1]->SetTextEditable(true);
  mText[1]->SetText("");

// Creation du champ titre, des boutons d'action et label fichier
  px = spx;
  py += (int)(spy+1.25*ytext);
  mLab[4] = new PILabel(this,"FileCode",xtext,bsy,px,py);
  mLab[4]->SetLabel("");
  mLab[4]->SetBorderWidth(1);
  px = spx;
  py += spy+bsy;
  mLab[1] = new PILabel(this,"Code",2*bsx,bsy,px,py);
  mLab[1]->SetLabel("User Code");
  mLab[1]->SetBorderWidth(1);
  px += spx+2*bsx;
  mBut[4] = new PIButton(this,"Open",501,bsx,bsy,px,py);
  px += bsx+spx;
  mBut[5] = new PIButton(this,"Save",511,bsx,bsy,px,py);
  px += bsx+spx;
  mBut[6] = new PIButton(this,"Save As",521,bsx,bsy,px,py);
  px += bsx+spx;
  mBut[7] = new PIButton(this,"Reset Name",531,1.5*bsx,bsy,px,py);

  ////////////////////////////////////
  //     Buttons for execution      //
  ////////////////////////////////////

// Creation du champ titre pour le code
  px = spx;
  py += 2*spy+bsy;
  mLab[2] = new PILabel(this, "Execute",2*bsx,bsy,px,py);
  mLab[2]->SetLabel("Execute :");
  mLab[2]->SetBorderWidth(1);

// Creation des boutons d'action 
  px += (int)(szx/2 - 1.2*bsx - spx);
  mBut[8] = new PIButton(this,"Exec",600,1.2*bsx,bsy,px,py);
  px += (int)(1.2*bsx+spx);
  mBut[9] = new PIButton(this,"Dismiss",601,1.2*bsx,bsy,px,py);

  ////////////////////////////////////
  //  Set Attributes for Elements   //
  ////////////////////////////////////

  int ii;
  for(ii=0; ii<5; ii++) 
    mLab[ii]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);
  for(ii=0; ii<10; ii++) 
    mBut[ii]->SetBinding(PIBK_elastic , PIBK_elastic , PIBK_elastic , PIBK_elastic);
  for(ii=0; ii<2; ii++) 
    mText[ii]->SetBinding(PIBK_elastic,PIBK_elastic, PIBK_elastic,PIBK_elastic);

  // File Chooser
  pfc = new PIFileChooser(this,"CxxExec-FileChooser", 5000); 
}

/* --Methode-- */
CxxExecWind::~CxxExecWind()
{
  int i;
  for(i=0; i<5; i++)  delete mLab[i];
  for(i=0; i<10; i++) delete mBut[i];
  for(i=0; i<2; i++)  delete mText[i];
  delete pfc;
}

/* --Methode-- */
void CxxExecWind::Show()
{
mLab[3]->SetLabel(mFName[0]);
mLab[4]->SetLabel(mFName[1]);
PIWindow::Show();
}

/* --Methode-- */
void CxxExecWind::Process(PIMessage msg, PIMsgHandler* /*sender*/, void* data)
{
  msg = UserMsg(msg);
  switch (msg)  {
    case 600:    // Bouton Execute C++
      SetUnSensitive();
      dap->GetConsole()->AddStr(
	 "CxxExecWind::Process() - Executing C++ Code ... \n", PIVA_Magenta);
      dap->SetBusy();
      cxxex->ExecuteCXX(mText[1]->GetText(),mText[0]->GetText());
      dap->GetConsole()->AddStr(
	 "CxxExecWind ... End of Executing C++ Code \n");
      SetSensitive();
      dap->SetReady();
      break;
    case 601:   // Bouton Dismiss - On cache la fenetre
      this->Hide();
      break;
    case 500:    // Open File for Function
    case 501:    // Open File for Code
      {
      int i = msg-500;
      pfc->AcceptNewFile(false); 
      pfc->SetMsg(5500+i);
      dap->SetBlocked();
      pfc->Show();
      break;
      }
    case 5500:  // Return from open-file dialog for Function
    case 5501:  // Return from open-file dialog for Code
      {
      int i = msg-5500;
      dap->SetBusy();
      if(data) {
	mFName[i] = pfc->GetFileName();
	mLab[3+i]->SetLabel(mFName[i]);
        string code = stringfrfile(mFName[i]);
	mText[i]->SetText(code);
      }
      dap->SetReady();
      break;
      }
    case 510:  // Save for Function
    case 511:  // Save for Code
    case 520:  // Save-File for Function
    case 521:  // Save-File for Code
      {
      int i = msg%10;
      if( msg<515 && mFName[i].length()>0 ) {
        string code = mText[i]->GetText();
        filefrstring(mFName[i],code);
      } else {
	pfc->AcceptNewFile(true); 
	pfc->SetMsg(5520+i);
	dap->SetBlocked();
	pfc->Show();	
      }
      break;
      }
    case 5520:  // Return from Save-file dialog for Function
    case 5521:  // Return from Save-file dialog for Code
      {
      int i = msg-5520;
      dap->SetBusy();
      if (data) {
	mFName[i] = pfc->GetFileName();
	mLab[3+i]->SetLabel(mFName[i]);
        string code = mText[i]->GetText();
        filefrstring(mFName[i],code);
      }
      dap->SetReady();
      break;
      }
    case 530:  // Reset name for Function
    case 531:  // Reset name for Code
      {
      int i = msg-530;
      mFName[i] = "";
      mLab[3+i]->SetLabel(mFName[i]);
      }
  }

  // In case of compile errors, we end-up here !    
  mBut[8]->SetSensitive();
  dap->SetReady();
  return;
}

/* --Methode-- */
void CxxExecWind::filefrstring(string filename,string& code)
{
if(filename.size()<1) return;
if(code.size()<1) return;
ofstream os(filename.c_str(),ios::out);
if(!os)
  {cout<<"CxxExecWind::filefrstring: unable to open "<<filename<<endl;
   return;}
os<<code<<endl;
}

/* --Methode-- */
string CxxExecWind::stringfrfile(string filename)
{
string code = "";
if(filename.size()<1) return code;
ifstream is(filename.c_str(),ios::in);
if(!is)
  {cout<<"CxxExecWind::stringfrfile: unable to open "<<filename<<endl;
   return code;}
char c;
while(is.get(c)) code += c;
return code;
}

// --------------------------------------------------------------------
// --------------------------------------------------------------------
// --------------- Fenetre d'option pour le CxxExecutor ---------------
// --------------------------------------------------------------------
// --------------------------------------------------------------------

/* --Methode-- */
CxxOptionWind::CxxOptionWind(PIStdImgApp* par, CxxExecutor * cxxexec)
: PIWindow((PIMsgHandler *)par, "CxxOption", PIWK_normal, 400, 300, 150, 150)
{

  dap = par;
  cxxex = cxxexec;

  int bsx, bsy, szx, szy;
  int px, py, spx, spy;
  int xtext;
  // On definit la taille a partir de la taille par defaut des composantes 
  PIApplicationPrefCompSize(bsx, bsy);
  // On redefinit la taille de la fenetre
  spx = bsx/12; if(spx<2) spx=2;
  spy = bsy/6;
  xtext = 7*bsx;
  szx = (int)(xtext+1.5*bsx+3*spx);
  szy = 7*bsy+8*spy;
  SetSize(szx, szy);

// Creation de champs "labels"
  px = (szx-xtext)/2;
  py = spy;
  mTit = new PILabel(this,"CxxExecutor Options",xtext,bsy,px,py);
  mTit->SetBorderWidth(1);

// Creation des labels et des champs texte
  px = spx;
  py += spy+bsy;
  mLab[0] = new PILabel(this,"Include Files",1.5*bsx,bsy,px,py);
  px += (int)(1.5*bsx+spx);
  mText[0] = new PIText(this,"IncFiles",xtext,bsy,px,py);
  mText[0]->SetText("");

  px = spx;
  py += spy+bsy;
  mLab[1] = new PILabel(this,"Compile Opt.",1.5*bsx,bsy,px,py);
  px += (int)(1.5*bsx+spx);
  mText[1] = new PIText(this,"CompOpt",xtext,bsy,px,py);
  mText[1]->SetText("");

  px = spx;
  py += spy+bsy;
  mLab[2] = new PILabel(this,"Link Options",1.5*bsx,bsy,px,py);
  px += (int)(1.5*bsx+spx);
  mText[2] = new PIText(this,"LinkOpt",xtext,bsy,px,py);
  mText[2]->SetText("");

  px = spx;
  py += spy+bsy;
  mLab[3] = new PILabel(this,"Libraries",1.5*bsx,bsy,px,py);
  px += (int)(1.5*bsx+spx);
  mText[3] = new PIText(this,"LinkLib",xtext,bsy,px,py);
  mText[3]->SetText("");

  px = spx;
  py += spy+bsy;
  mLab[4] = new PILabel(this,"Modules",1.5*bsx,bsy,px,py);
  px += (int)(1.5*bsx+spx);
  mText[4] = new PIText(this,"ModImp",xtext,bsy,px,py);
  mText[4]->SetText("");

// Creation de bouton d'action 

  px = (int)(szx/2 - 1.5*bsx - spx - 1.5*bsx/2.);
  py += spy+bsy;
  mBut[0] = new PIButton(this,"Set Options",500,1.5*bsx,bsy,px,py);
  px += (int)(1.5*bsx+spx);
  mBut[1] = new PIButton(this,"Get Options",600,1.5*bsx,bsy,px,py);
  px += (int)(1.5*bsx+spx);
  mBut[2] = new PIButton(this,"Dismiss",700,1.5*bsx, bsy,px,py);

//  Taille et position proportionnelles a la taille de la fenetre pour les elements
  mTit->SetBinding(PIBK_elastic , PIBK_elastic , PIBK_elastic , PIBK_elastic);
  int i;
  for(i=0; i<4; i++)
    mLab[i]->SetBinding(PIBK_elastic , PIBK_elastic , PIBK_elastic , PIBK_elastic);
  for(i=0; i<4; i++)
    mText[i]->SetBinding(PIBK_elastic , PIBK_elastic , PIBK_elastic , PIBK_elastic);
  for(i=0; i<3; i++) 
    mBut[i]->SetBinding(PIBK_elastic , PIBK_elastic , PIBK_elastic , PIBK_elastic);
}

/* --Methode-- */
CxxOptionWind::~CxxOptionWind()
{
  delete mTit;
  int i;
  for(i=0; i<5; i++) delete mLab[i];
  for(i=0; i<3; i++) delete mBut[i];
  for(i=0; i<5; i++) delete mText[i];
}

/* --Methode-- */
void CxxOptionWind::Show()
{
  mText[0]->SetText(cxxex->GetInclude());
  mText[1]->SetText(cxxex->GetCompileOpt());
  mText[2]->SetText(cxxex->GetLinkOpt());
  mText[3]->SetText(cxxex->GetLinkLibs());
  mText[4]->SetText(cxxex->GetModuleImport());
  PIWindow::Show();
}

/* --Methode-- */
void CxxOptionWind::Process(PIMessage msg, PIMsgHandler* /*sender*/, void* /*data*/)
{
  string opt;
  switch (UserMsg(msg))  {
    case 500:    // Bouton Set Options
      opt = mText[0]->GetText();
      cxxex->FillInclude(opt);
      opt = mText[1]->GetText();
      cxxex->FillCompileOpt(opt);
      opt = mText[2]->GetText();
      cxxex->FillLinkOpt(opt);
      opt = mText[3]->GetText();
      cxxex->FillLinkLibs(opt);
      opt = mText[4]->GetText();
      cxxex->FillModuleImport(opt);
      break;
    case 600:    // Bouton Get Options
      mText[0]->SetText(cxxex->GetInclude());
      mText[1]->SetText(cxxex->GetCompileOpt());
      mText[2]->SetText(cxxex->GetLinkOpt());
      mText[3]->SetText(cxxex->GetLinkLibs());
      mText[4]->SetText(cxxex->GetModuleImport());
      break;
    case 700:   // Bouton Dismiss - On cache la fenetre
      this->Hide();
      break;
  }
return;
}
