/*
 *******************************************************************************
 *
 *  Copyright 2026 RIEGL Laser Measurement Systems
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *  SPDX-License-Identifier: Apache-2.0
 *
 *******************************************************************************
 */
/*!
 *******************************************************************************
 *
 * \file    pointAttribute.h
 * \author  RIEGL LMS GmbH, Austria
 * \brief   Point attribute description
 * \version 2015-10-14/AW: Initial version
 * \version 2016-11-28/AW: Compression options added (#2423)
 * \version 2016-12-20/AW: New functions to load/save settings from/to JSON
 * \version 2017-03-22/AW: Point attribute scale factor added (#2552)
 * \version 2017-03-28/AW: Documentation of JSON load/save functions updated
 * \version 2017-11-09/AW: New function to suggest buffer data type (#2587)
 * \version 2018-03-09/AW: New attribute property "invalid value" added (#3047)
 * \version 2018-06-22/AW: Attribute length type changed to uint32 (#3117)
 * \version 2019-01-21/AW: New attribute property "lod settings" added
 * \version 2020-02-21/AW: Add "context-free" function variants (#3544)
 * \version 2022-01-26/AW: Add optional point attribute tags (#4128)
 * \version 2022-03-18/AW: Add optional list of named values (#4128)
 * \version 2023-10-04/AW: Add attribute definition string size limits (#4790)
 *
 * This class describes a point attribute. The database uses this
 * information for internal attribute representation and compression.
 *
 * While the name is a unique identifier, the description holds some
 * text that client programs might display the user in some way. Also
 * the physical unit is not used by the database but can be presented
 * to the user (see PointAttribute::unitSymbol).
 *
 * To avoid point attribute name conflicts, the names (not the titles)
 * shall contain a namespace prefix. Namespace and attribute name are
 * separated by a dot (".", e.g. "riegl.xyz"). The default namespace
 * "riegl" is used if no namespace is given.
 *
 * \remarks
 *
 * If the attribute is a vector (i.e. length > 1), then you might append
 * a zero-based vector element index to the attribute name when inserting,
 * updating or selecting points. Example: use "rgb[0]" to access the red
 * color component (0), the green (1) and blue (2) components are not read
 * or modified in this case.
 *
 * Furthermore, the minimum, maximum and default values are applied to all
 * elements of vectors and the vector length must be in the range [1..100000].
 *
 * PointAttribute::defaultValue is returned when reading a point attribute
 * that has never been written before. The value must be between minimum and
 * maximum (both inclusive).
 *
 * PointAttribute::invalidValue may be used to define a value that represents
 * an invalid/undefined/unknown value. The value must be between minimum and
 * maximum (both inclusive) and must be a multiple of the resolution value.
 * The value may be equal to the default value and you may use "NaN" (not a
 * number) to signal that there is no "invalid value".
 *
 * \note
 *
 * Attribute names may only contain following ASCII characters:
 *
 *   - a-z
 *   - A-Z
 *   - 0-9
 *   - .
 *   - _
 *
 * Attribute title, description and unit symbol may contain any UTF-8 character.
 *
 * \see riegl::rdb::pointcloud::PointAttributes
 *
 *******************************************************************************
 */

#ifndef RIEGL_RDB_POINTCLOUD_POINTATTRIBUTE_H
#define RIEGL_RDB_POINTCLOUD_POINTATTRIBUTE_H

//---< INCLUDES >---------------------------------------------------------------

#include "riegl/rdb.h"

//---< TYPE DEFINITIONS >-------------------------------------------------------

typedef struct RDBPointcloudPointAttribute RDBPointcloudPointAttribute; // forward declaration of implementation details

//---< FUNCTIONS >--------------------------------------------------------------

RDB_LIBRARY_API_BEGIN

//______________________________________________________________________________
/*!
 * \brief Default constructor
 *
 * All values are set to default values.
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_new,
    RDBContext                   *context,  //!< [in] library context
    RDBPointcloudPointAttribute **attribute //!< [out] handle of created object
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_new_cf,
    RDBPointcloudPointAttribute **attribute //!< [out] handle of created object
);

//______________________________________________________________________________
/*!
 * \brief Destroy point attribute object
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_delete,
    RDBContext                   *context,  //!< [in] library context
    RDBPointcloudPointAttribute **attribute //!< [in] handle of object to delete
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_delete_cf,
    RDBPointcloudPointAttribute **attribute //!< [in] handle of object to delete
);

//______________________________________________________________________________
/*!
 * \brief Load settings from JSON string
 *
 * This function parses the given JSON string and applies all available
 * properties - missing properties are silently ignored (i.e. the value
 * remains unchanged). When parsing the JSON string fails, an exception
 * is thrown.
 *
 * Example JSON string:
 *
 *     {
 *         "name": "riegl.reflectance",
 *         "title": "Reflectance",
 *         "tags": "",
 *         "description": "Target surface reflectance",
 *         "unit_symbol": "dB",
 *         "length": 1,
 *         "resolution": 0.01,
 *         "minimum_value": -327.68,
 *         "maximum_value": 327.67,
 *         "default_value": 0.0,
 *         "invalid_value": null,
 *         "named_values": {},
 *         "storage_class": "variable",
 *         "compression_options": "shuffle",
 *         "scale_factor": 1.0
 *     }
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_json_load,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] handle of object
    RDBString                    json       //!< [in] JSON string
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_json_load_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] handle of object
    RDBString                    json       //!< [in] JSON string
);

//______________________________________________________________________________
/*!
 * \brief Save settings to JSON string
 * \see rdb_pointcloud_point_attribute_json_load()
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_json_save,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] handle of object
    RDBString                   *json       //!< [out] JSON string
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_json_save_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] handle of object
    RDBString                   *json       //!< [out] JSON string
);

//______________________________________________________________________________
/*!
 * \brief Get buffer data type
 *
 * This function suggests a data type that is suitable to
 * construct a buffer for storing values of this attribute.
 *
 * The suggestion is based on the resolution, minimumValue
 * and maximumValue properties, all others are ignored.
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_data_type,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] handle of object
    uint32_t                    *result     //!< [out] data type enum
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_data_type_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] handle of object
    uint32_t                    *result     //!< [out] data type enum
);

//______________________________________________________________________________
/*!
 * \brief Get unique attribute name (for queries)
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_get_name,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    RDBString                   *value      //!< [out] current value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_get_name_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    RDBString                   *value      //!< [out] current value
);

//______________________________________________________________________________
/*!
 * \brief Set unique attribute name (for queries), string size limits: [1, 100]
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_set_name,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    RDBString                    value      //!< [in] new value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_set_name_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    RDBString                    value      //!< [in] new value
);

//______________________________________________________________________________
/*!
 * \brief Get attribute title (for display)
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_get_title,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    RDBString                   *value      //!< [out] current value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_get_title_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    RDBString                   *value      //!< [out] current value
);

//______________________________________________________________________________
/*!
 * \brief Set attribute title (for display), string size limits: [1, 100]
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_set_title,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    RDBString                    value      //!< [in] new value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_set_title_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    RDBString                    value      //!< [in] new value
);

//______________________________________________________________________________
/*!
 * \brief Get attribute tags (comma separated, e.g. "position, transform")
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_get_tags,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    RDBString                   *value      //!< [out] current value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_get_tags_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    RDBString                   *value      //!< [out] current value
);

//______________________________________________________________________________
/*!
 * \brief Set attribute tags (comma separated, e.g. "position, transform"), string size limits: [0, 5000]
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_set_tags,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    RDBString                    value      //!< [in] new value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_set_tags_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    RDBString                    value      //!< [in] new value
);

//______________________________________________________________________________
/*!
 * \brief Get attribute description (for display)
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_get_description,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    RDBString                   *value      //!< [out] current value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_get_description_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    RDBString                   *value      //!< [out] current value
);

//______________________________________________________________________________
/*!
 * \brief Set attribute description (for display), string size limits: [0, 5000]
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_set_description,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    RDBString                    value      //!< [in] new value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_set_description_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    RDBString                    value      //!< [in] new value
);

//______________________________________________________________________________
/*!
 * \brief Get physical unit symbol (e.g. "m", "rad", "K")
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_get_unit_symbol,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    RDBString                   *value      //!< [out] current value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_get_unit_symbol_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    RDBString                   *value      //!< [out] current value
);

//______________________________________________________________________________
/*!
 * \brief Set physical unit symbol (e.g. "m", "rad", "K"), string size limits: [0, 100]
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_set_unit_symbol,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    RDBString                    value      //!< [in] new value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_set_unit_symbol_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    RDBString                    value      //!< [in] new value
);

//______________________________________________________________________________
/*!
 * \brief Get number of dimensions/elements (1: scalar, >1: vector, e.g. 3 for point coordinates)
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_get_length,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    uint8_t                     *value      //!< [out] current value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_get_length_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    uint8_t                     *value      //!< [out] current value
);

//______________________________________________________________________________
/*!
 * \brief Get number of dimensions/elements (1: scalar, >1: vector, e.g. 3 for point coordinates)
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_get_length_u32,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    uint32_t                    *value      //!< [out] current value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_get_length_u32_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    uint32_t                    *value      //!< [out] current value
);

//______________________________________________________________________________
/*!
 * \brief Set number of dimensions/elements (1: scalar, >1: vector, e.g. 3 for point coordinates)
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_set_length,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    uint8_t                      value      //!< [in] new value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_set_length_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    uint8_t                      value      //!< [in] new value
);

//______________________________________________________________________________
/*!
 * \brief Set number of dimensions/elements (1: scalar, >1: vector, e.g. 3 for point coordinates)
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_set_length_u32,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    uint32_t                     value      //!< [in] new value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_set_length_u32_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    uint32_t                     value      //!< [in] new value
);

//______________________________________________________________________________
/*!
 * \brief Get expected value resolution
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_get_resolution,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    double                      *value      //!< [out] current value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_get_resolution_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    double                      *value      //!< [out] current value
);

//______________________________________________________________________________
/*!
 * \brief Set expected value resolution
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_set_resolution,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    double                       value      //!< [in] new value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_set_resolution_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    double                       value      //!< [in] new value
);

//______________________________________________________________________________
/*!
 * \brief Get theoretical minimum value
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_get_minimum_value,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    double                      *value      //!< [out] current value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_get_minimum_value_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    double                      *value      //!< [out] current value
);

//______________________________________________________________________________
/*!
 * \brief Set theoretical minimum value
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_set_minimum_value,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    double                       value      //!< [in] new value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_set_minimum_value_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    double                       value      //!< [in] new value
);

//______________________________________________________________________________
/*!
 * \brief Get theoretical maximum value
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_get_maximum_value,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    double                      *value      //!< [out] current value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_get_maximum_value_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    double                      *value      //!< [out] current value
);

//______________________________________________________________________________
/*!
 * \brief Set theoretical maximum value
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_set_maximum_value,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    double                       value      //!< [in] new value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_set_maximum_value_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    double                       value      //!< [in] new value
);

//______________________________________________________________________________
/*!
 * \brief Get default value
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_get_default_value,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    double                      *value      //!< [out] current value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_get_default_value_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    double                      *value      //!< [out] current value
);

//______________________________________________________________________________
/*!
 * \brief Set default value
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_set_default_value,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    double                       value      //!< [in] new value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_set_default_value_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    double                       value      //!< [in] new value
);

//______________________________________________________________________________
/*!
 * \brief Get invalid value
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_get_invalid_value,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    double                      *value      //!< [out] current value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_get_invalid_value_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    double                      *value      //!< [out] current value
);

//______________________________________________________________________________
/*!
 * \brief Set invalid value
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_set_invalid_value,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    double                       value      //!< [in] new value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_set_invalid_value_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    double                       value      //!< [in] new value
);

//______________________________________________________________________________
/*!
 * \brief Get list of VALUE=NAME pairs separated by a single line feed character (LF, ASCII 0x0A)
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_get_named_values,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    RDBString                   *value      //!< [out] current value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_get_named_values_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    RDBString                   *value      //!< [out] current value
);

//______________________________________________________________________________
/*!
 * \brief Set list of VALUE=NAME pairs separated by a single line feed character (LF, ASCII 0x0A), string size limits: [0, 1000000]
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_set_named_values,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    RDBString                    value      //!< [in] new value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_set_named_values_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    RDBString                    value      //!< [in] new value
);

//______________________________________________________________________________
/*!
 * \brief Get storage class
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_get_storage_class,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    uint8_t                     *value      //!< [out] current value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_get_storage_class_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    uint8_t                     *value      //!< [out] current value
);

//______________________________________________________________________________
/*!
 * \brief Set storage class
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_set_storage_class,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    uint8_t                      value      //!< [in] new value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_set_storage_class_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    uint8_t                      value      //!< [in] new value
);

//______________________________________________________________________________
/*!
 * \brief Get compression options
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_get_compression_options,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    uint8_t                     *value      //!< [out] current value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_get_compression_options_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    uint8_t                     *value      //!< [out] current value
);

//______________________________________________________________________________
/*!
 * \brief Set compression options
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_set_compression_options,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    uint8_t                      value      //!< [in] new value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_set_compression_options_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    uint8_t                      value      //!< [in] new value
);

//______________________________________________________________________________
/*!
 * \brief Get LOD settings
 *
 * This field defines the method to be used to generate level of detail
 * data (LOD) for this point attribute. Depending on the LOD mode defined
 * during database creation (see CreateSettings::LodMode), several LOD
 * methods are available. A list of all methods and their settings can
 * be found in file "/manual/riegl_rdb_lod_methods.json" in the RDB SDK.
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_get_lod_settings,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    RDBString                   *value      //!< [out] current value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_get_lod_settings_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    RDBString                   *value      //!< [out] current value
);

//______________________________________________________________________________
/*!
 * \brief Set LOD settings, string size limits: [0, 50000]
 * \see rdb_pointcloud_point_attribute_get_lod_settings()
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_set_lod_settings,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    RDBString                    value      //!< [in] new value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_set_lod_settings_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    RDBString                    value      //!< [in] new value
);

//______________________________________________________________________________
/*!
 * \brief Get scale factor
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_get_scale_factor,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    double                      *value      //!< [out] current value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_get_scale_factor_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    double                      *value      //!< [out] current value
);

//______________________________________________________________________________
/*!
 * \brief Set scale factor
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_set_scale_factor,
    RDBContext                  *context,   //!< [in] library context
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    double                       value      //!< [in] new value
);
RDB_FUNCTION_CF(rdb_pointcloud_point_attribute_set_scale_factor_cf,
    RDBPointcloudPointAttribute *attribute, //!< [in] attribute handle
    double                       value      //!< [in] new value
);

//__________________________________________________________________________
/*!
 * \brief Get attribute name and vector index from attribute descriptor
 *
 * This function decodes the given attribute descriptor into attribute name and attribute
 * vector index. The optional vector index is enclosed in square brackets and follows the
 * point attribute name. If no vector index is given, then index -1 is returned. If the
 * vector index cannot be interpreted as a single positive integer value, then an empty
 * name and index -2 is returned.
 *
 * Examples:
 *   descriptor | name  | index
 *  ------------|-------|-------
 *    "xyz"     | "xyz" |  -1
 *    "xyz[0]"  | "xyz" |   0
 *    "rgb[1]"  | "rgb" |   1
 *
 * \note 'name' is expected to point to a string that is at least as long as
 *       the 'descriptor' string plus 10 extra characters.
 *
 * \returns the number of characters written to 'name'
 */
RDB_FUNCTION(rdb_pointcloud_point_attribute_decode_descriptor,
    RDBString descriptor, //!< [in]  attribute descriptor, e.g. "xyz", "rgb[1]"
    RDBString name,       //!< [out] attribute name, e.g. "xyz", "rgb"
    int32_t  *index       //!< [out] attribute vector index, e.g. -1, 1
);

RDB_LIBRARY_API_END

#endif // RIEGL_RDB_POINTCLOUD_POINTATTRIBUTE_H
