#ifndef SQLTREENODE_H
#define SQLTREENODE_H

#include <memory>

#include <vector>

#include <type_traits>

#include <utility>

#include <QString>

// bi-directional node
// the way back is realized

template<typename DataType>
struct SqlTreeNode {
public:
  const size_t recordIdentifier;
  DataType data;
  SqlTreeNode *parent;
  //std::unique_ptr<std::vector<std::unique_ptr<SqlTreeNode>>> nestedNodes;
  std::vector<std::unique_ptr<SqlTreeNode>> nestedNodes;

public:
  explicit SqlTreeNode();
//  explicit SqlTreeNode(SqlTreeNode &&other);
  explicit SqlTreeNode(const SqlTreeNode &other) = delete;

  explicit SqlTreeNode(SqlTreeNode *parent, size_t recordIdentifier,
                       const DataType &data);
  explicit SqlTreeNode(SqlTreeNode *parent, size_t recordIdentifier,
                       DataType &&data);

public:
  template <typename T,
            typename = std::enable_if_t<std::is_same<
                DataType, std::remove_cv_t<std::remove_reference_t<T>>>::value>>
  SqlTreeNode<DataType> *createFront(size_t recordIdentifier, T &&newNodeData);
  template <typename T,
            typename = std::enable_if_t<std::is_same<
                DataType, std::remove_cv_t<std::remove_reference_t<T>>>::value>>
  SqlTreeNode<DataType> *createBack(size_t recordIdentifier, T &&newNodeData);
  void remove(SqlTreeNode *node);
};

#include "sqltreenode.tpp"

#endif // SQLTREENODE_H
