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

  Program:   ParaView
  Module:    vtkRemoteObjectProviderViews.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.

=========================================================================*/
/**
 * @class vtkRemoteObjectProviderViews
 * @brief
 *
 */

#ifndef vtkRemoteObjectProviderViews_h
#define vtkRemoteObjectProviderViews_h

#include "vtkPacket.h" // for vtkPacket
#include "vtkRemoteObjectProvider.h"
#include "vtkRemotingServerManagerViewsModule.h" // for exports

class vtkCamera;
class vtkMultiProcessController;
class vtkObjectStore;
class vtkObject;

class VTKREMOTINGSERVERMANAGERVIEWS_EXPORT vtkRemoteObjectProviderViews
  : public vtkRemoteObjectProvider
{
public:
  static vtkRemoteObjectProviderViews* New();
  vtkTypeMacro(vtkRemoteObjectProviderViews, vtkRemoteObjectProvider);
  void PrintSelf(ostream& os, vtkIndent indent) override;

  static const char* GetImageChannelName() { return "pvview-image-stream"; }
  static const char* GetDataChannelName() { return "pvview-data-stream"; }

  ///@{
  static vtkPacket Render(vtkTypeUInt32 gid, vtkCamera* camera, bool interactive);
  ///@}

protected:
  vtkRemoteObjectProviderViews();
  ~vtkRemoteObjectProviderViews() override;

  ///@{
  /**
   * Overridden to preview/process render requests.
   */
  void Preview(const vtkPacket& packet) override;
  vtkPacket Process(const vtkPacket& packet) override;
  ///@}

  void InitializeInternal(vtkService* service) override;

  /**
   * Overridden to handle views.
   */
  vtkNJson PiggybackInformation(vtkObject* object) const override;

private:
  vtkRemoteObjectProviderViews(const vtkRemoteObjectProviderViews&) = delete;
  void operator=(const vtkRemoteObjectProviderViews&) = delete;

  /**
   * Sets up observers so that the data-service can publish geometry on the data channel
   * and that the render-service can publish rendering results on the image channel.
   */
  void HandleObjectStoreEvent(vtkObject* caller, unsigned long eventId, void* callData);

  /**
   * Publishes geometry to the data channel. The data comes from the data delivery manager in the
   * DS.
   */
  void PushViewData(vtkObject* caller, unsigned long eventId, void* callData);

  /**
   * Publish image content on `pvview-image-stream`
   */
  void HandleViewResult(vtkObject* caller, unsigned long eventId, void* callData);

  class vtkInternals;
  std::unique_ptr<vtkInternals> Internals;
};

#endif
