/*

  Managing of external processes


  Copyright © 2011-5 F.Hroch (hroch@physics.muni.cz)

  This file is part of Munipack.

  Munipack is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.
  
  Munipack is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  
  You should have received a copy of the GNU General Public License
  along with Munipack.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <wx/wx.h>
#include <wx/app.h>
#include <wx/process.h>
#include <wx/event.h>
#include <wx/stopwatch.h>
#include <queue>



class MuniProcess: public wxProcess
{
public:
  MuniProcess(wxEvtHandler *, const wxString&, const wxArrayString& =wxArrayString());
  virtual ~MuniProcess();

  virtual void OnPreProcess() {}
  virtual void OnStart();
  virtual void OnPostProcess() {}
  wxKillError Kill(wxSignal sig =wxSIGTERM, int flags =wxKILL_NOCHILDREN);

  void Write(const char *);
  void Write(const wxString&, ...);
  void WriteOutput(const wxString&, const wxString& =wxEmptyString);
  void WriteFile(const wxString&);
  void WriteFiles(const wxString&,const wxString&,const wxString&);
  int GetExitCode() const { return exitcode; }
  wxArrayString GetArgs() const { return ArgsBuffer; }
  wxArrayString GetInput() const { return InputBuffer; }
  wxArrayString GetOutput() const { return OutputBuffer; }
  wxArrayString GetErrors() const { return ErrorBuffer; }
  size_t GetBufferSize() const { return MaxBuffer; }
  void SetInput(const wxArrayString&);
  wxString GetCommand() const { return command; }

  void SetBufferSize(size_t i) { MaxBuffer = i; }
  void SetVerbose(bool verb) { verbose = verb; }

protected:
  
  wxString command;
  wxArrayString ArgsBuffer,InputBuffer,OutputBuffer,ErrorBuffer;
  int exitcode;

private:

  wxEvtHandler *handler;
  wchar_t **argv;
  wxTimer timer;
  int tick;
  wxStopWatch stopwatch;
  size_t MaxBuffer;
  bool killing;
  bool verbose;

  void Flush();
  void OnTimer(wxTimerEvent&);
  void OnIdle(wxIdleEvent&);
  void OnFinish(wxProcessEvent&);
  void fitskeys(wxTextOutputStream&);
  bool StopLine(const wxString&, int&);

  void SetEnvironment();
};

class MuniPipe: public wxEvtHandler
{
public:
  MuniPipe(wxEvtHandler * =0);
  virtual ~MuniPipe();

  void push(MuniProcess *);
  void Start();
  void Stop();
  void SetExitCode(int e) { exitcode = e; }
  int GetExitCode() const { return exitcode; }
  bool empty() const { return procs.empty(); };
  wxArrayString GetOutput() const;
  wxArrayString GetErrors() const;

protected:

  void OnFinish(wxProcessEvent&);

private:

  wxEvtHandler *handler;
  std::queue<MuniProcess *> procs;
  wxArrayString OutputBuffer,ErrorBuffer;
  int exitcode;

};

