/* $Id: translat.cpp 2.4 1995/07/20 11:24:33 leon Exp leon $
 */

#define Uses_TEvent

#define Uses_MsgBox

#define Uses_TTerminal

#define Uses_otstream

#define Uses_TWindow

#define Uses_TProgram

#define Uses_TDeskTop

#define Uses_TApplication

#include <tvision/tv.h>


#if !defined( __TRANSLAT_H )

#include "translat.h"

#endif


#include <iostream.h>

#include <fstream.h>

#include <cstring.h>

#include "gisel.h"

#include "parse.h"

#include "comm.h"

#include "config.h"



/** Translate window **/
extern Translate *trans;
/** Total converted lines **/
extern long TotalLines; // gtoisel.cpp

/** Communication channell **/
extern Comm *comm;
/** YACC default input file **/ 
extern FILE *yyin;


static struct translateDataRec TranslateTime;

/**
 ** YACC error handling routine
 **/
int yyerror(char *str) // C function

{
  extern long int lineno;
  extern char linebuf[200];

  clog << "Error: '" << str << "' on line " << lineno << endl;
  clog << linebuf << endl;
  return 0;
}


/**
 ** Creates dumb terminal with ostream redirection
 **/
class TOutputWindow : public TWindow
{

TTerminal *term;
ostream_withassign oldOstr;
ostream_withassign *pOldOstr;

public:
  TOutputWindow( TRect bounds, const char *title,
                 ostream_withassign& ostr, ushort bufsize );
  ~TOutputWindow(){ *pOldOstr = oldOstr; }
  void attach( ostream_withassign& ostr ) { ostr = term; }
};


/**
 ** Creates ostream output terminal window. When window is deleted
 ** ostream is reassigned back to the original.
 **/
TOutputWindow::TOutputWindow( TRect bounds, const char *title,
                              ostream_withassign& ostr, ushort bufsize ) :
              TWindowInit( TOutputWindow::initFrame ),
              TWindow( bounds, title, OutputWndNum )
{
  bounds = getExtent();

  bounds.grow(-1, -1);
  options |= ofTileable;


  term = new TTerminal( bounds,
                        standardScrollBar( sbHorizontal | sbHandleKeyboard ),
                        standardScrollBar( sbVertical | sbHandleKeyboard ),
                        bufsize );
  insert( term );
  oldOstr = ostr;
  pOldOstr = &ostr;
  otstream ot( term );
  // ot << "Terminal window \"" << title << "\" created. " << endl;

  ostr = ot;
}



/**
 ** Translates file and sends directly to controller
 **/
Translate::Translate()
      : TDialog(TRect(21, 1, 55, 12), "Status"),
        TWindowInit(Translate::initFrame)

{
 TView *control;

 number = TranslateWndNum;

 TotalLines = 0;

 bar = new TColoredText(TRect(4, 2, 30, 3), "\003Converting...", 0x34);
 insert(bar);

 control = new TButton(TRect(9, 8, 25, 10), "Cancel Job", cmCancel, bfDefault);
 insert(control);

 control = new TInputLine(TRect(20, 4, 30, 5), 11);
 control->eventMask &= ~(evMouseDown | evKeyDown | evCommand);
 control->options &= ~(ofSelectable | ofFirstClick);
 insert(control);

   insert(new TLabel(TRect(3, 4, 19, 5), "Estimated Time:", control));

 control = new TInputLine(TRect(20, 5, 30, 6), 11);
 control->eventMask &= ~(evMouseDown | evKeyDown | evCommand);
 control->options &= ~(ofSelectable | ofFirstClick);
 insert(control);

   insert(new TLabel(TRect(5, 5, 19, 6), "Elapsed Time:", control));

 control = new TInputLine(TRect(20, 6, 30, 7), 11);
 control->eventMask &= ~(evMouseDown | evKeyDown | evCommand);
 control->options &= ~(ofSelectable | ofFirstClick);
 insert(control);

   insert(new TLabel(TRect(3, 6, 19, 7), "Remaining Time:", control));


 TranslateTime.estimatedTime[0] = '\0';
 TranslateTime.elapsedTime[0] = '\0';
 TranslateTime.remainedTime[0] = '\0';

 selectNext(False);
}

/*
 * Converts seconds to string with hh:mm:ss format
 */
inline char *secToDelta(long deltaSeconds, char ascTime[9])
{
  short seconds = deltaSeconds % 60;
  deltaSeconds /= 60;
  short minutes = deltaSeconds % 60;
  short hours = deltaSeconds / 60;

  sprintf(ascTime, "%2d:%02d:%02d", hours, minutes, seconds);
  return ascTime;
}

/**
 ** Updates progress bar
 **/
void Translate::update()
{
#define BARLENGTH 26

  if (TotalLines != 0 && trans)
    {

      short linenum = short(( (float)comm->getLineNumber()
                     /(float)TotalLines - 1.0/BARLENGTH) * BARLENGTH) + 1;

      char buf[BARLENGTH+1];
      for (short i = 0; i < linenum && i < BARLENGTH ; i++)
        buf[i] = '\xDB';
      buf[i] = '\0';
             
      bar->set(buf);


      double deltaTime = difftime(time(0), startTime);
      long elapsedSeconds = long(deltaTime);
      long estimatedSeconds = long (deltaTime *  (double)TotalLines
                                / (double)(comm->getLineNumber() + 1));
      long remainingSeconds = estimatedSeconds - elapsedSeconds;

      secToDelta(elapsedSeconds, TranslateTime.elapsedTime);
      secToDelta(estimatedSeconds, TranslateTime.estimatedTime); 
      secToDelta(remainingSeconds, TranslateTime.remainedTime);
      setData(&TranslateTime);
      drawView();
    }
}

/**
 ** Closes input files
 **/
Translate::~Translate()
{
  trans = NULL;
  ifs.close();
  if (yyin)
    {
      fclose(yyin);
      yyin = NULL;
    }
}

/**
 ** Handles window events
 **/
void Translate::handleEvent( TEvent& event)
{
    TDialog::handleEvent(event);
    switch(event.what)
      {
        case evCommand:
          if ( event.message.command ==  cmCancel )
            {
              comm->dequeue();
              close();
            }
        break;
      }
}

const char * const Translate::name = "Translate";

/**
 ** Writes to stream
 **/
void Translate::write( opstream& os )
{
 TDialog::write( os );
}

/**
 ** Reads object from stream
 **/
void *Translate::read( ipstream& is )
{
 TDialog::read( is );
 return this;
}

/**
 ** Builds object
 **/
TStreamable *Translate::build()
{
    return new Translate( streamableInit );
}


TStreamableClass Rranslate( Translate::name,
                        Translate::build,
                        __DELTA(Translate)
                      );


/**
 ** Translates G-Code /fileName/ and enqueues it to Job manager
 **/
Translate::translate(const char *fileName)
{
  extern long int lineno;
  ostream_withassign oldCout;
  string title("Conversion log of the file ");

  title += fileName;

  lineno = 1;

  TotalLines = 0;



  yyin = fopen(fileName, "r");
  if (!yyin)
    {
      messageBox(mfOKButton | mfError,  "Cannot open file %s",  fileName);
      return -1;
    }

  oldCout = cout;

  ofstream fout("gisel.out");
  cout = fout;

  TRect r = TProgram::deskTop->getExtent();
  r.a.y = r.b.y - 7;
  TView *t = (TView *) new TOutputWindow(r, (const char *)&title[0], clog, 8192 );
  if( t != 0 )
      TProgram::deskTop->insert( t );

  select();

  clog << "Converting..." << endl;

  if (yyparse() != 0)
    {
      yyrestart(yyin);
      fclose(yyin);
      yyin = NULL;
      cout = oldCout;
      fout.close();
      messageBox( mfOKButton | mfError, 
                 "Unrecoverable error occurred in the file %s\n"
                 "Conversion cannot continue!", fileName);
      return -2;
    }

  cout.flush();
  yyrestart(yyin);
  fclose(yyin);
  cout = oldCout;
  fout.close();

  clog << "End of conversion." << endl;

  if (messageBox("OK to enqueue to Job manager?", 
                 mfConfirmation | mfOKCancel) == cmOK)
    {
      time(&startTime);
      bar->set("\003Waiting controller...");
      ifs.open("gisel.out");
      comm->enqueue(ifs);
    }
  else
    {
//      comm->dequeue();

      close();
      return -1;
    }
  return 0;
}



__link(RButton)
__link(RScrollBar)
__link(RStaticText)
__link(Rranslate)




syntax highlighted by Code2HTML, v. 0.9.1