// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
// SPDX-License-Identifier: BSD-3-Clause

#ifndef vtkWebGPUComputeTextureView_h
#define vtkWebGPUComputeTextureView_h

#include "vtkObject.h"                // for superclass
#include "vtkRenderingWebGPUModule.h" // For export macro
#include "vtkSetGet.h"                // for get/set macros
#include "vtkWebGPUComputeTexture.h"  // for the aspect, dimension, format, ... attributes

VTK_ABI_NAMESPACE_BEGIN

class VTKRENDERINGWEBGPU_EXPORT vtkWebGPUComputeTextureView : public vtkObject
{
public:
  vtkTypeMacro(vtkWebGPUComputeTextureView, vtkObject);
  static vtkWebGPUComputeTextureView* New();

  /**
   * What will the shader sample from the texture when calling a sampling function.
   *
   * This may be useful for example when your texture has the DEPTH24_STENCIL8 format but you're
   * only interested in the depth in the shader. For this example, you will use TextureAspect::DEPTH
   * so that the shader samplers only sample the depth.
   *
   * ASPECT_ALL: Sample everything. Default.
   * ASPECT_DEPTH: Only sample the depth part
   * ASPECT_STENCIL: Only sample the stencil part
   */
  enum TextureViewAspect
  {
    ASPECT_ALL,
    ASPECT_DEPTH,
    ASPECT_STENCIL
  };

  /**
   * The mode of the texture view to define what operations will be doable on the texture in the
   * shader.
   *
   * UNDEFINED: Texture view mode not set. Default.
   * READ_ONLY: The compute shader can only read from the texture and a sampler can be usedc
   * READ_ONLY_STORAGE: The compute shader can only read from the texture and a sampler cannot be
   * used.
   * WRITE_ONLY_STORAGE: The compute shader can only write to the texture and a sampler cannot
   * be used READ_WRITE_STORAGE: The compute shader can read and write to the texture and a sampler
   * cannot be used
   */
  enum TextureViewMode
  {
    UNDEFINED,
    READ_ONLY,
    READ_ONLY_STORAGE,
    WRITE_ONLY_STORAGE,
    READ_WRITE_STORAGE
  };

  ///@{
  /**
   * Get/set mipmap level that this texture view represents
   */
  vtkGetMacro(BaseMipLevel, int);
  vtkSetMacro(BaseMipLevel, int);
  ///@}

  ///@{
  /**
   * Get/set the number of mipmaps that this texture view represents. Can only be 1 for storage
   * textures.
   */
  vtkGetMacro(MipLevelCount, int);
  vtkSetMacro(MipLevelCount, int);
  ///@}

  ///@{
  /**
   * Get/set the bind group index of the texture view
   */
  vtkGetMacro(Group, vtkIdType);
  vtkSetMacro(Group, vtkIdType);
  ///@}

  ///@{
  /**
   * Get/set the binding index of the texture view
   */
  vtkGetMacro(Binding, vtkIdType);
  vtkSetMacro(Binding, vtkIdType);
  ///@}

  ///@{
  /**
   * Get/set the aspect of the texture view
   */
  vtkGetMacro(Aspect, vtkWebGPUComputeTextureView::TextureViewAspect);
  vtkSetMacro(Aspect, vtkWebGPUComputeTextureView::TextureViewAspect);
  ///@}

  ///@{
  /**
   * Get/set the dimension of the texture view
   */
  vtkGetMacro(Dimension, vtkWebGPUComputeTexture::TextureDimension);
  vtkSetMacro(Dimension, vtkWebGPUComputeTexture::TextureDimension);
  ///@}

  ///@{
  /**
   * Get/set the format of the texture view
   */
  vtkGetMacro(Format, vtkWebGPUComputeTexture::TextureFormat);
  vtkSetMacro(Format, vtkWebGPUComputeTexture::TextureFormat);
  ///@}

  ///@{
  /**
   * Get/set the mode of the texture view
   */
  vtkGetMacro(Mode, vtkWebGPUComputeTextureView::TextureViewMode);
  vtkSetMacro(Mode, vtkWebGPUComputeTextureView::TextureViewMode);
  ///@}

  ///@{
  /**
   * Get/set the label of the texture view. This attribute is used for debugging is something goes
   * wrong
   */
  vtkGetMacro(Label, std::string&);
  vtkSetMacro(Label, std::string);
  ///@}

private:
  friend class vtkWebGPUComputePass;

  ///@{
  /**
   * Get/set the index (within the compute pass that created the texture) of the texture that this
   * texture view is a view of.
   */
  vtkGetMacro(AssociatedTextureIndex, int);
  vtkSetMacro(AssociatedTextureIndex, int);
  ///@}

  // Mip level of the base texture that this texture view gives a view on
  int BaseMipLevel = 0;
  // How many mip levels this texture view give the shader access to
  int MipLevelCount = 1;

  // Bind group of the texture view
  vtkIdType Group = -1;

  // Binding of the texture view
  vtkIdType Binding = -1;

  // What aspect of the texture is going to be sampled by the samplers in the shaders sampling this
  // texture
  vtkWebGPUComputeTextureView::TextureViewAspect Aspect = TextureViewAspect::ASPECT_ALL;

  // Dimension of the texture view
  vtkWebGPUComputeTexture::TextureDimension Dimension =
    vtkWebGPUComputeTexture::TextureDimension::DIMENSION_2D;

  // Format of the texture view
  vtkWebGPUComputeTexture::TextureFormat Format =
    vtkWebGPUComputeTexture::TextureFormat::RGBA8_UNORM;

  // Mode of the texture view
  vtkWebGPUComputeTextureView::TextureViewMode Mode =
    vtkWebGPUComputeTextureView::TextureViewMode::UNDEFINED;

  // Label used for debugging if something goes wrong
  std::string Label = "Texture view";

  // Texture index of the texture that this texture view views. This index is only viable in the
  // compute pass that created the texture.
  int AssociatedTextureIndex = -1;
};

VTK_ABI_NAMESPACE_END

#endif
