/*
 *******************************************************************************
 *
 *  Copyright 2025 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    graphNode.h
 * \author  RIEGL LMS GmbH, Austria
 * \brief   Index graph node
 * \version 2015-10-14/AW: Initial version
 *
 *******************************************************************************
 */

#ifndef RIEGL_RDB_POINTCLOUD_GRAPHNODE_H
#define RIEGL_RDB_POINTCLOUD_GRAPHNODE_H

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

#include <stdint.h>
#include "riegl/rdb.h"

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

typedef uint32_t RDBPointcloudGraphNodeID;
typedef uint32_t RDBPointcloudGraphNodeChildCount;
typedef uint64_t RDBPointcloudGraphNodePointCount;

//---< STRUCT GraphNode >--------------------------------------------------------
/*!
 * \brief Graph Node
 *
 * This class represents an index graph node. The index structure is
 * used to organize the point cloud and consists of at least one node.
 *
 * The index space is given by the primary point attribute defined
 * during point cloud database creation (see class CreateSettings).
 *
 * Each graph node covers a certain range of the index space and
 * has a number of sub-nodes (aka. "child nodes"). All child nodes
 * lie within the range of the parent node whereas they are usually
 * smaller. A node without child nodes is called a leaf node. Note
 * that any nodes may overlap in index space as well as all other
 * point dimensions (attributes).
 *
 * This documentation uses the term "branch" for a node and all
 * children and grandchildren up to and including the leaf nodes.
 *
 * \see riegl::rdb::Pointcloud::stat()
 */
#pragma pack(push, 1)
typedef struct RDBPointcloudGraphNode
{
    RDBPointcloudGraphNodeID         id;              //!< unique node identifier
    RDBPointcloudTransactionID       revision;        //!< ID of last transaction that has modified any attribute of this branch
    struct RDBPointcloudGraphNode  **children;        //!< list of pointers to child nodes
    RDBPointcloudGraphNodeChildCount childCount;      //!< number of child nodes (without grandchildren)
    RDBPointcloudGraphNodePointCount pointCountTotal; //!< total number of points in all leaf nodes of the branch
    RDBPointcloudGraphNodePointCount pointCountNode;  //!< number of points in this node (see notes about LOD)
} RDBPointcloudGraphNode;
#pragma pack(pop)

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

RDB_LIBRARY_API_BEGIN

//______________________________________________________________________________
/*!
 * \brief Create graph node
 */
RDB_FUNCTION(rdb_pointcloud_graph_node_new,
    RDBContext              *context, //!< [in] library context
    RDBPointcloudGraphNode **node     //!< [out] graph node
);

//______________________________________________________________________________
/*!
 * \brief Delete graph node
 */
RDB_FUNCTION(rdb_pointcloud_graph_node_delete,
    RDBContext              *context, //!< [in] library context
    RDBPointcloudGraphNode **node     //!< [in] graph node
);

RDB_LIBRARY_API_END

#endif // RIEGL_RDB_POINTCLOUD_GRAPHNODE_H
