// $Source: /usr/local/SimSoft/Sfx3D/src/gts/gtscb.cpp,v $
// $Revision: 1.2 $
// $Author: baum $
// $Date: 2001/11/29 15:18:10 $
//
// Login name of the user who locked the revision
// $Locker:  $
// Tag name used to checkout the file
// $Name: Release-14 $
// State assigned to revision
// $State: Exp $
//
//
// $Log: gtscb.cpp,v $
// Revision 1.2  2001/11/29 15:18:10  baum
// -Realzeitsteuerung eingebaut
// -Handsteuerung eingebaut
//

#ifdef WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN
#include <winnt.h>
#endif /*WIN32*/

#ifdef __linux
#include <typeinfo>
#else
#include <typeinfo.h>
#endif

#include "XGraph/Select.h"
#include "XGraph/Parent.h"
#include "XGraph/GeoObj.h"
#include "XGraph/Space.h"

#include "XGraph/AllViews.h"

// hope everybody has install Tcl/Tk
#include "X11/X.h"
#include "tk.h"
#include "gtsglob.h"
#include "gtsgui.h"
#include "gtsbst.h"
#include "gtstfk.h"
#include "gtsgraf.h"

#define _GTSCALLBACK_CPP
#include "gtscb.h"

#include "MathDefs.h"
#include "Angle.h"
#include "Vec3D.h"
#include "HMatrx3D.h"



static unsigned cz = 0;
void cursortest(OGLView* view)
{
/* $XConsortium: cursorfont.h,v 1.2 88/09/06 16:44:27 jim Exp $ */
  cz++;
  switch (cz)
  {
    case  1 : sprintf (DlgBuffer, "%s configure -cursor num_glyphs", ((ToglView*)view)->WidgetName ()); break;
    case  2 : sprintf (DlgBuffer, "%s configure -cursor X_cursor", ((ToglView*)view)->WidgetName ());
    case  3 : sprintf (DlgBuffer, "%s configure -cursor arrow", ((ToglView*)view)->WidgetName ()); break;
    case  4 : sprintf (DlgBuffer, "%s configure -cursor based_arrow_down", ((ToglView*)view)->WidgetName ()); break;
    case  5 : sprintf (DlgBuffer, "%s configure -cursor based_arrow_up", ((ToglView*)view)->WidgetName ()); break;
    case  6 : sprintf (DlgBuffer, "%s configure -cursor boat", ((ToglView*)view)->WidgetName ()); break;
    case  7 : sprintf (DlgBuffer, "%s configure -cursor bogosity", ((ToglView*)view)->WidgetName ()); break;
    case  8 : sprintf (DlgBuffer, "%s configure -cursor bottom_left_corner", ((ToglView*)view)->WidgetName ()); break;
    case  9 : sprintf (DlgBuffer, "%s configure -cursor bottom_right_corner", ((ToglView*)view)->WidgetName ()); break;
    case 10 : sprintf (DlgBuffer, "%s configure -cursor bottom_side", ((ToglView*)view)->WidgetName ()); break;
    case 11 : sprintf (DlgBuffer, "%s configure -cursor bottom_tee", ((ToglView*)view)->WidgetName ()); break;
    case 12 : sprintf (DlgBuffer, "%s configure -cursor box_spiral", ((ToglView*)view)->WidgetName ()); break;
    case 13 : sprintf (DlgBuffer, "%s configure -cursor center_ptr", ((ToglView*)view)->WidgetName ()); break;
    case 14 : sprintf (DlgBuffer, "%s configure -cursor circle", ((ToglView*)view)->WidgetName ()); break;
    case 15 : sprintf (DlgBuffer, "%s configure -cursor clock", ((ToglView*)view)->WidgetName ()); break;
    case 16 : sprintf (DlgBuffer, "%s configure -cursor coffee_mug", ((ToglView*)view)->WidgetName ()); break;
    case 17 : sprintf (DlgBuffer, "%s configure -cursor cross", ((ToglView*)view)->WidgetName ()); break;
    case 18 : sprintf (DlgBuffer, "%s configure -cursor cross_reverse", ((ToglView*)view)->WidgetName ()); break;
    case 19 : sprintf (DlgBuffer, "%s configure -cursor crosshair", ((ToglView*)view)->WidgetName ()); break;
    case 20 : sprintf (DlgBuffer, "%s configure -cursor diamond_cross", ((ToglView*)view)->WidgetName ()); break;
    case 21 : sprintf (DlgBuffer, "%s configure -cursor dot", ((ToglView*)view)->WidgetName ()); break;
    case 22 : sprintf (DlgBuffer, "%s configure -cursor dotbox", ((ToglView*)view)->WidgetName ()); break;
    case 23 : sprintf (DlgBuffer, "%s configure -cursor double_arrow", ((ToglView*)view)->WidgetName ()); break;
    case 24 : sprintf (DlgBuffer, "%s configure -cursor draft_large", ((ToglView*)view)->WidgetName ()); break;
    case 25 : sprintf (DlgBuffer, "%s configure -cursor draft_small", ((ToglView*)view)->WidgetName ()); break;
    case 26 : sprintf (DlgBuffer, "%s configure -cursor draped_box", ((ToglView*)view)->WidgetName ()); break;
    case 27 : sprintf (DlgBuffer, "%s configure -cursor exchange", ((ToglView*)view)->WidgetName ()); break;
    case 28 : sprintf (DlgBuffer, "%s configure -cursor fleur", ((ToglView*)view)->WidgetName ()); break;
    case 29 : sprintf (DlgBuffer, "%s configure -cursor gobbler", ((ToglView*)view)->WidgetName ()); break;
    case 30 : sprintf (DlgBuffer, "%s configure -cursor gumby", ((ToglView*)view)->WidgetName ()); break;
    case 31 : sprintf (DlgBuffer, "%s configure -cursor hand1", ((ToglView*)view)->WidgetName ()); break;
    case 32 : sprintf (DlgBuffer, "%s configure -cursor hand2", ((ToglView*)view)->WidgetName ()); break;
    case 33 : sprintf (DlgBuffer, "%s configure -cursor heart", ((ToglView*)view)->WidgetName ()); break;
    case 34 : sprintf (DlgBuffer, "%s configure -cursor icon", ((ToglView*)view)->WidgetName ()); break;
    case 35 : sprintf (DlgBuffer, "%s configure -cursor iron_cross", ((ToglView*)view)->WidgetName ()); break;
    case 36 : sprintf (DlgBuffer, "%s configure -cursor left_ptr", ((ToglView*)view)->WidgetName ()); break;
    case 37 : sprintf (DlgBuffer, "%s configure -cursor left_side", ((ToglView*)view)->WidgetName ()); break;
    case 38 : sprintf (DlgBuffer, "%s configure -cursor left_tee", ((ToglView*)view)->WidgetName ()); break;
    case 39 : sprintf (DlgBuffer, "%s configure -cursor leftbutton", ((ToglView*)view)->WidgetName ()); break;
    case 40 : sprintf (DlgBuffer, "%s configure -cursor ll_angle", ((ToglView*)view)->WidgetName ()); break;
    case 41 : sprintf (DlgBuffer, "%s configure -cursor lr_angle", ((ToglView*)view)->WidgetName ()); break;
    case 42 : sprintf (DlgBuffer, "%s configure -cursor man", ((ToglView*)view)->WidgetName ()); break;
    case 43 : sprintf (DlgBuffer, "%s configure -cursor middlebutton", ((ToglView*)view)->WidgetName ()); break;
    case 44 : sprintf (DlgBuffer, "%s configure -cursor mouse", ((ToglView*)view)->WidgetName ()); break;
    case 45 : sprintf (DlgBuffer, "%s configure -cursor pencil", ((ToglView*)view)->WidgetName ()); break;
    case 46 : sprintf (DlgBuffer, "%s configure -cursor pirate", ((ToglView*)view)->WidgetName ()); break;
    case 47 : sprintf (DlgBuffer, "%s configure -cursor plus", ((ToglView*)view)->WidgetName ()); break;
    case 48 : sprintf (DlgBuffer, "%s configure -cursor question_arrow", ((ToglView*)view)->WidgetName ()); break;
    case 49 : sprintf (DlgBuffer, "%s configure -cursor right_ptr", ((ToglView*)view)->WidgetName ()); break;
    case 50 : sprintf (DlgBuffer, "%s configure -cursor right_side", ((ToglView*)view)->WidgetName ()); break;
    case 51 : sprintf (DlgBuffer, "%s configure -cursor right_tee", ((ToglView*)view)->WidgetName ()); break;
    case 52 : sprintf (DlgBuffer, "%s configure -cursor rightbutton", ((ToglView*)view)->WidgetName ()); break;
    case 53 : sprintf (DlgBuffer, "%s configure -cursor rtl_logo", ((ToglView*)view)->WidgetName ()); break;
    case 54 : sprintf (DlgBuffer, "%s configure -cursor sailboat", ((ToglView*)view)->WidgetName ()); break;
    case 55 : sprintf (DlgBuffer, "%s configure -cursor sb_down_arrow", ((ToglView*)view)->WidgetName ()); break;
    case 56 : sprintf (DlgBuffer, "%s configure -cursor sb_h_double_arrow", ((ToglView*)view)->WidgetName ()); break;
    case 57 : sprintf (DlgBuffer, "%s configure -cursor sb_left_arrow", ((ToglView*)view)->WidgetName ()); break;
    case 58 : sprintf (DlgBuffer, "%s configure -cursor sb_right_arrow", ((ToglView*)view)->WidgetName ()); break;
    case 59 : sprintf (DlgBuffer, "%s configure -cursor sb_up_arrow", ((ToglView*)view)->WidgetName ()); break;
    case 60 : sprintf (DlgBuffer, "%s configure -cursor sb_v_double_arrow", ((ToglView*)view)->WidgetName ()); break;
    case 61 : sprintf (DlgBuffer, "%s configure -cursor shuttle", ((ToglView*)view)->WidgetName ()); break;
    case 62 : sprintf (DlgBuffer, "%s configure -cursor sizing", ((ToglView*)view)->WidgetName ()); break;
    case 63 : sprintf (DlgBuffer, "%s configure -cursor spider", ((ToglView*)view)->WidgetName ()); break;
    case 64 : sprintf (DlgBuffer, "%s configure -cursor spraycan", ((ToglView*)view)->WidgetName ()); break;
    case 65 : sprintf (DlgBuffer, "%s configure -cursor star", ((ToglView*)view)->WidgetName ()); break;
    case 66 : sprintf (DlgBuffer, "%s configure -cursor target", ((ToglView*)view)->WidgetName ()); break;
    case 67 : sprintf (DlgBuffer, "%s configure -cursor tcross", ((ToglView*)view)->WidgetName ()); break;
    case 68 : sprintf (DlgBuffer, "%s configure -cursor top_left_arrow", ((ToglView*)view)->WidgetName ()); break;
    case 69 : sprintf (DlgBuffer, "%s configure -cursor top_left_corner", ((ToglView*)view)->WidgetName ()); break;
    case 70 : sprintf (DlgBuffer, "%s configure -cursor top_right_corner", ((ToglView*)view)->WidgetName ()); break;
    case 71 : sprintf (DlgBuffer, "%s configure -cursor top_side", ((ToglView*)view)->WidgetName ()); break;
    case 72 : sprintf (DlgBuffer, "%s configure -cursor top_tee", ((ToglView*)view)->WidgetName ()); break;
    case 73 : sprintf (DlgBuffer, "%s configure -cursor trek", ((ToglView*)view)->WidgetName ()); break;
    case 74 : sprintf (DlgBuffer, "%s configure -cursor ul_angle", ((ToglView*)view)->WidgetName ()); break;
    case 75 : sprintf (DlgBuffer, "%s configure -cursor umbrella", ((ToglView*)view)->WidgetName ()); break;
    case 76 : sprintf (DlgBuffer, "%s configure -cursor ur_angle", ((ToglView*)view)->WidgetName ()); break;
    case 77 : sprintf (DlgBuffer, "%s configure -cursor watch", ((ToglView*)view)->WidgetName ()); break;
    case 78 : sprintf (DlgBuffer, "%s configure -cursor xterm", ((ToglView*)view)->WidgetName ()); break;
    default: break;
  }
    Tcl_GlobalEval (GTSInterpreter, DlgBuffer);
    sprintf (DlgBuffer, "Cursor=%d\n", cz);
    Meld.Ausgabe (DlgBuffer);
};


//==================================================================
//		Declaration
//		for class GTSCallback
//==================================================================

/*static*/ Pattern *GTSCallback::ClassRedRect;
/*static*/ Pattern *GTSCallback::ClassBlueRect;
           Vec3D TmpPos;

// constructor
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
GTSCallback::GTSCallback ()
  : OGLViewCallback    (),
    ObjStartX          (0),
    ObjStartY          (0),
    ObjStartZ          (0),
    ObjStartVec        (),
    ObjCursor          (0),
    ObjActivCursor     ("arrow"),
    ObjPassivCursor    ("arrow"),
    ObjMoveStep        (0.1), // 10 cm
    ObjAngleStep       (5),   // 5 Grad-Schritte
    ObjZoomRect        (),
    ObjActSelection    (NULL),
    ObjBoxZeichnen     (false),
    ObjDrehen          (false),
    ObjButtonHandling  (moveButton),
    ObjMotionHandling  (moveMotion),
    ObjPassiveHandling (selectPassive)
{
  Attribute *red   = ColorAttribute::create ("red");
  red->setName ("_ZoomRedAttr");
  Attribute *blue   = ColorAttribute::create ("blue");
  red->setName ("_ZoomBlueAttr");

  Primitive *p = LineQuad::create (Vec2D (), Vec2D (1.0, 1.0));
  p->setName ("_ZoomCubePrim");
  GeoPattern *red_gp = GeoPattern::create (*p, *red);
  red_gp->setName ("_ZoomRedGeoPat");
  GeoPattern *blue_gp = GeoPattern::create (*p, *blue);
  blue_gp->setName ("_ZoomBlueGeoPat");

  ClassRedRect   = Pattern::create (*red_gp);
  ClassRedRect->setName ("_ZoomRedPat");
  ClassRedRect->incRef ();

  ClassBlueRect   = Pattern::create (*blue_gp);
  ClassBlueRect->setName ("_ZoomBluePat");
  ClassBlueRect->incRef ();

  ObjZoomRect.insert (*(ClassRedRect));
}  // ENDE  konstructor

// destructor
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
GTSCallback::~GTSCallback ()
{
  ObjZoomRect.remove (*(ClassRedRect));
  ClassRedRect->dispose();
  ClassBlueRect->dispose();
  Pattern::clean ();
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::setMoveStep (float movestep)
{
    ObjMoveStep = movestep;
} // ENDE  setMoveStep

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
float GTSCallback::getMoveStep ()
{
    return ObjMoveStep;
} // ENDE  getMoveStep

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::setAngleStep (unsigned anglestep)
{
    ObjAngleStep = anglestep;
} // ENDE  setAngleStep

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Angle GTSCallback::getAngleStep ()
{
    return ObjAngleStep;
} // ENDE  getAngleStep

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::updateCursor (OGLView *view, unsigned activ)
{
  if (activ)
  {
    if (!ObjCursor)
    {
      sprintf (DlgBuffer, "%s configure -cursor %s",
               ((ToglView*)view)->WidgetName (), ObjActivCursor.str());
      Tcl_GlobalEval (GTSInterpreter, DlgBuffer);
      view->MySpace()->flushAllViews();
    }
  }
  else
  {
    if (ObjCursor)
    {
      sprintf (DlgBuffer, "%s configure -cursor %s",
               ((ToglView*)view)->WidgetName (), ObjPassivCursor.str());
      Tcl_GlobalEval (GTSInterpreter, DlgBuffer);
      view->MySpace()->flushAllViews();
    }
  }
  ObjCursor = activ;
}  // ENDE updateCursor

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::setActivCursor (OGLView *view, Ustring cursor)
{
  ObjActivCursor = cursor;
  updateCursor (view, 1);
}  // ENDE setActivCursor

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::setPassivCursor (OGLView *view, Ustring cursor)
{
  ObjPassivCursor = cursor;
  updateCursor (view, 0);
}  // ENDE setPassivCursor

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::MenueInfoBaustein (const GeoObject* zgeo)
{
  typBaustein* zbst = GTSMAP.findKey (*zgeo);
  if (zbst) {
    if (ModellRelease > 0) {
       sprintf  (DlgBuffer, "BalloonInfo_show %d %d %d %d %5.3f %5.3f %5.3f %d %d %d",
                          ObjStartX, ObjStartY,
                          zbst->i_BstNr(), zbst->i_BstTyp(),
                          zbst->i_xKoor(), zbst->i_yKoor(),
                          zbst->i_zKoor(), zbst->i_xWinkel(),
                          zbst->i_yKoor(), zbst->i_zWinkel());
    } else {
    sprintf  (DlgBuffer, "BalloonInfo_show %d %d %d %d %5.3f %5.3f %5.3f %d",
                          ObjStartX, ObjStartY,
                          zbst->i_BstNr(), zbst->i_BstTyp(),
                          zbst->i_xKoor(), zbst->i_yKoor(),
                          zbst->i_zKoor(), zbst->i_zWinkel());
    }
    Tcl_Eval (GTSInterpreter, DlgBuffer);
  }
}  // ENDE MenueInfoBaustein

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::beginZoomRect (GTSCallback *who, OGLView *view, int x, int y)
{
  who->ObjStartX = x;
  who->ObjStartY = y;
  who->ObjZoomRect.setPos (view->Camera()->PositionFromPixels (x, y));
  who->ObjZoomRect.setXTo (view->Camera()->ViewDir ().cross (view->Camera()->CameraUp ()));
  who->ObjZoomRect.setZTo (-view->Camera()->ViewDir ());
  who->ObjZoomRect.setScale (Vec3D (0.01, 0.01, 0.01));
  who->ObjZoomRect.setParent (*(view->MySpace()));
  view->flush ();
  setActivCursor  (GTSView, "crosshair");
  setPassivCursor (GTSView, "crosshair");
}  //  ENDE  beginZoomRect
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::drawZoomRect (GTSCallback *who, OGLView *view, int x, int y)
{
  Vec3D xLen (view->Camera()->VectorFromPixels (fabs (x - who->ObjStartX), 0));
  Vec3D yLen (view->Camera()->VectorFromPixels (0, fabs (y - who->ObjStartY)));
  who->ObjZoomRect.setPos (view->Camera()->PositionFromPixels (Min (x, who->ObjStartX), Max (y, who->ObjStartY)));
  who->ObjZoomRect.setScale (Vec3D (xLen.len (), yLen.len (), 1.0));
  view->flush ();
}  //  ENDE  drawZoomRect

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::endZoomRect (GTSCallback *who, OGLView *view, int x, int y)
{
  WrapBox box;
  box.adjust (view->Camera()->PositionFromPixels (who->ObjStartX, who->ObjStartY));
  box.adjust (view->Camera()->PositionFromPixels (x, y));
  box.sort ();
  Vec3D focus = box.Min + ((box.Max - box.Min) * 0.5);
  Vec3D distance = Vec3D (view->Camera ()->ViewDir ().unit () *
                         (((box.Max - box.Min)).len () /
                         (Angle (view->Camera ()->VisualAngle ()).tan ())));
  view->Camera ()->setCamera (focus - distance, focus, view->Camera ()->CameraUp ());
  who->ObjZoomRect.clearParent (0);
  who->setToObjectMoving ();
  Tcl_Eval (GTSInterpreter,(char*)Ustring("SetzAktMenueStatus {.knoeppe.pfeil}").str());
  view->flush ();
  setActivCursor  (view, "fleur");
  setPassivCursor (view, "arrow");
}  //  ENDE  endZoomRect

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::beginSelectRect (GTSCallback *who, OGLView *view, int x, int y)
{
  beginZoomRect (who, view, x, y);
  who->ObjBoxZeichnen = true;
}  //  ENDE  beginSelectRect
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::drawSelectRect (GTSCallback *who, OGLView *view, int x, int y)
{
  if (who->ObjStartY > y)
    if (ObjZoomRect.PattArray ().First () != ClassRedRect) {
      ObjZoomRect.remove (*(ClassBlueRect));
      ObjZoomRect.insert (*(ClassRedRect));
    }
  if (who->ObjStartY <= y)
    if (ObjZoomRect.PattArray ().First () != ClassBlueRect) {
      ObjZoomRect.remove (*(ClassRedRect));
      ObjZoomRect.insert (*(ClassBlueRect));
    }

  drawZoomRect (who, view, x, y);
}  //  ENDE  drawSelectRect

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::endSelectRect (GTSCallback *who, OGLView *view, int x, int y, const bool shift)
{
  WrapBox box;
  who->ObjBoxZeichnen = false;
  box.adjust (view->Camera()->PositionFromPixels (who->ObjStartX, who->ObjStartY));
  box.adjust (view->Camera()->PositionFromPixels (x, y));
  box.sort ();
  who->ObjZoomRect.clearParent (0);
  who->setToObjectMoving ();
  view->flush ();
  if ((who->ObjStartY > y)) {
    BausteinListe->selectBausteine (box, 0, shift);
  }
  else {
    ObjZoomRect.remove (*(ClassBlueRect));
    ObjZoomRect.insert (*(ClassRedRect));
    BausteinListe->selectBausteine (box, 1, shift);
  }

  if (view->MySpace()->MySelection()->SelectedObjects().Count()) {
    Tcl_Eval (GTSInterpreter,(char*)Ustring("SetzBstButton {active}").str());
    if (view->MySpace()->MySelection()->SelectedObjects().Count() > 1)
       Tcl_Eval (GTSInterpreter,(char*)Ustring("SetzAusrichtButton {active}").str());
  }
  else {
    Tcl_Eval (GTSInterpreter,(char*)Ustring("SetzAusrichtButton {disabled}").str());
    Tcl_Eval (GTSInterpreter,(char*)Ustring("SetzBstButton {disabled}").str());
  }
}  //  ENDE  endSelectRect

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::setToObjectMoving   () {
  ObjButtonHandling = moveButton;
  ObjMotionHandling = moveMotion;
  Meld.deleteSpeicher();
  Meld.deleteStatusZeile();
  setActivCursor  (GTSView, "fleur");
  setPassivCursor (GTSView, "arrow");
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::setToObjectRotation () {
  ObjButtonHandling = rotateButton;
  ObjMotionHandling = rotateMotion;
  Meld.deleteSpeicher();
  setActivCursor  (GTSView, "exchange");
  setPassivCursor (GTSView, "exchange");
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::setToZooming () {
  ObjButtonHandling = zoomButton;
  ObjMotionHandling = zoomMotion;
  Meld.deleteSpeicher();
  setActivCursor  (GTSView, "tcross");
  setPassivCursor (GTSView, "tcross");
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::setToCamera () {
  ObjButtonHandling = camButton;
  ObjMotionHandling = camMotion;
  Meld.deleteSpeicher();
  setActivCursor  (GTSView, "hand1");
  setPassivCursor (GTSView, "hand1");
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::setToNewCombining () {
  ObjButtonHandling = combErzeugeButton;
  ObjMotionHandling = combMotion;
  Meld.deleteSpeicher();
  GTSSpace->MySelection()->removeAll();
  GTSSpace->flushAllViews();
  setActivCursor  (GTSView, "hand2");
  setPassivCursor (GTSView, "hand2");
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::setToDeleteCombining () {
  ObjButtonHandling = combLoescheButton;
  ObjMotionHandling = combMotion;
  Meld.deleteSpeicher();
  GTSSpace->MySelection()->removeAll();
  GTSSpace->flushAllViews();
  setActivCursor  (GTSView, "hand2");
  setPassivCursor (GTSView, "hand2");
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::setToInfoCombining () {
  ObjButtonHandling = combInfoButton;
  ObjMotionHandling = combMotion;
  Meld.deleteSpeicher();
  GTSSpace->MySelection()->removeAll();
  GTSSpace->flushAllViews();
  setActivCursor  (GTSView, "hand2");
  setPassivCursor (GTSView, "hand2");
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::setToNewRouting () {
  ObjButtonHandling = routeErzeugeButton;
  ObjMotionHandling = routeMotion;
  Meld.deleteSpeicher();
  GTSSpace->MySelection()->removeAll();
  GTSSpace->flushAllViews();
  EndeEingabe = false;
  setActivCursor  (GTSView, "hand2");
  setPassivCursor (GTSView, "hand2");
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::setToDeleteRouting () {
  ObjButtonHandling = routeLoescheButton;
  ObjMotionHandling = routeMotion;
  Meld.deleteSpeicher();
  GTSSpace->MySelection()->removeAll();
  GTSSpace->flushAllViews();
  EndeEingabe = false;
  setActivCursor  (GTSView, "hand2");
  setPassivCursor (GTSView, "hand2");
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::setToInfoRouting () {
  ObjButtonHandling = routeInfoButton;
  ObjMotionHandling = routeMotion;
  Meld.deleteSpeicher();
  GTSSpace->MySelection()->removeAll();
  GTSSpace->flushAllViews();
  EndeEingabe = false;
  setActivCursor  (GTSView, "hand2");
  setPassivCursor (GTSView, "hand2");
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::setToWorkScheduling () {
}

//==================================================================
//		the button CB's
//==================================================================

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool OKEingabe (typBaustein* zebst)
{
  if (FahrkursListe->TFKAnfangPruefen (zebst->i_BstTyp()))
  {
    GTSSpace->MySelection()->remove(
          *(GTSSpace->MySelection()->SelectedObjects ().Last()));
    Meld.Ausgabe (102, zebst->i_BstNr());
    return false;
  }
  if (GTSSpace->MySelection()->SelectedObjects().Count() > 1)
  {
    if(FahrkursListe->TFKLogischeBausteinePruefen (zebst->i_BstTyp()))
    {
      GTSSpace->MySelection()->remove(
          *(GTSSpace->MySelection()->SelectedObjects ().Last()));
      Meld.Ausgabe (103, zebst->i_BstTyp());
      return false;
    }
  }
  return true;
}  // ENDE OKEingabe

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void FahrkurseErzeugen ()
{
  GeoObject   *selObj;
  typBaustein *zabst;
  typBaustein *zebst;
  typFahrkurs *zfk;
  List<typFahrkurs> FkListe;

  selObj = GTSSpace->MySelection()->SelectedObjects().First();
  zabst = GTSMAP.findKey (*selObj);
  GTSSpace->MySelection()->remove(*selObj);

  for ( selObj = GTSSpace->MySelection()->SelectedObjects().First();
       (GTSSpace->MySelection()->SelectedObjects())();
        selObj = GTSSpace->MySelection()->SelectedObjects().Next())
  {
    zebst = GTSMAP.findKey (*selObj);
    zfk = FahrkursListe->FahrkursErzeugen(zabst, zebst);
    if (zfk) FkListe.append(*zfk);
    else
    {
      Meld.Ausgabe(104, zabst->i_BstNr(), zebst->i_BstNr());
      while (!FkListe.isEmpty()) delete (FkListe.removeFirst());
      return;
    }
    zabst = zebst;
  }

  typFahrkurs* neuFk = new typFahrkurs();
  while (!FkListe.isEmpty())
  {
    zfk = FkListe.removeFirst();
    neuFk->append(*zfk);
    delete (zfk);
  }
  FahrkursListe->TFKEingliedern (neuFk);
  neuFk->ZeigeFahrkurs ();
}  //  ENDE FahrkurseErzeugen

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::routeButtonWithShift (GTSCallback* who, OGLView* view)
{
   typBaustein* zabst;
   typBaustein* zebst;
   if ((zabst = GTSMAP.findKey (*(who->ObjActSelection))) == NULL)
     return;

   view->MySpace()->MySelection()->insert (*(who->ObjActSelection));

   zabst = GTSMAP.findKey (*(view->MySpace()->MySelection()->SelectedObjects().First()));
   if (!FahrkursListe->TFKAnfangPruefen (zabst->i_BstTyp(), false))
   {
     view->MySpace()->MySelection()->removeAll();
     Meld.Ausgabe (101, zabst->i_BstNr());
     return;
   }

   if (view->MySpace()->MySelection()->SelectedObjects().Count() > 1)
   {
     zebst = GTSMAP.findKey (*(view->MySpace()->MySelection()->SelectedObjects().Last()));

     EndeEingabe = FahrkursListe->TFKEndePruefen (zebst->i_BstTyp(), false);
     if (EndeEingabe)
     {
       typFahrkurs* fkurs = FahrkursListe->TFKSuchen(zabst, zebst);
       if (fkurs) FahrkursListe->TFKLoeschen (fkurs);
       FahrkurseErzeugen();
       Meld.StatusZeile (118, true);
     }
     else
       if (!OKEingabe(zebst)) return;
   }
}  //  routeButtonMitShift

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::routeButton (GTSCallback* who, OGLView* view,
                               Ustring art, int meld1, int meld2)
{
   typBaustein* zabst;
   typBaustein* zebst;
   typBaustein* zbst;
   if (view->MySpace()->MySelection()->SelectedObjects().Count() >= 2)
   {
     view->MySpace()->MySelection()->removeAll();
     view->MySpace()->flushAllViews();
   }

   if ((zbst = GTSMAP.findKey (*(who->ObjActSelection))) == NULL)
   return;

   if (!view->MySpace()->MySelection()->SelectedObjects().Count())
   {
     if (FahrkursListe->TFKAnfangPruefen (zbst->i_BstTyp(), true))
     {
       view->MySpace()->MySelection()->insert (*(who->ObjActSelection));
       Meld.StatusZeile (meld2, true);
     }
     else
       Meld.Ausgabe (106, zbst->i_BstTyp());

     view->MySpace()->flushAllViews();
     return;
   }

   if (FahrkursListe->TFKEndePruefen (zbst->i_BstTyp(), true))
   {
     view->MySpace()->MySelection()->insert (*(who->ObjActSelection));
     Meld.StatusZeile (meld1, true);
   }
   else
   {
     Meld.Ausgabe (107, zbst->i_BstTyp());
     return;
   }
   view->MySpace()->flushAllViews();

   zabst = GTSMAP.findKey (*(view->MySpace()->MySelection()->SelectedObjects().First()));
   zebst = GTSMAP.findKey (*(view->MySpace()->MySelection()->SelectedObjects().Last()));
   typFahrkurs* fkurs = FahrkursListe->TFKSuchen(zabst, zebst);
   if (art == "Info")
     FahrkursListe->TFKZeigen (zabst, zebst);
   else
   if (art == "Erzeugen")
     FahrkursListe->TFKErzeugen(zabst, zebst);
   else
   if (art == "Loeschen")
   {
     if (fkurs)
     {
       Meld.Ausgabe(40, zabst->i_BstNr(), zebst->i_BstNr());
       FahrkursListe->TFKLoeschen (fkurs);
     }
     else
       Meld.Ausgabe(11, zabst->i_BstNr(), zebst->i_BstNr());
   }
   EndeEingabe = true;
} // ENDE routeButton

void GTSCallback::setCursorButton (GTSCallback* who, OGLView* view, bool down,
                                   Ustring dc1, Ustring dc2, Ustring uc1, Ustring uc2)
{
  if (down)                   // Button_Down
  {
    who->setActivCursor  (view, dc1);
    who->setPassivCursor (view, dc2);
  }
  else                       // Button_Up
  {
    who->setActivCursor  (view, uc1);
    who->setPassivCursor (view, uc2);
  }
}  // ENDE setCursorButton

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::routeInfoButton (GTSCallback* who, OGLView* view,
                              int button, int state, int x, int y)
{
  if (button == Button2)       // Middle-Mouse-Button
  {
    who->setCursorButton (who, view, (state < Button2Mask),
                     "hand1", "hand1", "hand2", "hand2");
    return;
  }
  if (button == Button1) {       // Left-Mouse-Button
    if (state < Button1Mask) {   // Button1_Down
      who->ObjStartX = x;
      who->ObjStartY = y;
      if (EndeEingabe){
        view->MySpace()->MySelection()->removeAll();
        EndeEingabe = false;
        view->MySpace()->flushAllViews();
      }
      view->doSelect (view, who->ObjSelectedObjects, x, y, 2, 2);
      if (who->ObjSelectedObjects.isEmpty () ||
          (who->ObjActSelection = view->MySpace()->MySelection()->couldSelect (*(who->ObjSelectedObjects.Last ()))) == NULL)
        return;

      if (view->MySpace()->MySelection()->hasSelection (*(who->ObjActSelection)))
        view->MySpace()->MySelection()->remove (*(who->ObjActSelection));
      else
        routeButton (who, view, Ustring ("Info"), 116, 117);
      view->MySpace()->flushAllViews();
    }       // Button1_Down
    else {  // Button1_Up
      who->ObjActSelection = NULL;
    }
  }
  else if ((button == Button3) && (state & Button3Mask)) {
    view->MySpace()->MySelection()->removeAll();
    view->MySpace()->flushAllViews();
    sprintf  (DlgBuffer, "SelectFahrkursMenu %d %d", x, y);
    Tcl_Eval (GTSInterpreter, DlgBuffer);
  } // Button3 && Button3Mask
  who->ObjSelectedObjects.removeAll ();
}  //  ENDE routeInfoButton

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::routeLoescheButton (GTSCallback* who, OGLView* view,
                              int button, int state, int x, int y)
{
  if (button == Button2)       // Middle-Mouse-Button
  {
    who->setCursorButton (who, view, (state < Button2Mask),
                     "hand1", "hand1", "hand2", "hand2");
    return;
  }

  if (button == Button1) {       // Left-Mouse-Button
    if (state < Button1Mask) {   // Button1_Down
      who->ObjStartX = x;
      who->ObjStartY = y;
      if (EndeEingabe) {
        view->MySpace()->MySelection()->removeAll();
        EndeEingabe = false;
        view->MySpace()->flushAllViews();
      }
      view->doSelect (view, who->ObjSelectedObjects, x, y, 2, 2);
      if (who->ObjSelectedObjects.isEmpty () ||
          (who->ObjActSelection = view->MySpace()->MySelection()->couldSelect (*(who->ObjSelectedObjects.Last ()))) == NULL)
        return;

      if (view->MySpace()->MySelection()->hasSelection (*(who->ObjSelectedObjects.Last())))
        view->MySpace()->MySelection()->remove (*(who->ObjSelectedObjects.Last()));
      else
        routeButton (who, view, Ustring ("Loeschen"), 121, 122);

      view->MySpace()->flushAllViews();
    }       // Button1_Down
    else {  // Button1_Up
      who->ObjActSelection = NULL;
    }
  } // Button1
  else if ((button == Button3) && (state & Button3Mask)) {
    view->MySpace()->MySelection()->removeAll();
    view->MySpace()->flushAllViews();
    sprintf  (DlgBuffer, "SelectFahrkursMenu %d %d", x, y);
    Tcl_Eval (GTSInterpreter, DlgBuffer);
  } // Button3 && Button3Mask
  who->ObjSelectedObjects.removeAll ();
}  //  ENDE routeLoescheButton

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::routeErzeugeButton (GTSCallback* who, OGLView* view,
                              int button, int state, int x, int y)
{
  if (button == Button2)       // Middle-Mouse-Button
  {
    who->setCursorButton (who, view, (state < Button2Mask),
                     "hand1", "hand1", "hand2", "hand2");
    return;
  }

  if (button == Button1) {       // Left-Mouse-Button
    if (state < Button1Mask) {   // Button1_Down
      who->ObjStartX = x;
      who->ObjStartY = y;
      if (EndeEingabe) {
        view->MySpace()->MySelection()->removeAll();
        EndeEingabe = false;
        view->MySpace()->flushAllViews();
      }
      view->doSelect (view, who->ObjSelectedObjects, x, y, 2, 2);
      if (who->ObjSelectedObjects.isEmpty () ||
          (who->ObjActSelection = view->MySpace()->MySelection()->couldSelect (*(who->ObjSelectedObjects.Last ()))) == NULL)
        return;

      if (view->MySpace()->MySelection()->hasSelection (*(who->ObjActSelection)))
        view->MySpace()->MySelection()->remove (*(who->ObjActSelection));
      else
        if (state & ShiftMask)         // with ShiftKey
          routeButtonWithShift (who, view);
        else
          routeButton (who, view, Ustring ("Erzeugen"), 118, 119);

      view->MySpace()->flushAllViews();
    }       // Button1_Down
    else {  // Button1_Up
      who->ObjActSelection = NULL;
    }
  } // Button1
  else if ((button == Button3) && (state & Button3Mask)) {
    view->MySpace()->MySelection()->removeAll();
    view->MySpace()->flushAllViews();
    sprintf  (DlgBuffer, "SelectFahrkursMenu %d %d", x, y);
    Tcl_Eval (GTSInterpreter, DlgBuffer);
  } // Button3 && Button3Mask
  who->ObjSelectedObjects.removeAll ();
}  //  ENDE routeErzeugeButton

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::combInfoButton (GTSCallback* who, OGLView* view,
                              int button, int state, int x, int y)
{
  if (button == Button2)       // Middle-Mouse-Button
  {
    who->setCursorButton (who, view, (state < Button2Mask),
                     "hand1", "hand1", "hand2", "hand2");
    return;
  }

  if (button == Button1) {       // Left-Mouse-Button
    if (state < Button1Mask) {   // Button1_Down
      view->doSelect (view, who->ObjSelectedObjects, x, y, 2, 2);
      if (!who->ObjSelectedObjects.isEmpty () &&
          (who->ObjActSelection = view->MySpace()->MySelection()->couldSelect (*(who->ObjSelectedObjects.Last ()))) != NULL) {
        who->ObjStartX = x;
        who->ObjStartY = y;
        if (view->MySpace()->MySelection()->SelectedObjects().Count() > 0)
            view->MySpace()->MySelection()->removeAll();

        typBaustein* zbst;
        if ((zbst = GTSMAP.findKey (*(who->ObjActSelection))) == NULL)
        return;

        view->MySpace()->MySelection()->insert (*(who->ObjActSelection));
        view->MySpace()->flushAllViews();
        zbst->InfoVerkettung ();
      } // Count
    }       // Button1_Down
    else {  // Button1_Up
      who->ObjActSelection = NULL;
    }
  } // Button1
  else if ((button == Button3) && (state & Button3Mask)) { // Button3 und Button3_Up
    if (view->MySpace()->MySelection()->SelectedObjects().Count() > 0) {
      view->MySpace()->MySelection()->removeAll();
      view->MySpace()->flushAllViews();
    }
    sprintf  (DlgBuffer, "SelectVerkettungsMenu %d %d", x, y);
    Tcl_Eval (GTSInterpreter, DlgBuffer);
  } // Button3 und Button3Mask
}  //  ENDE combInfoButton

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::combLoescheButton (GTSCallback* who, OGLView* view,
                              int button, int state, int x, int y)
{
  if (button == Button2)       // Middle-Mouse-Button
  {
    who->setCursorButton (who, view, (state < Button2Mask),
                     "hand1", "hand1", "hand2", "hand2");
    return;
  }

  if (button == Button1) {       // Left-Mouse-Button
    if (state < Button1Mask) {   // Button1_Down
      view->doSelect (view, who->ObjSelectedObjects, x, y, 2, 2);
      if (!who->ObjSelectedObjects.isEmpty () &&
          (who->ObjActSelection = view->MySpace()->MySelection()->couldSelect (*(who->ObjSelectedObjects.Last ()))) != NULL) {
        who->ObjStartX = x;
        who->ObjStartY = y;
        if (view->MySpace()->MySelection()->SelectedObjects().Count() >= 2)
            view->MySpace()->MySelection()->removeAll();

        if ((GTSMAP.findKey (*(who->ObjActSelection))) == NULL)
        return;

        view->MySpace()->MySelection()->insert (*(who->ObjActSelection));
        view->MySpace()->flushAllViews();

        if (view->MySpace()->MySelection()->SelectedObjects().Count() == 2) {
          typBaustein* zvon =
            GTSMAP.findKey (*(view->MySpace()->MySelection()->SelectedObjects().First()));
          typBaustein* zmit =
            GTSMAP.findKey (*(view->MySpace()->MySelection()->SelectedObjects ().Last()));
          zvon->loeseVerkettung (zmit);
          zvon->InfoVerkettung ();
          Meld.StatusZeile (114, true);
        } else
          Meld.StatusZeile (115, true);
        who->ObjSelectedObjects.removeAll ();
      } // Count
    }       // Button1_Down
    else {  // Button1_Up
      who->ObjActSelection = NULL;
    }
  } // Button1
  else if ((button == Button3) && (state & Button3Mask)) { // Button3 und Button3_Up
    if (view->MySpace()->MySelection()->SelectedObjects().Count() == 2) {
      view->MySpace()->MySelection()->removeAll();
      view->MySpace()->flushAllViews();
      sprintf  (DlgBuffer, "SelectVerkettungsMenu %d %d", x, y);
      Tcl_Eval (GTSInterpreter, DlgBuffer);
    }
    else
      if (view->MySpace()->MySelection()->SelectedObjects().Count() > 0) {
        view->MySpace()->MySelection()->removeAll();
        view->MySpace()->flushAllViews();
      }
      else {
        sprintf  (DlgBuffer, "SelectVerkettungsMenu %d %d", x, y);
        Tcl_Eval (GTSInterpreter, DlgBuffer);
      }
  } // Button3 und Button3Mask
}  //  ENDE combLoescheButton

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::combErzeugeButton (GTSCallback* who, OGLView* view,
                              int button, int state, int x, int y)
{
  if (button == Button2)       // Middle-Mouse-Button
  {
    who->setCursorButton (who, view, (state < Button2Mask),
                     "hand1", "hand1", "hand2", "hand2");
    return;
  }

  if (button == Button1) {       // Left-Mouse-Button
    if (state < Button1Mask) {   // Button1_Down
      view->doSelect (view, who->ObjSelectedObjects, x, y, 2, 2);
      if (!who->ObjSelectedObjects.isEmpty () &&
          (who->ObjActSelection = view->MySpace()->MySelection()->couldSelect (*(who->ObjSelectedObjects.Last ()))) != NULL) {
        who->ObjStartX = x;
        who->ObjStartY = y;
        if (view->MySpace()->MySelection()->SelectedObjects().Count() >= 2)
            view->MySpace()->MySelection()->removeAll();
        typBaustein* ztest = GTSMAP.findKey (*(who->ObjActSelection));
        if (ztest) {
          int vonbsttyp  = ztest->i_BstTyp();
          int nachbsttyp = 0;
          if (view->MySpace()->MySelection()->SelectedObjects().Count()) {
            vonbsttyp =
              GTSMAP.findKey (*(view->MySpace()->MySelection()->SelectedObjects().First()))->i_BstTyp();
            nachbsttyp = ztest->i_BstTyp();
          }
          if (view->MySpace()->MySelection()->hasSelection (*(who->ObjActSelection)))
          return;

          if (pruefeTBVEingabe (vonbsttyp, nachbsttyp))
             view->MySpace()->MySelection()->insert
                   (*(who->ObjActSelection), Selection::SelRed);
        }
        view->MySpace()->flushAllViews();

        if (view->MySpace()->MySelection()->SelectedObjects().Count() == 2) {
          typBaustein* zvon =
             GTSMAP.findKey (*(view->MySpace()->MySelection()->SelectedObjects().First()));
          typBaustein* zmit =
             GTSMAP.findKey (*(view->MySpace()->MySelection()->SelectedObjects ().Last()));
          zvon->verkette (0, zmit, 0, 0);
          zvon->InfoVerkettung ();
          Meld.StatusZeile (112, true);
        }
        else
          Meld.StatusZeile (113, true);
        who->ObjSelectedObjects.removeAll ();
      } // Count
    }       // Button1_Down
    else {  // Button1_Up
      who->ObjActSelection = NULL;
    }
  } // Button1
  else if ((button == Button3) && (state & Button3Mask)) { // Button3 und Button3_Up
    if (view->MySpace()->MySelection()->SelectedObjects().Count() == 2) {
      view->MySpace()->MySelection()->removeAll();
      view->MySpace()->flushAllViews();
      sprintf  (DlgBuffer, "SelectVerkettungsMenu %d %d", x, y);
      Tcl_Eval (GTSInterpreter, DlgBuffer);
    }
    else
      if (view->MySpace()->MySelection()->SelectedObjects().Count() > 0) {
        view->MySpace()->MySelection()->removeAll();
        view->MySpace()->flushAllViews();
      }
      else {
        sprintf  (DlgBuffer, "SelectVerkettungsMenu %d %d", x, y);
        Tcl_Eval (GTSInterpreter, DlgBuffer);
      }
  } // Button3 und Button3Mask
}  //  ENDE combErzeugeButton

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::camButton (GTSCallback * /*who*/, OGLView* /*view*/,
                             int /*button*/, int /*state*/, int /*x*/, int /*y*/)
{
}  //  ENDE camButton

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::moveButtonNewObjectSelect (GTSCallback * who, OGLView* view, int /*button*/, int state, int x, int y)
{
  who->ObjStartX = x;
  who->ObjStartY = y;
  GeoObject* ztmp = who->ObjActSelection;
  who->MenueInfoBaustein (ztmp);
  who->ObjActSelection = ztmp;
//  cursortest(view);
  if (state & ShiftMask) {        // with ShiftKey
    if (view->MySpace()->MySelection()->hasSelection (*(who->ObjActSelection)))
    {
      view->MySpace()->MySelection()->remove (*(who->ObjActSelection));
      who->updateCursor (view, 0);
     }
    else
      view->MySpace()->MySelection()->insert (*(who->ObjActSelection));
      who->updateCursor (view, 1);
      ZBSTAKTIV = GTSMAP.findKey (*(view->MySpace()->MySelection()->SelectedObjects ().Last()));
      view->MySpace()->flushAllViews();
  } // ShiftMask
  else {
    if (! (view->MySpace()->MySelection()->hasSelection (*(who->ObjActSelection)))) {
      view->MySpace()->MySelection()->removeAll();
      view->MySpace()->MySelection()->insert (*(who->ObjSelectedObjects.Last()));
      ZBSTAKTIV = GTSMAP.findKey (*(view->MySpace()->MySelection()->SelectedObjects ().Last()));
      view->MySpace()->flushAllViews();
    }
  }
  if (view->MySpace()->MySelection()->SelectedObjects().Count()) {
    Tcl_Eval (GTSInterpreter,(char*)Ustring("SetzBstButton {active}").str());
    if (view->MySpace()->MySelection()->SelectedObjects().Count() > 1)
       Tcl_Eval (GTSInterpreter,(char*)Ustring("SetzAusrichtButton {active}").str());
  }
  else {
    Tcl_Eval (GTSInterpreter,(char*)Ustring("SetzAusrichtButton {disabled}").str());
    Tcl_Eval (GTSInterpreter,(char*)Ustring("SetzBstButton {disabled}").str());
  }
  who->ObjSelectedObjects.removeAll ();
}  // ENDE moveButtonNewObjectSelect

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::moveButton   (GTSCallback * who, OGLView* view, int button, int state, int x, int y)
{
  if (button == Button2)       // Middle-Mouse-Button
  {
    who->setCursorButton (who, view, (state < Button2Mask),
                     "hand1", "hand1", "fleur", "arrow");
    return;
  }

  if (button == Button1) {       // Left-Mouse-Button
    if (state < Button1Mask) {   // Button1_Down
      view->doSelect (view, who->ObjSelectedObjects, x, y, 2, 2);
      if (!who->ObjSelectedObjects.isEmpty () &&
          (who->ObjActSelection = view->MySpace()->MySelection()->couldSelect (*(who->ObjSelectedObjects.Last ()))) != NULL)
        who->moveButtonNewObjectSelect (who, view, button, state, x, y);
      else if (!(state & ShiftMask)) {
        if (view->MySpace ()->MySelection ()->hasSelection ()) {
          Tcl_Eval (GTSInterpreter,(char*)Ustring("SetzBstButton {disabled}").str());
          Tcl_Eval (GTSInterpreter,(char*)Ustring("SetzAusrichtButton {disabled}").str());
          view->MySpace()->MySelection()->removeAll();
          view->MySpace()->flushAllViews();
        }
        who->beginSelectRect (who, view, x, y);
      }
      else if ((state & ShiftMask)) {
        who->beginSelectRect (who, view, x, y);
      }
    }       // Button1_Down
    else {  // Button1_Up
      who->ObjActSelection = NULL;
      if (who->ObjBoxZeichnen)
         who->endSelectRect (who, view, x, y, (state & ShiftMask));
    }
  } //Button1
  else
  if ((button == Button3) && (state & Button3Mask))  // Button3 und Button3_Up
  {
    sprintf (DlgBuffer, "%s configure -cursor %s",
               ((ToglView*)view)->WidgetName (), who->ObjPassivCursor.str());
    Tcl_GlobalEval (GTSInterpreter, DlgBuffer);
    view->flush ();

    sprintf  (DlgBuffer, "SelectMenu %d %d", x, y);
    Tcl_Eval (GTSInterpreter, DlgBuffer);
  } // Button3 und Button3Mask
}  // ENDE moveButton

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void rotateSelection (Angle& diffwinkel)
{
  typBaustein *zhilfe;
  GeoObject   *selObj;

  typBaustein* zfirst =
    GTSMAP.findKey (*(GTSSpace->MySelection()->SelectedObjects().First ()));

  for (selObj = GTSSpace->MySelection()->SelectedObjects().First ();
       (GTSSpace->MySelection()->SelectedObjects())();
        selObj = GTSSpace->MySelection()->SelectedObjects().Next())
  {
    zhilfe = GTSMAP.findKey (*selObj);
    if (zhilfe) zhilfe->drehen (zfirst->zBstGraphik->Pos(), diffwinkel);
  }
} // ENDE rotateSelection

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::rotateButton (GTSCallback* who, OGLView* view, int button, int state, int x, int y)
{
  if (button == Button2)       // Middle-Mouse-Button
  {
    who->setCursorButton (who, view, (state < Button2Mask),
                     "hand1", "hand1", "exchange", "exchange");
    return;
  }

  if (button == Button1) {       // Left-Mouse-Button
    if (state < Button1Mask)    // Button1_Down
    {
      typBaustein* zfirst =
      GTSMAP.findKey (*(GTSSpace->MySelection()->SelectedObjects().First ()));
      who->ObjStartVec = view->Camera()->PositionFromPixels (x, y) -
                         zfirst->zBstGraphik->Pos();
      who->ObjStartX = x;
      who->ObjStartY = y;
      who->ObjDrehen = true;
    }       // Button1_Down
    else
      who->ObjDrehen = false;
  } //Button1
  else
  if ((button == Button3) && (state & Button3Mask))  // Button3 und Button3_Up
  {
    sprintf  (DlgBuffer, "SelectMenu %d %d", x, y);
    Tcl_Eval (GTSInterpreter, DlgBuffer);
  } // Button3 und Button3Mask
}  // ENDE  rotateButton

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::zoomButton (GTSCallback *who, OGLView *view, int button, int state, int x, int y)
{
  if (button == Button2)       // Middle-Mouse-Button
  {
    who->setCursorButton (who, view, (state < Button2Mask),
                     "hand1", "hand1", "tcross", "tcross");
    return;
  }

  if (button == Button1)              // Left-Mouse-Button
    if (state < Button1Mask)          // Button1_Down
      who->beginZoomRect (who, view, x, y);
    else                              // Button1_Up
      if (who->ObjStartX != x && who->ObjStartY != y)
        who->endZoomRect (who, view, x, y);
}// ENDE  zoomButton

//==================================================================
//		the motion CB's
//==================================================================

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::routeMotion    (GTSCallback* who, OGLView* view, int state, int, int)
{
  if (state & Button2Mask)  // bewege Kamera mit Mittle-Left-Mouse-Button
  {
    who->bewegeKamera (who, view, state);
    return;
  } // Button3Mask
}  // ENDE routeMotion

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::combMotion    (GTSCallback* who, OGLView* view, int state, int, int)
{
  if (state & Button2Mask)  // bewege Kamera mit Mittle-Left-Mouse-Button
  {
    who->bewegeKamera (who, view, state);
    return;
  } // Button3Mask
}  // ENDE combMotion


// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::bewegeKamera (GTSCallback * who, OGLView* view, int state)
{
  if (state & ShiftMask)           // with ShiftKey
  {
    if  (who->ObjDeltaX)
      view->Camera()->move (view->Camera()->VectorFromPixels (-who->ObjDeltaX, 0));
  }
  else if (state & ControlMask)     // with ControlKey
  {
    if (who->ObjDeltaY)
      view->Camera()->move (view->Camera()->VectorFromPixels (0, -who->ObjDeltaY));
  }
  else if (state & Mod2Mask)     // with ALTKey
  {
    if (who->ObjDeltaY)
      view->Camera()->zoom (who->ObjDeltaY * 0.1);
  }
  else
  {
    if (who->ObjDeltaX || who->ObjDeltaY)
      view->Camera()->move (view->Camera()->VectorFromPixels (-who->ObjDeltaX, -who->ObjDeltaY));
  }
  view->flush ();
}  // ENDE bewegeKamera

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::camMotion    (GTSCallback * who, OGLView* view, int state, int, int)
{
  if ((state & Button1Mask) || (state & Button2Mask))           // Motion with Left-Mouse-Button
  {
    who->bewegeKamera (who, view, state);
  } // Button1Mask
  else if ((state & Button3Mask) && who->ObjDeltaY) {
    view->Camera()->zoom (who->ObjDeltaY * 0.1);
    view->flush ();
  }
}  // ENDE camMotion

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::moveMotionWithSelectObject (GTSCallback *who, OGLView *view, int state, int x, int y)
{
  double deltaX (x - who->ObjStartX);
  double deltaY (y - who->ObjStartY);
  double deltaZ (y - who->ObjStartZ);
  if (deltaX || deltaY)
  {
    Vec3D v (view->Camera()->VectorFromPixels (-deltaX, -deltaY));
    double dx = 0.0;
    double dy = 0.0;
    double dz = 0.0;
    int steps;
    if (state & ShiftMask)            // with ShiftKey
    {
      steps = (int) (v.X () / ObjMoveStep);
      if  (steps)
      {
        dx = steps * ObjMoveStep;
        who->ObjStartX = x - (int)(Round (deltaX - ((deltaX * dx) / v.X ())));
        who->ObjStartY = y;
      }
    }
    else if (state & ControlMask)    // with ControlKey
    {
      steps = (int) (v.Y () / ObjMoveStep);
      if  (steps)
      {
        dy = steps * ObjMoveStep;
        who->ObjStartX = x;
        who->ObjStartY = y - (int) (Round (deltaY - ((deltaY * dy) / v.Y ())));
      }
    }
    else if (state & Mod2Mask)     // with ALTKey
    {
      v =(view->Camera()->VectorFromPixels (0.0, -deltaY));
      steps = (int) (v.Y () / 1 / ObjMoveStep);
      if  (steps)
      {
        dz = steps * ObjMoveStep;
        who->ObjStartZ = y - (int) (Round (deltaZ - ((deltaZ * dz) / v.Y ())));
        who->ObjStartY = y;
        who->ObjStartX = x;
      }
    }
    else
    {
      steps = (int) (v.X () / ObjMoveStep);
      if  (steps) {
        dx = steps * ObjMoveStep;
        who->ObjStartX = x - (int) (Round (deltaX - ((deltaX * dx) / v.X ())));
      }
//      else who->ObjStartX = x;

      steps = (int) (v.Y () / ObjMoveStep);
      if  (steps) {
        dy = steps * ObjMoveStep;
        who->ObjStartY = y - (int) (Round (deltaY - ((deltaY * dy) / v.Y ())));
      }
//      else who->ObjStartY = y;
    }
    view->MySpace()->MySelection()->move (Vec3D (dx, dy, dz));
    view->MySpace()->flushAllViews();
  }
}  // ENDE  moveMotionWithSelectObject

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::moveMotion   (GTSCallback * who, OGLView* view, int state, int x, int y)
{
  if (state & Button2Mask)  // bewege Kamera mit Mittle-Left-Mouse-Button
  {
    who->bewegeKamera (who, view, state);
    return;
  } // Button3Mask

  Tcl_Eval (GTSInterpreter, "BalloonInfo_cancel");
  if (state & Button1Mask)    // Button1_Down
  {
    if (who->ObjBoxZeichnen)
    {
      if (who->ObjStartX != x || who->ObjStartY != y)
          who->drawSelectRect (who, view, x, y);
    }
    else
    if (view->MySpace()->MySelection()->hasSelection())
        who->moveMotionWithSelectObject (who, view, state, x, y);
  } // Button1_Down
}  //  ENDE  moveMotion

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::rotateMotion (GTSCallback* who, OGLView* view, int state, int x, int y)
{
  if (state & Button2Mask)  // bewege Kamera mit Mittle-Left-Mouse-Button
  {
    who->bewegeKamera (who, view, state);
    return;
  } // Button3Mask

  if (state & Button1Mask)    // Button1_Down
  {
    typBaustein* zfirst =
      GTSMAP.findKey (*(GTSSpace->MySelection ()->SelectedObjects ().First ()));
    Vec3D v = view->Camera ()->PositionFromPixels (x, y) -
                zfirst->zBstGraphik->Pos ();
    Angle w (v.angle (who->ObjStartVec));
    int steps = (int) Round (w.deg () / who->ObjAngleStep.deg ());
    if  (steps) {
      if ((v.cross (who->ObjStartVec)).Z () > 0.0) steps *= -1;
      Angle ang (steps * who->ObjAngleStep.deg ());
      rotateSelection (ang);
      who->ObjStartVec = v;
      view->MySpace ()->flushAllViews ();

      sprintf (DlgBuffer, "set koorstatus  \" Winkel=%4d°\"; ",
               zfirst->i_zWinkel());
      Tcl_GlobalEval (GTSInterpreter, DlgBuffer);
    }
  } // Button1_Down
}  // ENDE rotateMotion

void GTSCallback::zoomMotion  (GTSCallback *who, OGLView *view, int state, int x, int y)
{
  if (state & Button2Mask)  // bewege Kamera mit Mittle-Left-Mouse-Button
  {
    who->bewegeKamera (who, view, state);
    return;
  } // Button3Mask

  if (state & Button1Mask)            // Motion with Left-Mouse-Button
  {
    if (who->ObjStartX != x || who->ObjStartY != y)
    {
      who->drawZoomRect (who, view, x, y);
    }
  }
}

//==================================================================
//		the passive-motion CB's
//==================================================================

void GTSCallback::selectPassive (GTSCallback * who, OGLView* view, int x, int y)
{
  if (view->MySpace()->MySelection()->hasSelection ())
  {
    if (view->doSelectOfSubset (view->MySpace()->MySelection()->SelectedObjects (), x, y, 2, 2))
    {
      who->updateCursor(view, 1);
    }
    else  {
      who->updateCursor(view, 0);
      Meld.deleteStatusZeile (1);
      Tcl_Eval (GTSInterpreter, "BalloonInfo_cancel");
    }
  }
}  // ENDE selectPassive

//==================================================================
//		the standard CB's
//==================================================================

void GTSCallback::MouseButtonCB  (OGLView* view, int button, int state, int x, int y)
{
  ObjButtonHandling (this, view, button, state, x, y);
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::MouseMotionCB  (OGLView* view, int state, int x, int y)
{
  ObjMotionHandling (this, view, state, x, y);
  if (!ObjDrehen)
  {
    TmpPos = view->Camera()->PositionFromPixels (x, y);
    int xsteps = (int) (TmpPos.X () / ObjMoveStep);
    int ysteps = (int) (TmpPos.Y () / ObjMoveStep);
    TmpPos = Vec3D (xsteps * ObjMoveStep, ysteps * ObjMoveStep, 0.0);
    sprintf (DlgBuffer, "set koorstatus  \"x=%7.3fm, y=%7.3fm\"; ",
                        TmpPos.X(), TmpPos.Y());
    Tcl_GlobalEval (GTSInterpreter, DlgBuffer);
  }
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GTSCallback::MousePassiveCB (OGLView* view, int x, int y) {
  if (ObjPassiveHandling) ObjPassiveHandling (this, view, x, y);
  if (!ObjDrehen)
  {
    TmpPos = view->Camera()->PositionFromPixels (x, y);
    int xsteps = (int) (TmpPos.X () / ObjMoveStep);
    int ysteps = (int) (TmpPos.Y () / ObjMoveStep);
    TmpPos = Vec3D (xsteps * ObjMoveStep, ysteps * ObjMoveStep, 0.0);
    sprintf (DlgBuffer, "set koorstatus  \"x=%7.3fm, y=%7.3fm\"; ",
                        TmpPos.X(), TmpPos.Y());
    Tcl_GlobalEval (GTSInterpreter, DlgBuffer);
  }
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



