/* $Id: MANUAL.CPP 2.4 1995/07/20 11:24:33 leon Exp $
 */

#define Uses_TEvent

#define Uses_MsgBox

#include <tvision/tv.h>


#if !defined( __MANUAL_H )

#include "manual.h"

#endif


#include <stdio.h>


#include "comm.h"

#include "gisel.h"

#include "config.h"

#include "position.h"


/** global communication channel **/
extern Comm *comm;
/** current position in steps **/
extern long position[3];
/** Position window indicator **/
extern PositionWnd *positionWnd;
/** Global Settings **/
extern SettingsRec *Settings;

/**
 ** Creates manual motion window with buttons for manual driveing
 **/
ManualMotion::ManualMotion() :
       TDialog(TRect(45, 2, 76, 20), "Manual motion"),
       TWindowInit(ManualMotion::initFrame)

{
 TView *control;

 number = ManualMotionWndNum;

 control = new TButton(TRect(11, 15, 21, 17), "O~K~", cmOK, bfDefault);
 insert(control);

 control = new TButton(TRect(2, 5, 11, 7), "Step \x10", cmSplus, bfNormal);
 insert(control);

 control = new TButton(TRect(2, 7, 11, 9), "Step \x11", cmSminus, bfNormal);
 insert(control);

 control = new TButton(TRect(11, 7, 20, 9), "~S~peed", cmSpeed, bfNormal);
 insert(control);

 control = new TButton(TRect(11, 5, 20, 7), "~G~o To", cmGoTo, bfNormal);
 insert(control);

 control = new TButton(TRect(20, 5, 29, 7), "Z \x1E", cmZminus, bfNormal);
 insert(control);

 control = new TButton(TRect(20, 7, 29, 9), "Z \x1F", cmZplus, bfNormal);
 insert(control);

 control = new TButton(TRect(2, 12, 11, 14), "Y \x1B", cmYminus, bfNormal);
 insert(control);

 control = new TButton(TRect(20, 12, 29, 14), "Y \x1A", cmYplus, bfNormal);
 insert(control);

 control = new TButton(TRect(11, 10, 20, 12), "X \x18", cmXminus, bfNormal);
 insert(control);

 control = new TButton(TRect(11, 12, 20, 14), "X \x19", cmXplus, bfNormal);
 insert(control);

 stepScroll = new TScrollBar(TRect(3, 3, 28, 4));
 insert(stepScroll);

   insert(new TLabel(TRect(3, 2, 13, 3), "Step size", stepScroll));

 stepSize = new TInputDouble(TRect(14, 2, 24, 3), 8, 0.001, 1000.0); // Step limits

 insert(stepSize);

   insert(new TLabel(TRect(25, 2, 28, 3), "mm", control));

 double ssize = double(Settings->stepSize)/ double(Settings->spuX);
 stepSize->setData(&ssize);

 selectNext(False);
}


/**
 ** Moves in direction with respect of the given command.
 **/
void ManualMotion::moveInDirection(short direction)
{
  double ssize;

  if( comm->getReply() < 0)
    return;

  stepSize->getData(&ssize);

  switch (direction)
    {
      case cmXplus:
        position[0] += long(ssize * double(Settings->spuX));
        break;
      case cmXminus:
        position[0] -= long(ssize * double(Settings->spuX));
        break;
      case cmYplus:
        position[1] += long(ssize * double(Settings->spuY));
        break;
      case cmYminus:
        position[1] -= long(ssize * double(Settings->spuY));
        break;
      case cmZplus:
        if (ssize > double(Settings->ratioZ))
          ssize = double(Settings->ratioZ);
        position[2] += long(ssize * double(Settings->spuZ));
        break;
      case cmZminus:
        if (ssize > double(Settings->ratioZ))
          ssize = double(Settings->ratioZ);
        position[2] -= long(ssize * double(Settings->spuZ));
        break;
    }
    static char command[80];
    sprintf(command, "@%ldM%ld,%ld,%ld,%ld,%ld,%ld,0,30",
    	 Settings->device,
	 position[0],
	 long (double(Settings->speedX) * (ssize <= 10.0 ? 0.5 : 1.0)) ,
	 position[1],
	 long (double(Settings->speedY) * (ssize <= 10.0 ? 0.5 : 1.0)) ,
	 position[2],
	 long (double(Settings->speedZ) * (ssize < 10.0 ? 0.5 : 1.0)) );
    comm->sendCommand(command);
}

/**
 ** Changes step size for manual motion. Step change is in decade.
 **/
void ManualMotion::stepChange(ushort cmd)
{
  double ssize;

  stepSize->getData(&ssize);

  switch (cmd)
    {
      case cmSplus:
        ssize *= 10.0;
        break;
      case cmSminus:
        ssize /= 10.0;
        break;
    }
  stepSize->setData(&ssize);
  stepSize->valid(cmOK);
  stepSize->draw();
}

/**
 ** Handles manual motion events (button commands and keyboard)
 **/
void ManualMotion::handleEvent( TEvent& event)
{
    TDialog::handleEvent(event);

    switch (event.what)
      {
        case evKeyboard:
          switch (event.keyDown.keyCode)
            {
              case kbPgUp:
                moveInDirection(cmZminus);
                break;
              case kbPgDn:
                moveInDirection(cmZplus);
                break;
              case kbLeft:
                moveInDirection(cmYminus);
                break;
              case kbRight:
	              moveInDirection(cmYplus);
            		break;
      	      case kbUp:
	              moveInDirection(cmXminus);
            		break;
      	      case kbDown:
	              moveInDirection(cmXplus);
            		break;
        	    case kbIns:
	              stepChange(cmSplus);
            		break;
      	      case kbDel:
      	        stepChange(cmSminus);
           		break;
            }
          break;

        case evCommand:
          switch( event.message.command )
            {
              case cmOK:
                close();
                break;
              case cmXplus:
              case cmYplus:
              case cmZplus:
              case cmXminus:
              case cmYminus:
              case cmZminus:
                moveInDirection(event.message.command);
                break;
      	      case cmSplus:
      	      case cmSminus:
	              stepChange(event.message.command);
            		break;
            }
        default:
          return;
      }
      clearEvent(event);
}

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

/** Writes stream **/
void ManualMotion::write( opstream& os )
{
 TDialog::write( os );
 os << stepScroll;
}

/** Reads stream **/
void *ManualMotion::read( ipstream& is )
{
 TDialog::read( is );
 is >> stepScroll;
 return this;
}

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

TStreamableClass RanualMotion( ManualMotion::name,
                        ManualMotion::build,
                        __DELTA(ManualMotion)
                      );

__link(RanualMotion)
__link(RButton)
__link(RInputLine)
__link(RLabel)
__link(RScrollBar)


syntax highlighted by Code2HTML, v. 0.9.1