/*
  Program:   Visualization Toolkit
  Module:    $RCSfile: controls.h,v $
  Language:  C++
  Date:      $Date: 2003/04/04 20:12:54 $
  Version:   $Revision: 1.1 $
*/

//used in each header file to make sure includes are only included once
#ifndef __controls_h
#define __controls_h

//vtkLibrary header files
#include "vtkInteractorStyle.h"
#include "vtkAbstractPropPicker.h"
#include "vtkInteractorStyleUser.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkActor.h"
#include "vtkLODActor.h"
#include "vtkRenderWindow.h"
#include "vtkRenderer.h"
#include "vtkCellPicker.h"
#include "vtkCommand.h"
#include "vtkOldStyleCallbackCommand.h"
#include "vtkCamera.h"
#include <string>

//custom header files
#include "grid3D.h"
#include "coastlines.h"
#include "textDisplay.h"
#include "topography.h"
#include "visibility.h"

  const float defaultLandElevation = 200.0;


class PickData;

#define VTKIS_JOY            0
#define VTKIS_TRACK          1
#define VTKIS_CAMERA         0
#define VTKIS_ACTOR          1
#define VTKIS_CONTROL_OFF    0
#define VTKIS_CONTROL_ON     1
        
/***********************************************************
Controls is a subclass of vtkInteractor style that overrides
most user interactions and allows for the custom interactions
that eCubed needs.  Many of the functions are here but never
used but will remain in case future usage changes.

The user control are as follows:

Mouse:
ctrl + left mouse button  - changes cell group to default elevation
shift + left mouse button - allows user to change cell elevation
middle mouse button       - zooms in and out quickly(dollies)
                            depending on mouse location
right mouse button        - moves the earth around in the window
                            left to right and up and down

Keypresses:
'h' - rotates the earth 30 degrees left
'j' - rotates the earth 15 degrees down
'k' - rotates the earth 15 degrees up
'l' - rotates the earth 30 degrees right
't' - toggles topography visibility
'c' - toggles continental outline (coastline) visibility
'g' - toggles gridline visibility
'p' - saves image in PostScript format
'q' - quits and prompts for save option
'r' - returns earth to original settings
'v' - saves high-resolution image in PostScript format
'z' - zooms to a user specified latitude and longitude
'<' - zooms in 
'>' - zooms out


                                                                
**********************************************************/



class VTK_EXPORT controls : public vtkInteractorStyle 
{
 public:
  static controls *New();
  vtkTypeMacro(controls,vtkInteractorStyle);
  void PrintSelf(ostream& os, vtkIndent indent);
        

  // tells if shift was pressed with another button
  bool shiftClick;
  bool ctrlClick;

  /***************** overridden from vtkInteractorStyle **************/

  // Description:
  // Concrete implementation of event bindings
  virtual   void OnRightButtonDown(int ctrl, int shift, int X, int Y);
  virtual   void OnRightButtonUp  (int ctrl, int shift, int X, int Y);
  virtual   void OnMiddleButtonDown(int ctrl, int shift, int X, int Y);
  virtual   void OnMiddleButtonUp  (int ctrl, int shift, int X, int Y);
  virtual   void OnLeftButtonDown(int ctrl, int shift, int X, int Y);
  virtual   void OnLeftButtonUp  (int ctrl, int shift, int X, int Y);
  virtual   void OnChar(int ctrl, int shift, char keycode, int repeatcount);
  virtual   void OnKeyPress(int ctrl, int shift, char keycode, char *keysym, int repeatcount);

  // Description:
  // External switching between actor and camera mode.
  virtual void SetActorModeToCamera();
  virtual void SetActorModeToActor();
  vtkGetMacro(ActorMode, int);
  
  // Description:
  // External switching between joystick and trackball mode.
  virtual void SetTrackballModeToTrackball();
  virtual void SetTrackballModeToJoystick();
  vtkGetMacro(TrackballMode, int);

  // Description:
  // OnTimer calls RotateCamera, RotateActor etc which
  // should be overridden by style subclasses.
  virtual void OnTimer(void);


  /*********custom functions only implemented here*********/

        //
        void ChangeVisibility(char mode);

        // handles a rotate keypress 
        void OnLeftArrowDown();
        void OnRightArrowDown();
        void OnDownArrowDown();
        void OnUpArrowDown();

        // handles zoom keypresses
        void OnZoomIn();
        void OnZoomOut();

        void SaveToPostScript();
        void SaveToHiResPostScript();

        // returns earth actors to original settings
        void OriginalSettings();

  //used to zoom to given lat. and long. 
  void ZoomToLocation();


 protected:

  //default constructor
  controls();

  //default destructor
  ~controls();

  // Both created so compiler does not create machine specific functions
  controls(const controls&) {};
  void operator=(const controls&) {};

  // used to track picked objects in actor mode
  // reason for existence: user may use any kind of picker.  Interactor
  // needs the high precision of cell picker at all time.
  vtkAbstractPropPicker *InteractionPicker;
  int PropPicked;  

  // boolean: prop picked?
  vtkProp3D *InteractionProp;

  unsigned long KeyPressTag;
  float FOCAL_LENGTH;

  int Char;
  char *KeySym;


  // new interactor modes
  int ActorMode;
  int TrackballMode;
  int ControlMode;
  float MotionFactor;                // constant: for motion
  int Preprocess;                       // boolean: was preprocessing done?
  float RadianToDegree;                 // constant: for conv from deg to rad

  // data arrays for motion
  float NewPickPoint[4];
  float OldPickPoint[4];
  float MotionVector[3];                // vector used for interaction
  float OldX;
  float OldY;
  
  // this really belongs in camera
  double ViewLook[3];
  double ViewPoint[3];
  double ViewFocus[3];
  double ViewUp[3];
  double ViewRight[3];

  // actor stuff
  float Origin[3];
  float Position[3];
  float ObjCenter[3];                   // center of bounding box
  float DispObjCenter[3];               // center of box in display coord
  float Radius;                         // radius of virtual sphere

  // methods for the different interactions in different modes
  virtual void TrackballRotateCamera(int x, int y);
  virtual void TrackballSpinCamera(int x, int y);
  virtual void TrackballPanCamera(int x, int y);
  virtual void TrackballDollyCamera(int x, int y);
  
  virtual void JoystickRotateActor(int x, int y);
  virtual void JoystickSpinActor(int x, int y);
  virtual void JoystickPanActor(int x, int y);
  virtual void JoystickDollyActor(int x, int y);
  virtual void JoystickScaleActor(int x, int y);
  
  virtual void TrackballRotateActor(int x, int y);
  virtual void TrackballSpinActor(int x, int y);
  virtual void TrackballPanActor(int x, int y);
  virtual void TrackballDollyActor(int x, int y);
  virtual void TrackballScaleActor(int x, int y);



  void Prop3DTransform(vtkProp3D *prop3D, double *boxCenter,
                       int numRotation, double **rotate,
                       double *scale);
  void Prop3DTransform(vtkProp3D *prop3D,float *boxCenter,
                       int NumRotation,double **rotate,
                       double *scale);
  void FindPickedActor(int X, int Y);
};

#endif
