/******************************************************************************
 * Copyright 2021 NVIDIA Corporation. All rights reserved.
 *****************************************************************************/
/// \file
/// \brief Database element for a colormap

#ifndef NVIDIA_INDEX_ICOLORMAP_H
#define NVIDIA_INDEX_ICOLORMAP_H

#include <mi/base/interface_declare.h>
#include <nv/index/iattribute.h>

namespace nv
{
namespace index
{

/// An abstract representation of a colormap for storing in the distributed database.
///
/// \ingroup nv_index_scene_description_attribute
///
class IColormap :
    public mi::base::Interface_declare<0x68ba9632,0xe3d6,0x4ced,0xa8,0xd7,0x32,0x0f,0x87,0x33,0xde,0x1b,
                                       nv::index::IAttribute>
{
public:
    /// Returns an entry of the colormap.
    ///
    /// \note This method is not used in the IndeX library to access the colormap array. It
    /// should be used by an application.
    ///
    /// \param[in] idx Index in the colormap
    ///
    /// \return Color at the given index
    virtual mi::math::Color_struct get_color(mi::Uint32 idx) const = 0;

    /// Sets an entry of the colormap.
    ///
    /// \param[in] idx   Index in the colormap
    /// \param[in] color Color to be set
    virtual void set_color(
        mi::Uint32                    idx,
        const mi::math::Color_struct& color) = 0;

    /// Set the colormap values using an array of color values.
    ///
    /// \param[in] colormap_values      Array of color values.
    /// \param[in] nb_entries           Number of color values.
    ///
    virtual void set_colormap(
        const mi::math::Color_struct* colormap_values,
        mi::Uint32                    nb_entries) = 0;

    /// Returns a reference to the colormap array.
    ///
    /// \note This method is used internally by the IndeX library to access the colormap data.
    ///
    /// \return Constant reference to the internal colormap array
    virtual const mi::math::Color_struct* get_colormap() const = 0;

    /// Returns the number of entries in the colormap.
    /// \return number of colormap entries
    virtual mi::Uint32 get_number_of_entries() const = 0;

    /// Returns the range of colormap indices in which color values are non-transparent.
    /// \param[out] min Minimum index with non-transparent color (inclusive).
    /// \param[out] max Maximum index with non-transparent color (inclusive).
    virtual void get_non_transparent_range(
        mi::Uint32& min,
        mi::Uint32& max) const = 0;

    /// Sets the domain of the colormap, describing how source data
    /// (e.g. voxel values) should be mapped to color values.
    ///
    /// The domain is normalized to support different types of
    /// source values: The default domain [0.0, 1.0] corresponds to
    /// raw data values in the range [0, 255] for 8-bit integer
    /// data, [0, 65535] for 16-bit integer data, or [0.0, 1.0] for
    /// normalized float data. For non-normalized float data the
    /// domain should be set to the actual value range found in the
    /// data.
    ///
    /// The domain may also be outside of the actual value range of
    /// the data, or just cover part of the value range. Data values
    /// outside of the specified domain treated according to the
    /// \c Domain_boundary_mode controlled by \c set_domain_boundary_mode().
    ///
    /// Note that \c value_first > \c value_last is valid, and will
    /// effectively flip the colormap. If \c value_first is equal to
    /// \c value_last then the default domain [0.0, 1.0] will be
    /// used.
    ///
    /// \param[in] value_first  Data value (normalized) that should be
    ///                         mapped to the first entry of the colormap.
    /// \param[in] value_last   Data value (normalized) that should be
    ///                         mapped to the last entry of the colormap.
    virtual void set_domain(
        mi::Float32 value_first,
        mi::Float32 value_last) = 0;

    /// Returns the domain of the colormap.
    ///
    /// \param[out] value_first  Data value (normalized) that should be
    ///                          mapped to the first entry of the colormap.
    /// \param[out] value_last   Data value (normalized) that should be
    ///                          mapped to the last entry of the colormap.
    virtual void get_domain(
        mi::Float32& value_first,
        mi::Float32& value_last) const = 0;

    /// Controls how data values that are outside of the colormap's
    /// domain should be treated.
    enum Domain_boundary_mode
    {
        /// Data values outside of the domain will be clamped to the
        /// domain, i.e. will be mapped to either the first or last
        /// entry of the colormap.
        CLAMP_TO_EDGE        = 0,
        /// Data values outside of the domain will be considered
        /// fully transparent and therefore ignored for rendering
        CLAMP_TO_TRANSPARENT = 1
    };

    /// Sets the mode for handling data values outside of the
    /// colormap's domain.
    ///
    /// \param[in] mode Domain boundary mode
    virtual void set_domain_boundary_mode(Domain_boundary_mode mode) = 0;

    /// Returns the mode for handling data values outside of the
    /// colormap's domain.
    ///
    /// \return Current domain boundary mode
    virtual Domain_boundary_mode get_domain_boundary_mode() const = 0;
};

}} // namespace index / nv

#endif // NVIDIA_INDEX_ICOLORMAP_H
