#ifndef SYMBOL_MATRIX_HPP
#define SYMBOL_MATRIX_HPP

#include <cstdint>

typedef struct symbol_cblk_s
{
    int32_t     m_snodeid;  // Id of the supernodes this cblk belongs to
    int32_t     m_fcolnum;  // First column index
    int32_t     m_lcolnum;  // Last column index (inclusive)
    int32_t     m_bloknum;  // First blok in column
    int32_t     m_flags;    // Flags
    float       m_color;
} symbol_cblk_t;

typedef struct symbol_blok_s
{
    int32_t     m_frownum;  // First row index
    int32_t     m_lrownum;  // Last row index (inclusive)
    int32_t     m_lcblknm;  // Local column blok
    int32_t     m_fcblknm;  // Facing column blok

    uint32_t    m_localization; // Localization
    int32_t     m_flags;
    float       m_color;
} symbol_blok_t;

#define BLOK_FLAG_IN_TREE    1

/*

 How localization works ?
 => See Z-curve identification

 We use Z-curve to ID the quadtree nodes and we flip the bit of the level.
 For example if we are in the third level of quadtreefication and we have the ID 2:

 0000 0000 0001 0010
 ^   ^
 |   ID of the node
 Bit flipped for the level

 With this technique we can store a 32 bits localization to allow 15 levels of details
 and know the parents of any node due to the Z-curve :D

 */

typedef struct symbol_matrix_s
{
    int32_t         m_baseval;
    int32_t         m_dof;

    int32_t         m_sndenbr; // Supernodes number (= cblknbr if no order file)
    int32_t         m_cblknbr; // Column blocks number
    int32_t         m_bloknbr; // Block number
    int32_t         m_colsnbr; // Column number
    int32_t         m_rowsnbr; // Row number

    int32_t*        m_sndetab;
    symbol_cblk_t*  m_cblktab;
    symbol_blok_t*  m_bloktab;
    int32_t*        m_browtab;
} symbol_matrix_t;

void symbol_matrix_init(symbol_matrix_t* matrix);
void symbol_matrix_deinit(symbol_matrix_t* matrix);

void symbol_matrix_print_stats(symbol_matrix_t* matrix);

#endif
