// @(#)root/gl:$Id$
// Author:  Richard Maunder  16/09/2005

/*************************************************************************
 * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "TGLTransManip.h"
#include "TGLPhysicalShape.h"
#include "TGLCamera.h"
#include "TGLIncludes.h"

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TGLTransManip                                                        //
//                                                                      //
// Translation manipulator - attaches to physical shape and draws local //
// axes widgets with arrow heads. User can mouse over (turns yellow) and//
// L click/drag to translate along this axis.                           //
// Widgets use standard 3D package axes colours: X red, Y green, Z blue.//
//////////////////////////////////////////////////////////////////////////

ClassImp(TGLTransManip)

//______________________________________________________________________________
TGLTransManip::TGLTransManip()
{
   // Construct translation manipulator not bound to any physical shape.
}

//______________________________________________________________________________
TGLTransManip::TGLTransManip(TGLPhysicalShape * shape) :
   TGLManip(shape)
{
   // Construct translation manipulator, attached to supplied TGLViewer
   // 'viewer', bound to TGLPhysicalShape 'shape'.
}

//______________________________________________________________________________
TGLTransManip::~TGLTransManip()
{
   // Destory the translation manipulator
}

//______________________________________________________________________________
void TGLTransManip::Draw(const TGLCamera & camera) const
{
   // Draw translation manipulator - tubes with arrow heads, in local axes of
   // attached shape, in red(X), green(Y) and blue(Z), with white center sphere.
   // If selected widget (mouse over) this is drawn in active colour (yellow).
   if (!fShape) {
      return;
   }

   // Get draw scales
   const TGLBoundingBox & box = fShape->BoundingBox();
   Double_t baseScale;
   TGLVector3 axisScale[3];
   CalcDrawScale(box, camera, baseScale, axisScale);

   // Get permitted manipulations on shape
   TGLPhysicalShape::EManip manip = fShape->GetManip();

   glEnable(GL_BLEND);
   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
   glDisable(GL_CULL_FACE);

   // Draw three axis widgets out of bounding box where permitted
   // Not drawing will prevent interaction
   // GL name loading for hit testing - 0 reserved for no selection
   if (manip & TGLPhysicalShape::kTranslateX) {
      glPushName(1);
      TGLUtil::DrawLine(box.Center(), axisScale[0], TGLUtil::kLineHeadArrow,
                        baseScale, ColorFor(1));
      glPopName();
   } else {
      TGLUtil::DrawLine(box.Center(), axisScale[0], TGLUtil::kLineHeadArrow,
                        baseScale, TGLUtil::fgGrey);
   }
   if (manip & TGLPhysicalShape::kTranslateY) {
      glPushName(2);
      TGLUtil::DrawLine(box.Center(), axisScale[1], TGLUtil::kLineHeadArrow,
                        baseScale, ColorFor(2));
      glPopName();
   } else {
      TGLUtil::DrawLine(box.Center(), axisScale[1], TGLUtil::kLineHeadArrow,
                        baseScale, TGLUtil::fgGrey);
   }
   if (manip & TGLPhysicalShape::kTranslateZ) {
      glPushName(3);
      TGLUtil::DrawLine(box.Center(), axisScale[2], TGLUtil::kLineHeadArrow,
                        baseScale, ColorFor(3));
      glPopName();
   } else {
      TGLUtil::DrawLine(box.Center(), axisScale[2], TGLUtil::kLineHeadArrow,
                        baseScale, TGLUtil::fgGrey);
   }
   // Draw white center sphere
   TGLUtil::DrawSphere(box.Center(), baseScale/2.0, TGLUtil::fgWhite);

   glEnable(GL_CULL_FACE);
   glDisable(GL_BLEND);
}

//______________________________________________________________________________
Bool_t TGLTransManip::HandleMotion(const Event_t        & event,
                                   const TGLCamera      & camera)
{
   // Handle mouse motion over manipulator - if active (selected
   // widget) translate physical along selected widget (axis) of the
   // manipulator, so it tracks mouse action. Returns kTRUE if redraw
   // required kFALSE otherwise.
   if (fActive) {
      // Find mouse delta projected into world at attached object center
      TGLVector3 shift =
         camera.ViewportDeltaToWorld( fShape->BoundingBox().Center(),
                                      event.fX - fLastMouse.GetX(),
                                     -event.fY + fLastMouse.GetY() ); // Y inverted

      // Now project this delta onto the current widget (axis) to give
      // a constrained shift along this
      UInt_t axisIndex = fSelectedWidget - 1; // Ugg sort out axis / widget id mapping
      TGLVector3 widgetAxis = fShape->BoundingBox().Axis(axisIndex, kTRUE);
      TGLVector3 constrainedShift = widgetAxis * Dot(shift, widgetAxis);
      fShape->Translate(constrainedShift);

      fLastMouse.SetX(event.fX);
      fLastMouse.SetY(event.fY);

      return kTRUE;
   }
   return kFALSE;
}

 TGLTransManip.cxx:1
 TGLTransManip.cxx:2
 TGLTransManip.cxx:3
 TGLTransManip.cxx:4
 TGLTransManip.cxx:5
 TGLTransManip.cxx:6
 TGLTransManip.cxx:7
 TGLTransManip.cxx:8
 TGLTransManip.cxx:9
 TGLTransManip.cxx:10
 TGLTransManip.cxx:11
 TGLTransManip.cxx:12
 TGLTransManip.cxx:13
 TGLTransManip.cxx:14
 TGLTransManip.cxx:15
 TGLTransManip.cxx:16
 TGLTransManip.cxx:17
 TGLTransManip.cxx:18
 TGLTransManip.cxx:19
 TGLTransManip.cxx:20
 TGLTransManip.cxx:21
 TGLTransManip.cxx:22
 TGLTransManip.cxx:23
 TGLTransManip.cxx:24
 TGLTransManip.cxx:25
 TGLTransManip.cxx:26
 TGLTransManip.cxx:27
 TGLTransManip.cxx:28
 TGLTransManip.cxx:29
 TGLTransManip.cxx:30
 TGLTransManip.cxx:31
 TGLTransManip.cxx:32
 TGLTransManip.cxx:33
 TGLTransManip.cxx:34
 TGLTransManip.cxx:35
 TGLTransManip.cxx:36
 TGLTransManip.cxx:37
 TGLTransManip.cxx:38
 TGLTransManip.cxx:39
 TGLTransManip.cxx:40
 TGLTransManip.cxx:41
 TGLTransManip.cxx:42
 TGLTransManip.cxx:43
 TGLTransManip.cxx:44
 TGLTransManip.cxx:45
 TGLTransManip.cxx:46
 TGLTransManip.cxx:47
 TGLTransManip.cxx:48
 TGLTransManip.cxx:49
 TGLTransManip.cxx:50
 TGLTransManip.cxx:51
 TGLTransManip.cxx:52
 TGLTransManip.cxx:53
 TGLTransManip.cxx:54
 TGLTransManip.cxx:55
 TGLTransManip.cxx:56
 TGLTransManip.cxx:57
 TGLTransManip.cxx:58
 TGLTransManip.cxx:59
 TGLTransManip.cxx:60
 TGLTransManip.cxx:61
 TGLTransManip.cxx:62
 TGLTransManip.cxx:63
 TGLTransManip.cxx:64
 TGLTransManip.cxx:65
 TGLTransManip.cxx:66
 TGLTransManip.cxx:67
 TGLTransManip.cxx:68
 TGLTransManip.cxx:69
 TGLTransManip.cxx:70
 TGLTransManip.cxx:71
 TGLTransManip.cxx:72
 TGLTransManip.cxx:73
 TGLTransManip.cxx:74
 TGLTransManip.cxx:75
 TGLTransManip.cxx:76
 TGLTransManip.cxx:77
 TGLTransManip.cxx:78
 TGLTransManip.cxx:79
 TGLTransManip.cxx:80
 TGLTransManip.cxx:81
 TGLTransManip.cxx:82
 TGLTransManip.cxx:83
 TGLTransManip.cxx:84
 TGLTransManip.cxx:85
 TGLTransManip.cxx:86
 TGLTransManip.cxx:87
 TGLTransManip.cxx:88
 TGLTransManip.cxx:89
 TGLTransManip.cxx:90
 TGLTransManip.cxx:91
 TGLTransManip.cxx:92
 TGLTransManip.cxx:93
 TGLTransManip.cxx:94
 TGLTransManip.cxx:95
 TGLTransManip.cxx:96
 TGLTransManip.cxx:97
 TGLTransManip.cxx:98
 TGLTransManip.cxx:99
 TGLTransManip.cxx:100
 TGLTransManip.cxx:101
 TGLTransManip.cxx:102
 TGLTransManip.cxx:103
 TGLTransManip.cxx:104
 TGLTransManip.cxx:105
 TGLTransManip.cxx:106
 TGLTransManip.cxx:107
 TGLTransManip.cxx:108
 TGLTransManip.cxx:109
 TGLTransManip.cxx:110
 TGLTransManip.cxx:111
 TGLTransManip.cxx:112
 TGLTransManip.cxx:113
 TGLTransManip.cxx:114
 TGLTransManip.cxx:115
 TGLTransManip.cxx:116
 TGLTransManip.cxx:117
 TGLTransManip.cxx:118
 TGLTransManip.cxx:119
 TGLTransManip.cxx:120
 TGLTransManip.cxx:121
 TGLTransManip.cxx:122
 TGLTransManip.cxx:123
 TGLTransManip.cxx:124
 TGLTransManip.cxx:125
 TGLTransManip.cxx:126
 TGLTransManip.cxx:127
 TGLTransManip.cxx:128
 TGLTransManip.cxx:129
 TGLTransManip.cxx:130
 TGLTransManip.cxx:131
 TGLTransManip.cxx:132
 TGLTransManip.cxx:133
 TGLTransManip.cxx:134
 TGLTransManip.cxx:135
 TGLTransManip.cxx:136
 TGLTransManip.cxx:137
 TGLTransManip.cxx:138