#include <stdlib.h>
#include <stdio.h>
#include <iostream.h>

#include "pistdimgapp.h"
#include "piacmd.h"
#include "piversion.h"
#include "piaversion.h"

#include "timing.h"
#include "skyinit.h"

#include "xntuple.h" // Pour faire le SetTmpDir()


// ---- Pour charger automatiquement le module sopiamodule 
extern "C" {
void sopiamodule_init();
void sopiamodule_end();
void fitsbtadapter_init();
void fitsbtadapter_end();
void W2PSModule_init();
void W2PSModule_end();
}

/*!
  \defgroup ProgPI ProgPI module
  This module contains programs for interactive data analysis and
  visualisation, based on SOPHYA class libray and PI (GUI framework)
  and PIext (Interactive data analysis framework).
*/

/*!
  \ingroup ProgPI
  \file piapp.cc
  \brief \b (s)piapp: Starts the piapp interactive data analysis program.

  The current version of the program has a single execution thread. This
  creates few limitations (GUI can not be used when computing is being
  done, ...). Also the command file executed during start-up (-exec)
  cannot contain display (graphic) commands.

  \verbatim
  csh> spiapp -h
  SOPHYA Version  1.1 Revision 0 (V_Fev2001) -- Mar  9 2001 15:45:31 cxx

  piapp: Interactive data analysis and visualisation program
  Usage: piapp [-nored] [-nosig] [-nosigfpe] [-nosigsegv]
               [-tmpdir TmpDirectory] [-help2tex] [-exec file [args]]
    -nored : NoRedirect StdOut/StdErr
    -nosig : Don't catch SigFPE, SigSEGV
    -nosigfpe -nosigsegv: Don t catch SigFPE / SigSEGV
    -tmpdir TmpDirectory: defines TMDIR for temporary files
    -help2tex: Create a LaTeX help file (piahelp.tex)
    -exec file [args] : Execute command file
  
  \endverbatim
 
*/

void Usage(bool fgerr)
{
  if (fgerr) { 
    cout << " piapp : Argument Error ! piapp -h for Usage" << endl; 
    exit(1);
  }
  else {
    cout << "\n piapp: Interactive data analysis and visualisation program \n"
	 << " Usage: piapp [-nored] [-nosig] [-nosigfpe] [-nosigsegv] \n"
	 << "              [-tmpdir TmpDirectory] [-help2tex] [-exec file [args]] \n"
	 << "  -nored : NoRedirect StdOut/StdErr \n"
	 << "  -nosig : Don't catch SigFPE, SigSEGV \n"
         << "  -nosigfpe -nosigsegv: Don t catch SigFPE / SigSEGV \n"
	 << "  -tmpdir TmpDirectory: defines TMDIR for temporary files \n"
	 << "  -help2tex: Create a LaTeX help file (piahelp.tex)\n"
	 << "  -exec file [args] : Execute command file \n"
	 << endl;
    exit(0);
  }
}

/*  ================================ MAIN() =================================  */

int main(int narg, char *arg[])
{
int ofa;
int fgfpe, fgsegv, fgred, fgexec;

SkyTInitiator skyinit;
   
InitTim();


if ( (narg > 1) && (strcmp(arg[1],"-h") == 0) ) Usage(false);

ofa = 1;
fgred = fgfpe = fgsegv = true;
fgexec = false;
bool fgtmp = false;
string tmpdir;
string exfc;
// Pour fabriquer le help
bool fgtexh = false;
int ka;
for(ka=1; ka<narg; ka++) {
  if (strcmp(arg[ka],"-nored") == 0)   fgred=false; 
  else if (strcmp(arg[ka],"-nosig") == 0)   fgfpe=fgsegv=false; 
  else if (strcmp(arg[ka],"-nosigfpe") == 0)   fgfpe=false; 
  else if (strcmp(arg[ka],"-nosigsegv") == 0)   fgsegv=false; 
  else if (strcmp(arg[ka],"-help2tex") == 0) { fgtexh=true; fgred=false; }
  else if (strcmp(arg[ka],"-tmpdir") == 0) {
    if (ka == narg-1) Usage(true);
    fgtmp = true;  ka++;
    tmpdir = arg[ka];    
  }
  else if (strcmp(arg[ka],"-exec") == 0) {
    if (ka < narg-1) {
      fgexec = true;
      exfc = "exec";
      for(int kaa=ka+1; kaa<narg; kaa++)  { exfc += ' ';  exfc +=  arg[kaa]; }
      }
    break;
    }
  }

 
if (fgexec) printf(">>>>> Starting piapp , Executing %s \n", exfc.c_str()); 
else printf(">>>>> Starting piapp <<<<< \n");
printf("Version: piapp=%g  PI=%g  SOPHYA=%g \n", (double)PIAPP_VERSIONNUMBER, 
              (double)PI_VERSIONNUMBER, (double)skyinit.Version());

char *vcmds;
if (fgtmp) {
  if (tmpdir[tmpdir.length()-1] != '/') tmpdir += '/';  // Necessaire pour SetSwapPath
  string vcmd = "TMPDIR=" + tmpdir;
  vcmds = new char[vcmd.length()+1];
  strcpy(vcmds, vcmd.c_str());
  putenv(vcmds);
}

// cout << " DBG-TMPDIR= " << getenv("TMPDIR") << endl;

PIStdImgApp * app = new PIStdImgApp(narg, arg);
// cout << " DBG-2 " <<  app->ObjMgr()->GetTmpDir() << endl;
if (fgtmp) {  // Changement de tmpdir 
  cout << "  NamedObjMgr::SetTmpDir()+XNTuple::SetSwapPath() " << tmpdir << endl;
  app->ObjMgr()->SetTmpDir(tmpdir);
  XNTuple::SetSwapPath(const_cast<char *>(tmpdir.c_str()));
}


// Gestion de redirection stdout/err et Signaux
if (fgred) app->RedirectStdOutErr(true);
else app->RedirectStdOutErr(false);
app->CatchSignals(fgfpe, fgsegv);

// S'il y a un fichier de commande a executer
if (fgexec) app->CmdInterpreter()->Interpret(exfc);

// On charge le module sopiamodule
sopiamodule_init();
// On charge le module de lecture ligne a ligne des Fits BINARY/ASCII tables
fitsbtadapter_init();
// On charge le module des commandes de creation de fichier postscript
W2PSModule_init();

// S'il y a besoin de faire le fichier Help
if (fgtexh) { 
  string thf = "piahelp.tex";
  app->CmdInterpreter()->HelptoLaTex(thf);
  printf("piapp : Help file piahelp.tex created --> exit(0) \n"); 
  delete app;
  exit(0);
}

int rc = 0;
bool cont = true;
char ans[32],rep;
int excnt = 0;
while(cont) {
  rc = 0;   cont = false;
  app->SetReady();
  if (fgred) app->RedirectStdOutErr(true);
  try {
  app->Run();
  }  
  catch(PThrowable exc) {  // Catching SOPHYA exceptions 
    app->Stop();
    app->RedirectStdOutErr(false);  
    //BUG ? fait planter OSF-cxx     fflush(stdout); 
    cout << endl;      cerr << endl;
    cout << "\n piapp/main() PThrowable catched ! " << exc.Msg() << endl;
    cout << ++excnt << "- continue <CR>, Close Windows, "
         << " continue C<CR> Stop program S<CR> ? " << endl; 
    gets(ans);
    rep = toupper(ans[0]);  
    if (rep == 'S')  { 
      cout << " !!!! Stopping piapp !!!! " << endl;
      rc = 78;
      cont = false;
    }
    else { 
      if (rep == 'C') {
	cout << "piapp/main() Closing all windows ... " << endl;
	app->CloseAllWindows();
      }
      cout << " *** piapp - Continuing event loop *** " << endl;
      cont = true;
    }
  }
  catch(...) { // Catching all other exceptions 
    app->Stop();
    app->RedirectStdOutErr(false);  
    cout << endl;      cerr << endl;
    cout << "\n piapp/main() exception catched ! " << endl;
    cout << ++excnt << "- continue <CR>, Close Windows, "
         << " continue C<CR> Stop program S<CR> ? " << endl; 
    gets(ans);
    rep = toupper(ans[0]);  
    if (rep == 'S')  { 
      cout << " !!!! Stopping piapp !!!! " << endl;
      rc = 78;
      cont = false;
    }
    else { 
      if (rep == 'C') {
	cout << "piapp/main() Closing all windows ... " << endl;
	app->CloseAllWindows();
      }
      cout << " *** piapp - Continuing event loop *** " << endl;
      cont = true;
    }
  }
}

app->RedirectStdOutErr(false);  
// On de-charge le module sopiamodule et fitsbtadapter
sopiamodule_end();
fitsbtadapter_end();
W2PSModule_end();

delete app;
if (fgtmp) delete[] vcmds;

cout << "\n------------------------------------------------ \n"
     << "-------- piapp : Exiting .... Rc= " << rc << " -----------\n"
     << "------------------------------------------------ " << endl; 
return(rc);
}

