#include "ceditint.h"

#define Uses_TEvent
#define Uses_TInputLine
#define Uses_TButton
#define Uses_TLabel
#define Uses_TRect
#define Uses_THistory
#define Uses_TDialog
#define Uses_TApplication
#define Uses_MsgBox
#define Uses_TDeskTop
#include <tv.h>

#define Uses_TEditorApp
#include "tvedit.h"

#include <stdio.h>

#ifdef FLEX_BISON
extern "C" char *yyParseString(char *s);
#else
extern "C" int eval(char *mit,char **out);
#endif

class TRect;
class TInputLine;

class TCalcDialog : public TDialog
{
public:
  TCalcDialog(const TRect & bounds, char *Title, char *StartVal = NULL);
  virtual void handleEvent(TEvent &);
  TInputLine *input;
  TInputLine *result;
};

const TCalcDialog_His_Exp = 40,
      cmEval = 900;


TCalcDialog::TCalcDialog(const TRect & bounds, char *Title, char *StartVal)
  : TDialog(bounds,Title),
  TWindowInit(TCalcDialog::initFrame)
{
  TRect r;
  helpCtx = hcNoContext;
  r.a.x = 2;
  r.a.y = 2;
  r.b.x = size.x - 5;
  r.b.y = r.a.y + 1;
  input = new TInputLine(r,255);
  //InitHistoryID(TCalcDialog_His_Exp);
  insert(new THistory(TRect(r.b.x,r.a.y,r.b.x+3,r.b.y), input,
                      TCalcDialog_His_Exp));
  if (StartVal)
  {
    input->setData(StartVal);
  }
  insert(input);
  r.move(0,-1);
  insert(new TLabel(r,_("~E~xpression"),input));
  r.move(0,3);
  result = new TInputLine(r,255);
  insert(result);
  r.move(0,-1);
  insert(new TLabel(r,_("~R~esult"),result));
  r.move(0,3);
  r.b.x = r.a.x + 12;
  r.b.y = r.a.y + 2;
  insert(new TButton(r,_("E~v~al"),cmEval,bfDefault));
  r.a.x = r.b.x + 2;
  r.b.x = r.a.x + 12;
  insert(new TButton(r,_("Cancel"),cmCancel,bfNormal));
  input->select();
  options |= ofCentered;
}

void TCalcDialog::handleEvent(TEvent & event)
{
  char *ret;
  TDialog::handleEvent(event);
  switch (event.what)
  {
    case evCommand:
      if (event.message.command==cmEval)
        {
          char input_buffer[256];
          input->getData(input_buffer);
#ifdef FLEX_BISON
          ret = yyParseString(input_buffer);
#else
          int err=eval(input_buffer,&ret);
          if (err)
            {
             sprintf(input_buffer,_("Error in expression (%d)"),err);
             messageBox(input_buffer,mfError | mfOKButton);
            }
#endif
          result->setData(ret);
          input->selectAll(True);
          clearEvent(event);
          break;
        }
      break;
  }
}

void TEditorApp::executeCalc(void)
{
 TCalcDialog *d;
 d = new TCalcDialog(TRect(10,2,72,11),_("Calculator"));
 deskTop->execView(d);
 delete d;
}

