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

  Program:   ParaView
  Module:    vtkVolumeRepresentation.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 vtkVolumeRepresentation
 * @brief Abstract base class for volume representations. Provides some functionality common to
 * volume representations.
 *
 */
#ifndef vtkVolumeRepresentation_h
#define vtkVolumeRepresentation_h

#include "vtkPVDataRepresentation.h"

#include "vtkRemotingServerManagerViewsModule.h" //needed for exports

#include <memory> // for std::unique_ptr

class vtkColorTransferFunction;
class vtkDataSet;
class vtkOutlineSource;
class vtkPiecewiseFunction;
class vtkVolumeProperty;
class vtkPVLODVolume;
class vtkVolumeProperty;

class VTKREMOTINGSERVERMANAGERVIEWS_EXPORT vtkVolumeRepresentation : public vtkPVDataRepresentation
{
public:
  vtkTypeMacro(vtkVolumeRepresentation, vtkPVDataRepresentation);
  void PrintSelf(ostream& os, vtkIndent indent) override;

  /**
   * Get/Set the visibility for this representation. When the visibility of
   * representation of false, all view passes are ignored.
   */
  void SetVisibility(bool val) override;

  ///@{
  /**
   * Get/Set the vtkVolumeProperty. This is non-null only on render-service and
   * client.
   */
  void SetProperty(vtkVolumeProperty* property);
  vtkVolumeProperty* GetProperty() const;
  ///@}

  ///@{
  /**
   * Get/Set the vtkPVLODVolume actor. This is non-null only on rendering services.
   */
  void SetActor(vtkPVLODVolume* actor);
  vtkPVLODVolume* GetActor() const;
  ///@}

  //***************************************************************************
  // Forwarded to vtkVolumeProperty and vtkProperty (when applicable).
  void SetMapScalars(bool);
  bool GetMapScalars();
  void SetMultiComponentsMapping(bool);
  bool GetMultiComponentsMapping();

  //***************************************************************************
  // For separate opacity array support
  void SetUseSeparateOpacityArray(bool);
  bool GetUseSeparateOpacityArray();
  void SelectOpacityArray(int, int, int, int, const char* name);
  void SelectOpacityArrayComponent(int component);

  // Wrapper wraps only methods Set/Get methods (and methods with no arguments"
  void SetOpacityArray(int a, int b, int c, int fieldAssociation, const char* name)
  {
    this->SelectOpacityArray(a, b, c, fieldAssociation, name);
  }
  void SetOpacityArrayComponent(int component) { this->SelectOpacityArrayComponent(component); }

protected:
  vtkVolumeRepresentation();
  ~vtkVolumeRepresentation() override;

  ///@{
  void InitializeForDataProcessing() override;
  void InitializeForRendering() override;
  ///@}

  /**
   * Appends a designated opacity component to a scalar array used for color/opacity mapping.
   */
  bool AppendOpacityComponent(vtkDataSet* dataset);

  unsigned long GetDataSize();
  void SetDataSize(unsigned long dataSize);

  double* GetDataBounds();
  void SetDataBounds(double* dataBounds);

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

  class vtkRenderingInternals;

  std::unique_ptr<vtkRenderingInternals> RInternals;
};

#endif // vtkVolumeRepresentation_h
