/*=========================================================================

  Copyright (c) Kitware, Inc.
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/VolViewCopyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkKWInteractorStyleEventMap.h"
#include "vtkObjectFactory.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkKWEventMap.h"

vtkCxxRevisionMacro(vtkKWInteractorStyleEventMap, "$Revision: 1.15 $");
vtkStandardNewMacro(vtkKWInteractorStyleEventMap);

vtkCxxSetObjectMacro(vtkKWInteractorStyleEventMap, EventMap, vtkKWEventMap);

//----------------------------------------------------------------------------
vtkKWInteractorStyleEventMap::vtkKWInteractorStyleEventMap()
{
  this->EventMap = NULL;
  this->CurrentAction = NULL;
  this->EventIdentifier = -1;
}

//----------------------------------------------------------------------------
vtkKWInteractorStyleEventMap::~vtkKWInteractorStyleEventMap()
{
  this->SetEventMap(NULL);
  this->SetCurrentAction(NULL);
}

//----------------------------------------------------------------------------
void vtkKWInteractorStyleEventMap::OnMouseMove()
{
  this->PerformAction(this->CurrentAction);
}

//----------------------------------------------------------------------------
void vtkKWInteractorStyleEventMap::OnLeftButtonDown()
{
  this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
                          this->Interactor->GetEventPosition()[1]);
  
  if (this->Interactor->GetShiftKey())
    {
    this->SetCurrentAction(
      this->EventMap->FindMouseAction(
        vtkKWEventMap::LeftButton, vtkKWEventMap::ShiftModifier));
    }
  else if (this->Interactor->GetControlKey())
    {
    this->SetCurrentAction(
      this->EventMap->FindMouseAction(
        vtkKWEventMap::LeftButton, vtkKWEventMap::ControlModifier));
    }
  else
    {
    this->SetCurrentAction(
      this->EventMap->FindMouseAction(
        vtkKWEventMap::LeftButton, vtkKWEventMap::NoModifier));
    }
  this->StartAction(this->CurrentAction);
}

//----------------------------------------------------------------------------
void vtkKWInteractorStyleEventMap::OnLeftButtonUp()
{
  this->StopAction(this->CurrentAction);
  this->SetCurrentAction(NULL);
}

//----------------------------------------------------------------------------
void vtkKWInteractorStyleEventMap::OnMiddleButtonDown()
{
  this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
                          this->Interactor->GetEventPosition()[1]);
  
  if (this->Interactor->GetShiftKey())
    {
    this->SetCurrentAction(
      this->EventMap->FindMouseAction(
        vtkKWEventMap::MiddleButton, vtkKWEventMap::ShiftModifier));
    }
  else if (this->Interactor->GetControlKey())
    {
    this->SetCurrentAction(
      this->EventMap->FindMouseAction(
        vtkKWEventMap::MiddleButton, vtkKWEventMap::ControlModifier));
    }
  else
    {
    this->SetCurrentAction(
      this->EventMap->FindMouseAction(
        vtkKWEventMap::MiddleButton, vtkKWEventMap::NoModifier));
    }
  this->StartAction(this->CurrentAction);
}

//----------------------------------------------------------------------------
void vtkKWInteractorStyleEventMap::OnMiddleButtonUp()
{
  this->StopAction(this->CurrentAction);
  this->SetCurrentAction(NULL);
}

//----------------------------------------------------------------------------
void vtkKWInteractorStyleEventMap::OnRightButtonDown()
{
  this->FindPokedRenderer(this->Interactor->GetEventPosition()[0],
                          this->Interactor->GetEventPosition()[1]);
  
  if (this->Interactor->GetShiftKey())
    {
    this->SetCurrentAction(
      this->EventMap->FindMouseAction(
        vtkKWEventMap::RightButton, vtkKWEventMap::ShiftModifier));
    }
  else if (this->Interactor->GetControlKey())
    {
    this->SetCurrentAction(
      this->EventMap->FindMouseAction(
        vtkKWEventMap::RightButton, vtkKWEventMap::ControlModifier));
    }
  else
    {
    this->SetCurrentAction(
      this->EventMap->FindMouseAction(
        vtkKWEventMap::RightButton, vtkKWEventMap::NoModifier));
    }
  this->StartAction(this->CurrentAction);
}

//----------------------------------------------------------------------------
void vtkKWInteractorStyleEventMap::OnRightButtonUp()
{
  this->StopAction(this->CurrentAction);
  this->SetCurrentAction(NULL);
}

//----------------------------------------------------------------------------
void vtkKWInteractorStyleEventMap::OnKeyPress()
{
  // Try with the key first

  char key = this->Interactor->GetKeyCode();
  char *keysym = this->Interactor->GetKeySym();

  const char *action = NULL;

  if (key)
    {
    if (this->Interactor->GetShiftKey())
      {
      action = this->EventMap->FindKeyAction(
        key, vtkKWEventMap::ShiftModifier);
      }
    else if (this->Interactor->GetControlKey())
      {
      action = this->EventMap->FindKeyAction(
        key, vtkKWEventMap::ControlModifier);
      }
    else
      {
      action = this->EventMap->FindKeyAction(
        key, vtkKWEventMap::NoModifier);
      }
    }

  // Otherwise try the keysym

  else if (keysym)
    {
    if (this->Interactor->GetShiftKey())
      {
      action = this->EventMap->FindKeySymAction(
        keysym, vtkKWEventMap::ShiftModifier);
      }
    else if (this->Interactor->GetControlKey())
      {
      action = this->EventMap->FindKeySymAction(
        keysym, vtkKWEventMap::ControlModifier);
      }
    else
      {
      action = this->EventMap->FindKeySymAction(
        keysym, vtkKWEventMap::NoModifier);
      }
    }
  
  // We found no action, let's not set the CurrentAction to NULL so that
  // we can keep the old current action when modifiers keys only are
  // pressed.

  if (!action)
    {
    return;
    }

  this->SetCurrentAction(action);
  this->PerformAction(this->CurrentAction);
  this->SetCurrentAction(NULL);
}

//----------------------------------------------------------------------------
void vtkKWInteractorStyleEventMap::OnChar()
{
  // DO NOT DO ANYTHING ON CHAR!
  // for compat reason, vtkKWRenderWidget::KeyPressCallback calls both
  // KeyPressEvent and CharEvent
  // Subclasses of this interactor typically handles KeyPress. For example
  // The 'R' key is redirected to perform specific reset cameras.
  // If OnChar() is left unimplemented, the superclass will pass it through
  // the vtkInteractorStyle super, which will pass it to the renderer to
  // perform a ResetCamera...
}

//----------------------------------------------------------------------------
void vtkKWInteractorStyleEventMap::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  
  os << indent << "EventMap: " << this->EventMap << endl;
  os << indent << "EventIdentifier: " << this->EventIdentifier << endl;
}
