/* $Id: GISEL.CPP 2.4 1995/07/20 11:24:33 leon Exp $
 *
 *      GISEL - G-CODE ISEL CNC driver
 *
 *      Copyright (c) 1994 LECAD
 *      All Rights Reserved.
 *
 */


#define EDITOR

#define HEAPVIEW

#define CLOCKVIEW

#define CSECT "Communications"



#define Uses_MsgBox

#define Uses_TApplication

#define Uses_TButton

#define Uses_TChDirDialog

#define Uses_TDeskTop

#define Uses_TDialog

#define Uses_TEditWindow

#define Uses_TEditor

#define Uses_TEvent

#define Uses_TFileDialog

#define Uses_TFileEditor

#define Uses_fpstream

#define Uses_TKeys

#define Uses_TMenuBar

#define Uses_TMenuItem

#define Uses_TRect

#define Uses_TScroller

#define Uses_TStaticText

#define Uses_TSubMenu

#define Uses_TTerminal


#include <tvision/tv.h>

#include <tvision/help.h>


__link( RView )
__link( RWindow )
__link(RScroller)
__link(RScrollBar)
__link(REditWindow)

#include "config.h"

#include "gadgets.h"

#include "calc.h"

#include "profport.h"

#include "gisel.h"

#include "terminal.h"

#include "setup.h"

#include "log.h"

#include "comm.h"

#include "manual.h"

#include "translat.h"

#include "position.h"

#include "jobman.h"

#include "giselhlp.h"

#include "machinin.h"

#include "machdlg.h"

 
#include <stdlib.h>

#include <stdarg.h>

#include <strstrea.h>

#include <fstream.h>

#include <iomanip.h>

#include <dos.h>

#include <io.h>     // access()


extern "C" void ExpirationTime(char *argv0); // protect.c


TEditWindow *clipWindow;    // Clipboard window pointer 

Comm *comm;                 // Communication channel for most modules */

Translate *trans;           // current translating window 

PositionWnd *positionWnd;   // current position indicator

long position[3];           // current position in steps

char IniFile[100];          // .INI filename

extern Machining Machining; // gtoisel.cpp


/* Global settings */
SettingsRec *Settings;
/* Homing speed settings */
HomingSpeedRec *HomingSpeed;

/**
 ** Main application constructor
 **/
TGIselApp::TGIselApp(int /*argc*/, char ** /* argv */) :
                TProgInit( TGIselApp::initStatusLine,
                           TGIselApp::initMenuBar,
                           TGIselApp::initDeskTop ),
                TApplication()
{

#if 1

    TCommandSet ts;
    ts.enableCmd( cmSave );
    ts.enableCmd( cmSaveAs );
    ts.enableCmd( cmCut );
    ts.enableCmd( cmCopy );
    ts.enableCmd( cmPaste );
    ts.enableCmd( cmClear );
    ts.enableCmd( cmUndo );
    ts.enableCmd( cmFind );
    ts.enableCmd( cmReplace );
    ts.enableCmd( cmSearchAgain );
    ts.enableCmd( cmClose );
    ts.enableCmd( cmNext );

    disableCommands( ts );

    trans = NULL;
    positionWnd = NULL;
    position[0] = position[1] = position[2] = 0;

#endif

    log = NULL;

    comm = new Comm(&log);
    Settings = new SettingsRec;
    HomingSpeed = new HomingSpeedRec;

#ifdef EDITOR

    TEditor::editorDialog = doEditDialog;

    clipWindow = openEditor( 0, False );
    if( clipWindow != 0 )
        {
        TEditor::clipboard = clipWindow->editor;
        TEditor::clipboard->canUndo = False;
        }
#endif


#ifdef HEAPVIEW

    // Heap gadget


    TRect r = getExtent();
    r.a.y = r.b.y - 1;
    r.a.x = r.b.x - 13;
    heap = new THeapView( r );
    insert( heap );
#endif



#ifdef CLOCKVIEW

    // Clock gadget


    r = getExtent();
    r.b.y = r.a.y + 1;
    r.a.x = r.b.x - 8;
    clock = new TClockView( r );
    insert( clock );
#endif


    // retrieveDesktop();


}


/**
 ** Destructor closes comm channel and deletes settings
 **/
TGIselApp::~TGIselApp()
{
  delete Settings;
  delete HomingSpeed;
  delete comm;
}        


/**
 ** Changes current directory
 **/
void TGIselApp::changeDir()
{
    execDialog( new TChDirDialog( cdNormal, 0 ), 0 );
}

/**
 ** Executes dos shell
 **/
void TGIselApp::dosShell()
{
    suspend();
    system("cls");
    cout << "Type EXIT to return...";
    system( getenv( "COMSPEC"));
    resume();
    redraw();
}

/*
 ** Executes Previewer
 **/
void TGIselApp::spawnPreviewer()
{   
    char fileName[MAXPATH];
    strcpy( fileName, "*.G" );

    if( execDialog( new TFileDialog( "*.*", "File to translate",
        "~N~ame", fdOpenButton, 100 ), fileName) != cmCancel )
      {
        if (access(fileName, 0) == 0) 
           {
#if 1

	     char command[MAXPATH+30] = "gviewer ";
	     strcat(command, fileName);
             cout << "Executing gviewer.exe " << fileName << endl;
	     suspend();
             system( command );
             resume();
             redraw();
#endif

           }
	else 
          {
            messageBox(mfOKButton | mfError, 
                     "Cannot open file: %s for preview.", fileName);
	  }
      }

}

/**
 ** Executes comm setup dialog
 **/
void TGIselApp::comSetup()
{
    TSetupDialog *t = (TSetupDialog *) validView( new TSetupDialog() );

    extern comData settings;
    if( t != 0 )
    {
        t->options |= ofCentered;
        t->setData( (void *) &settings);
        if( deskTop->execView( t ) != cmCancel )
            t->getData( (void *) &settings);
    }

    destroy(t);
}


/**
 ** Shows editior clipboard
 **/
void TGIselApp::showClip()
{
    clipWindow->select();
    clipWindow->show();
}

/**
 ** Tiles windows on the desktop
 **/
void TGIselApp::tile()
{
    deskTop->tile( deskTop->getExtent() );
}

/**
 ** Cascades windows on the desktop
 **/
void TGIselApp::cascade()
{
    deskTop->cascade( deskTop->getExtent() );
}


/**
 ** Main idle loop for background execution and pseudo multitasking.
 ** This routine is called after getEvent()
 **/
void TGIselApp::idle()
{
#ifdef HEAPVIEW

  heap->update();
#endif

#ifdef CLOCKVIEW

  clock->update();
#endif

  if (comm->isOpen())
    comm->update();
  if (positionWnd)
    positionWnd->update();
}

/**
 ** Opens terminal for direct command entry
 **/
void TGIselApp::terminal()
{
  
  TRect r = deskTop->getExtent();
  r.b.y -= 6;
  TView *t = validView( new TTermWindow(r, "Terminal Interaction", 
                                        TerminalWndNum ));
  if( t != 0 )
    {
      if (log == NULL)
        logOpen();
      deskTop->insert( t );
      t->helpCtx = hcTerminal;
    }
  else
    messageBox("Cannot open terminal.", mfOKButton);
}



/**
 ** Translates file with G-CODE
 **/
void TGIselApp::translateFile()
{
    if (trans)
      {
        messageBox("Translation already in progress.", mfOKButton);
        return;
      }
    
    char fileName[MAXPATH];
    strcpy( fileName, "*.G" );

    if( execDialog( new TFileDialog( "*.*", "File to translate",
        "~N~ame", fdOpenButton, 100 ), fileName) != cmCancel )
      {
        extern int Dongle();
        if (!Dongle())
          {
             messageBox(mfOKButton | mfError, 
                     "Sorry! This DEMO product is expired.\n"
                     "Please contact LECAD for licensing.");
             return;
          }
        if (access(fileName, 0) == 0)
          {
            trans = new Translate;
            TView *t = validView(trans);
            if(t != 0)
              {
                deskTop->insert(t);
                trans->translate(fileName);
                trans->helpCtx = hcTranslateFile;
              }
          }
        else
          messageBox(mfOKButton | mfError, 
                     "Cannot open file: %s for translation.", fileName);

      }
    
}


/**
 ** Calculator function
 **/
void TGIselApp::calculator()
{
    TCalculator *calc = (TCalculator *) validView(new TCalculator);

    if(calc != 0)
    {
        deskTop->insert(calc);
        calc->helpCtx = hcCalculator;
    }
}


/**
 ** Job Manager
 **/
void TGIselApp::jobManager()
{
    JobManager *jm = (JobManager *) validView(new JobManager);

    if(jm != 0)
    {
        deskTop->insert(jm);
        jm->helpCtx = hcJobManager;
    }
}


/**
 ** Opens position indicatior
 **/
void TGIselApp::showPosition()
{
  if (positionWnd)
    {
       messageBox("Position indicator already open", mfOKButton | mfError);
    }
  else
    {
      if (comm->open() != 0)
        {
          messageBox("Cannot open communication channel.", mfOKButton);
        }
      else
        {
            positionWnd = (PositionWnd *) validView(new PositionWnd);
            if(positionWnd != 0)
              {
                deskTop->insert(positionWnd);
                positionWnd->helpCtx = hcPosition;
              }
        }
    }
}


/**
 ** Opens Manual Motion windows
 **/
void TGIselApp::manualMotion()
{
    if (comm->open() != 0)
      {
        messageBox("Cannot open communication channel.", mfOKButton);
      }
    else
      {
        ManualMotion *control = (ManualMotion *) validView(new ManualMotion);

        if(control != 0)
          {
            if (!positionWnd)
              showPosition();
            deskTop->insert(control);
            control->helpCtx = hcManualMotion;
          }
      }
}



#ifdef EDITOR


/**
 ** Opens file for editing
 **/
void TGIselApp::fileOpen()
{
    char fileName[MAXPATH];
    strcpy( fileName, "*.*" );

    if( execDialog( new TFileDialog( "*.*", "Open file",
            "~N~ame", fdOpenButton, 100 ), fileName) != cmCancel )
        openEditor( fileName, True );
}

/**
 ** Opens unnamed window for editing
 **/
void TGIselApp::fileNew()
{
    openEditor( 0, True );
}


/**
 ** Opens file for editing
 **/
TEditWindow *TGIselApp::openEditor( const char *fileName, Boolean visible )
{
    TRect r = deskTop->getExtent();
    TView *p = validView( new TEditWindow( r, fileName, wnNoNumber ) );
    if( !visible )
        p->hide();
    deskTop->insert( p );
    return (TEditWindow *)p;
}

#endif



/**
 ** Opens communication log window.
 **/
void TGIselApp::logOpen()
{
  if (log == NULL)
    {
      TRect r = deskTop->getExtent();
      r.a.y = r.b.y - 5;

      log = new TLogWindow( r, "Controller Log Window", LogWindowWndNum, &log);
    
      TView *p = validView( log );
      if (p)
        {
          deskTop->insert( p );
          p->helpCtx = hcControllerLog;
        }
      else
        {
          if (log)
            {
               delete log;
               log = NULL;
            }
        }
    }
  else
    messageBox(mfOKButton, "Log window is allredy opened");
}



/**
 ** Event loop to check for context help request
 **/
void TGIselApp::getEvent(TEvent &event)
{
    TWindow *w;
    THelpFile *hFile;
    fpstream *helpStrm;
    static Boolean helpInUse = False;

    TApplication::getEvent(event);
    switch (event.what)
        {
        case evCommand:
            if ((event.message.command == cmHelp) && ( helpInUse == False)) 
                {
                helpInUse = True;
                helpStrm = new fpstream(HELP_FILENAME, ios::in|ios::binary);
                hFile = new THelpFile(*helpStrm);
                if (!helpStrm)
                    {
                    messageBox("Could not open help file", mfError | mfOKButton);
                    delete hFile;
                    }
                else
                    {
                    w = new THelpWindow(hFile, getHelpCtx());
                    if (validView(w) != 0)
                        {
                        execView(w);
                        destroy( w );
                        }
                    clearEvent(event);
                    }
                helpInUse = False;
                }
            break;
        case evMouseDown:
            if (event.mouse.buttons != 1)
                event.what = evNothing;
            break;
        }

}


/**
 ** Main Event handling routine
 **/
void TGIselApp::handleEvent( TEvent& event )
{
    TApplication::handleEvent( event );

    if( event.what != evCommand )
        return;
    else
      {
        switch( event.message.command )
            {
            case cmIntro:       // show intro 

              helpCtx = hcIntro;
              event.message.command = cmHelp;
              putEvent(event);
              getEvent(event);
              helpCtx = hcNoContext;
              break;
            case cmIndex:
              helpCtx = hcIndex;
              event.message.command = cmHelp;
              putEvent(event);
              getEvent(event);
              helpCtx = hcNoContext;
              break;
#ifdef EDITOR

            case cmOpen:
                fileOpen();
                break;

            case cmNew:
                fileNew();
                break;
#endif

            case cmChangeDrct:
                changeDir();
                break;

            case cmDosShell:
                dosShell();
                break;

            case cmPreview:
                spawnPreviewer();
                break;

            case cmShowClip:
                showClip();
                break;

            case cmTile:
                tile();
                break;

            case cmCascade:
                cascade();
                break;


            case cmAboutBox:
                execDialog( createAboutDialog(), 0 );
                break;

            case cmCalculator:
                calculator();
                break;

            case cmPositionCmd:
                showPosition();
                break;

            case cmComSetup:
                comSetup();
                break;

            case cmTerminal:
                if ( comm->clearToSend() )
                  terminal();
                break;

            case cmSaveCmd:             //  Save current desktop

                saveDesktop();
                break;

 
            case cmSaveSettings:        //  Save settings

                saveSettings();
                break;

            case cmRestoreCmd:          //  Restore saved desktop

                retrieveDesktop();
                break;

            case cmLogCmd:              //  Open Log window

                logOpen();
                break;

            case cmSettings:            //  Settings 

                execDialog(createSettingsDialog(), Settings);
                break;

            case cmHomingSpeed:         //  Homming Speed 

                if ( comm->clearToSend() )
                  execDialog(createHomingSpeedDialog(), HomingSpeed);
                break;

            case cmMachining:          //  Machining I/O

                
                {
                  TMachining *m = (TMachining *) validView(new TMachining);
                  if(m != 0)
                   {
                    deskTop->insert(m);
                    m->helpCtx = hcMachining;
                   }
                }
                break;

            case cmJobManagerCmd:
                jobManager();
                break;

            case cmHomeCmd:
                if ( comm->clearToSend() )
                  HomeMotors();
                break;

            case cmManualMotion:
                if ( comm->clearToSend() )
                  manualMotion();
                break;

            case cmZeroAbsolute:
                if ( comm->clearToSend() )
                  ZeroAbsolute();
                break;

            case cmTranslateFile:
                if ( comm->clearToSend() )
                  translateFile();
                break;


            default:
                return ;
            }
        clearEvent( event );
      }
}


/**
 ** Saves settings to INI file
 **/
void TGIselApp::saveSettings()
{
  extern comData settings;
  char buffer[80];
  writeIniString(CSECT, "Port", itoa(settings.getComPort(), buffer, 10));
  writeIniString(CSECT, "Baud", itoa(settings.getBaud(), buffer, 10));
  writeIniString(CSECT, "DataBits", itoa(settings.getDataBits(), buffer, 10));
  writeIniString(CSECT, "StopBits", itoa(settings.getStopBits(), buffer, 10));
  writeIniString(CSECT, "Parity", itoa(settings.getParityNum(), buffer, 10));
  #define STEPS_SECTION "StepsPerUnit"

  writeIniString(STEPS_SECTION, "CoordinateX", ltoa(Settings->spuX, buffer, 10) );
  writeIniString(STEPS_SECTION, "CoordinateY", ltoa(Settings->spuY, buffer, 10) );
  writeIniString(STEPS_SECTION, "CoordinateZ", ltoa(Settings->spuZ, buffer, 10) );
  #define SPEED_SECTION "ManualStepsPerSecond"

  writeIniString(SPEED_SECTION, "CoordinateX", ltoa(Settings->speedX, buffer, 10) );
  writeIniString(SPEED_SECTION, "CoordinateY", ltoa(Settings->speedY, buffer, 10) );
  writeIniString(SPEED_SECTION, "CoordinateZ", ltoa(Settings->speedZ, buffer, 10) );
  #define DEVICE_SECTION "Device"

  writeIniString(DEVICE_SECTION, "DeviceNumber", ltoa(Settings->device, buffer, 10) );
  writeIniString(DEVICE_SECTION, "CommandAcknowledge", ltoa(Settings->ack, buffer, 10) );
  writeIniString(DEVICE_SECTION, "ManualStepSize", ltoa(Settings->stepSize, buffer, 10) );
  writeIniString(DEVICE_SECTION, "ZAxisRatio", ltoa(Settings->ratioZ, buffer, 10) );
  writeIniString(DEVICE_SECTION, "Options", ltoa(Settings->option, buffer, 10) );
  writeIniString(DEVICE_SECTION, "LogFileName", Settings->logFileName);

  #define HOMING_SECTION "HomingSpeed"

  writeIniString(HOMING_SECTION, "XStepsPerSec", ltoa(HomingSpeed->x, buffer, 10));
  writeIniString(HOMING_SECTION, "YStepsPerSec", ltoa(HomingSpeed->y, buffer, 10));
  writeIniString(HOMING_SECTION, "ZStepsPerSec", ltoa(HomingSpeed->z, buffer, 10));
}



/**
 ** Reads initial settings and runs application.
 **/
void TGIselApp::run()
{

    strcpy(IniFile, INIFILENAME);

    if (access(IniFile, 0) != 0)
       execDialog( createAboutDialog(), 0 );

    extern comData settings;
    settings.setPort(getIniInt(CSECT, "Port", 1));
    settings.setBaud(getIniInt(CSECT, "Baud", 9600));
    settings.setDataBits(getIniInt(CSECT, "DataBits", 8));
    settings.setStopBits(getIniInt(CSECT, "StopBits", 1));
    settings.setParity(getIniInt(CSECT, "Parity", P_NONE));

    #define STEPS_SECTION "StepsPerUnit"

    Settings->spuX = getIniInt(STEPS_SECTION, "CoordinateX", 80);
    Settings->spuY = getIniInt(STEPS_SECTION, "CoordinateY", 80);
    Settings->spuZ = getIniInt(STEPS_SECTION, "CoordinateZ", 80);
    #define SPEED_SECTION "ManualStepsPerSecond"

    Settings->speedX = getIniInt(SPEED_SECTION, "CoordinateX", 3500);
    Settings->speedY = getIniInt(SPEED_SECTION, "CoordinateY", 3500);
    Settings->speedZ = getIniInt(SPEED_SECTION, "CoordinateZ", 1000);
    #define DEVICE_SECTION "Device"

    Settings->device = getIniInt(DEVICE_SECTION, "DeviceNumber", 0);
    Settings->ack = getIniInt(DEVICE_SECTION, "CommandAcknowledge", 0);
    Settings->stepSize = getIniInt(DEVICE_SECTION, "ManualStepSize", 8000);
    Settings->ratioZ = getIniInt(DEVICE_SECTION, "ZAxisRatio", 10);
    Settings->option = getIniInt(DEVICE_SECTION, "Options", 4);
    getIniString(DEVICE_SECTION, "LogFileName", "gisel.log", 
                 Settings->logFileName);

    #define HOMING_SECTION "HomingSpeed"

    HomingSpeed->x = getIniInt(HOMING_SECTION, "XStepsPerSec", 3500);
    HomingSpeed->y = getIniInt(HOMING_SECTION, "YStepsPerSec", 3500);
    HomingSpeed->z = getIniInt(HOMING_SECTION, "ZStepsPerSec", 3500);

    Machining.ReadINI(IniFile);

    TProgram::run();
}

/*
 * Main program
 */

int main(int argc, char **argv)
{
    // ExpirationTime(argv[0]);

    TGIselApp *app = new TGIselApp(argc, argv);
    app->run();
    TObject::destroy( app );
    return 0;
}




syntax highlighted by Code2HTML, v. 0.9.1