// Copyright (c) 2016-2019 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.

#ifndef _AIS_ViewInputBuffer_HeaderFile
#define _AIS_ViewInputBuffer_HeaderFile

#include <Aspect_ScrollDelta.hxx>

#include <AIS_SelectionScheme.hxx>
#include <Graphic3d_Vec2.hxx>
#include <NCollection_Sequence.hxx>
#include <V3d_TypeOfOrientation.hxx>

//! Selection mode
enum AIS_ViewSelectionTool
{
  AIS_ViewSelectionTool_Picking,    //!< pick to select
  AIS_ViewSelectionTool_RubberBand, //!< rubber-band to select
  AIS_ViewSelectionTool_Polygon,    //!< polyline to select
  AIS_ViewSelectionTool_ZoomWindow, //!< zoom-in window (no selection)
};

//! Input buffer type.
enum AIS_ViewInputBufferType
{
  AIS_ViewInputBufferType_UI, //!< input buffer for filling from UI thread
  AIS_ViewInputBufferType_GL, //!< input buffer accessible  from GL thread
};

//! Auxiliary structure defining viewer events
class AIS_ViewInputBuffer
{
public:

  bool IsNewGesture;     //!< transition from one action to another

  NCollection_Sequence<Aspect_ScrollDelta> ZoomActions; //!< the queue with zoom actions

  struct _orientation
  {
    bool                  ToFitAll;         //!< perform FitAll operation
    bool                  ToSetViewOrient;  //!< set new view orientation
    V3d_TypeOfOrientation ViewOrient;       //!< new view orientation

    _orientation() : ToFitAll (false), ToSetViewOrient (false), ViewOrient (V3d_Xpos) {}
  } Orientation;

  struct _highlighting
  {
    bool            ToHilight; //!< perform dynamic highlighting at specified point
    Graphic3d_Vec2i Point;     //!< the new point for dynamic highlighting

    _highlighting() : ToHilight (false) {}
  } MoveTo;

  struct _selection
  {
    AIS_ViewSelectionTool Tool;          //!< perform selection
    AIS_SelectionScheme   Scheme;        //!< selection scheme
    NCollection_Sequence<Graphic3d_Vec2i>
                          Points;        //!< the points for selection
    bool                  ToApplyTool;   //!< apply rubber-band selection tool

    _selection() : Tool (AIS_ViewSelectionTool_Picking), Scheme (AIS_SelectionScheme_UNKNOWN), ToApplyTool (false) {}
  } Selection;

  struct _panningParams
  {
    bool            ToStart;    //!< start panning
    Graphic3d_Vec2i PointStart; //!< panning start point
    bool            ToPan;      //!< perform panning
    Graphic3d_Vec2i Delta;      //!< panning delta

    _panningParams() : ToStart (false), ToPan (false) {}
  } Panning;

  struct _draggingParams
  {
    bool            ToStart;    //!< start dragging
    bool            ToConfirm;  //!< confirm dragging
    bool            ToMove;     //!< perform dragging
    bool            ToStop;     //!< stop  dragging
    bool            ToAbort;    //!< abort dragging (restore previous position)
    Graphic3d_Vec2i PointStart; //!< drag start point
    Graphic3d_Vec2i PointTo;    //!< drag end point

    _draggingParams() : ToStart (false), ToConfirm (false), ToMove (false), ToStop (false), ToAbort (false) {}
  } Dragging;

  struct _orbitRotation
  {
    bool            ToStart;    //!< start orbit rotation
    Graphic3d_Vec2d PointStart; //!< orbit rotation start point
    bool            ToRotate;   //!< perform orbit rotation
    Graphic3d_Vec2d PointTo;    //!< orbit rotation end point

    _orbitRotation() : ToStart (false), ToRotate (false) {}
  } OrbitRotation;

  struct _viewRotation
  {
    bool            ToStart;    //!< start view rotation
    Graphic3d_Vec2d PointStart; //!< view rotation start point
    bool            ToRotate;   //!< perform view rotation
    Graphic3d_Vec2d PointTo;    //!< view rotation end point

    _viewRotation() : ToStart (false), ToRotate (false) {}
  } ViewRotation;

  struct _zrotateParams
  {
    Graphic3d_Vec2i Point;    //!< Z rotation start point
    double          Angle;    //!< Z rotation angle
    bool            ToRotate; //!< start Z rotation

    _zrotateParams() : Angle (0.0), ToRotate (false) {}
  } ZRotate;

public:

  AIS_ViewInputBuffer()
  : IsNewGesture (false) {}

  //! Reset events buffer.
  void Reset()
  {
    Orientation.ToFitAll = false;
    Orientation.ToSetViewOrient = false;
    MoveTo.ToHilight = false;
    Selection.ToApplyTool = false;
    IsNewGesture     = false;
    ZoomActions.Clear();
    Panning.ToStart    = false;
    Panning.ToPan      = false;
    Dragging.ToStart   = false;
    Dragging.ToConfirm = false;
    Dragging.ToMove    = false;
    Dragging.ToStop    = false;
    Dragging.ToAbort   = false;
    OrbitRotation.ToStart  = false;
    OrbitRotation.ToRotate = false;
    ViewRotation.ToStart   = false;
    ViewRotation.ToRotate  = false;
    ZRotate.ToRotate = false;
  }

};

#endif // _AIS_ViewInputBuffer_HeaderFile
