// Copyright 2023 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#pragma once

#include "../common/DataShared.h"
#include "openvkl/VKLFormat.h"
#include "openvkl/VKLTemporalFormat.h"
#include "openvkl/vdb/topology.h"  // This file is generated by cmake.

#ifdef __cplusplus
namespace ispc {
#endif  // __cplusplus

#ifndef __ISPC_STRUCT_VdbLevel__
#define __ISPC_STRUCT_VdbLevel__
  struct VdbLevel
  {
    vkl_uint64 numNodes;

    // For each *node*, the origin in root-relative index space.
    vec3ui *origin;

    // Voxels for node 0, node 1, node 2, ...
    vkl_uint64 *voxels;

    // For each voxel, the range of values contained within, by attribute:
    // (range0, range1, ..., rangeNumAttributes)_0, [...]
    range1f *valueRange;
  };
#endif

#ifndef __ISPC_STRUCT_VdbGrid__
#define __ISPC_STRUCT_VdbGrid__
  /*
   * A grid is a collection of levels.
   */
  struct VdbGrid
  {
    // Global grid parameters.
    float objectToIndex[12];  // Row-major transformation matrix, 3x4,
                              // rotation-shear-scale | translation
    float indexToObject[12];  // Row-major transformation matrix, 3x4,
                              // rotation-shear-scale | translation
    vec3i rootOrigin;         // In index scale space.
    vec3ui activeSize;        // Size of the root node, in voxels,
    box3f domainBoundingBox;  // Domain space bounding box (different
                              // for constant cell data vs vertex centered data
                              // interpretation)
    bool constantCellData;    // Data is either considered constant per cell, or
                              // vertex-centered.

    vkl_uint64 numLeaves;
    vkl_uint32 numAttributes;
    bool allLeavesCompact;   // Do we only have compact (non strided) leaf data?
    bool allLeavesConstant;  // Are all leaf nodes temporally constant?

    vkl_uint32 *attributeTypes;  // Data type for each attribute.

    // Per-node data for sparse / non-dense volumes only.
    const vkl_int32 *leafStructuredTimesteps;
    Data1D *leafUnstructuredIndices;
    Data1D *leafUnstructuredTimes;

    // Per-attribute data for sparse / non-dense volumes only: size [numLeaves *
    // numAttributes]
    Data1D *leafData;

    // Optional: per-attribute node-packed data for sparse / non-dense volumes
    // only: size [numAttributes]
    bool packedAddressing32;
    Data1D *nodesPackedDense;
    Data1D *nodesPackedTile;

    // Parameters for dense volumes only.
    bool dense;
    vec3i denseDimensions;
    Data1D *denseData;  // Per-attribute data: size [numAttributes]
    VKLTemporalFormat denseTemporalFormat;
    int denseTemporallyStructuredNumTimesteps;
    Data1D denseTemporallyUnstructuredIndices;
    Data1D denseTemporallyUnstructuredTimes;

    // Level data.
    VdbLevel levels[VKL_VDB_NUM_LEVELS - 1];
  };
#endif

#ifdef __cplusplus
}
#endif  // __cplusplus