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

  Program:   ParaView
  Module:    vtkSMViewProxyInternals.h

  Copyright (c) Kitware, Inc.
  All rights reserved.
  See Copyright.txt or http://www.paraview.org/HTML/Copyright.html 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.

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

#ifndef vtkSMViewProxyInternals_h
#define vtkSMViewProxyInternals_h

#include <vtkBoundingBox.h>
#include <vtkCompressedVideoPacket.h>
#include <vtkJPEGReader.h>
#include <vtkOpenGLVideoFrame.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkTextRepresentation.h>
#include <vtkVideoDecoder.h>

#include <string>
#include <thread>

#include "vtk_rxcpp.h" // for rxcpp
// clang-format off
// ideally, we include rx-lite.hpp here.
#include VTK_REMOTING_RXCPP(rx.hpp)
// clang-format on

class vtkSMViewProxyInternals
{
public:
  const std::thread::id OwnerTID{ std::this_thread::get_id() };

  // The client window will have two layers.
  // Base layer contains the primary renderer that simply
  // draws the image we receive from the render service.
  // The second layer has two 2D renderers that display
  // interesting performance metrics as a key-value pair.
  // Two separate 2D renderers are used for a neat table-like appearance.
  //@{
  vtkSmartPointer<vtkRenderWindow> RenderWindow;
  vtkSmartPointer<vtkRenderer> Renderer;
  vtkSmartPointer<vtkTextRepresentation> AnnotationKeys;
  vtkSmartPointer<vtkTextRepresentation> AnnotationValues;
  vtkSmartPointer<vtkRenderer> Renderer2DForKeys;
  vtkSmartPointer<vtkRenderer> Renderer2DForValues;
  //@}

  // when the render window gets a chance to draw, it consumes packets from this queue in FIFO order
  std::queue<vtkSmartPointer<vtkCompressedVideoPacket>> PayloadQueue;

  // Use decoder when the render service is using a video codec and
  // the client wants the view to decode the bitstream.
  vtkSmartPointer<vtkVideoDecoder> VideoDecoder;

  // Stream the view output as png or webm, depends on render service codec type.
  //@{
  rxcpp::subjects::subject<vtkSmartPointer<vtkCompressedVideoPacket>> OutputStream;
  //@}

  // helps updating the server side camera.
  //@{
  vtkMTimeType LastCameraMTime{ 0 };
  bool InDrawOverlay{ false };
  //@}

  // keep track of the raytracing information so we can request for the next rendering pass
  //@{
  bool UsingRayTracing{ false };
  uint64_t RenderingPass{ 0 };
  uint64_t TotalRenderingPasses{ 0 };
  //@}

  // Keeps the render window interactor observers.
  //@{
  std::vector<unsigned long> InteractorObserverIds;
  unsigned long RenderWindowObserverId{ 0 };
  //@}

  // keep track of when the last overlay was drawn so we compute the perceived frame rate on the
  // client.
  // TODO: The Qt interactor adds an extra delay we cannot know from here.
  //@{
  std::chrono::high_resolution_clock::time_point LastOverlayTimePoint{
    std::chrono::high_resolution_clock::now()
  };
  long FrameRate{ 0 };
  //@}

  bool InteractiveRender = false;
  // when false, it allow packets to be queued for rendering.
  // useful when interactor controls rendering, default enabled (iren->EnableRenderOff to disable)
  // when true, the payload queue is flushed and results are rendered immediately.
  bool FlushPackets = false;
  vtkBoundingBox VisiblePropBounds;
  std::string DefaultRepresentationName;

  // Reader for Jpeg encoded packets
  vtkNew<vtkJPEGReader> JpegReader;
};

#endif // vtkSMViewProxyInternals_h
// VTK-HeaderTest-Exclude: vtkSMViewProxyInternals.h
