//
// Created by martin on 21. 2. 2021.
//

#ifndef ARC_MATRIX_KDTREE_H
#define ARC_MATRIX_KDTREE_H
#include <opencv2/core.hpp>
#include "ArcExtraction.h"
#include "AAMBuild.h"
#include <memory>



/**
 * a node for KD tree
 */
class KDNode {
    int index;
public:
    std::unique_ptr<KDNode> right;
    std::unique_ptr<KDNode> left;


    KDNode() = default;

    int getIndex() {
        return index;
    }

    void setIndex(posArc arc) {
        this->index = arc.index;

    }

};

/**
 * A KD tree structure
 */
class KDTree {
    std::unique_ptr<KDNode> root;
public:
    KDTree() = default;
    void setRoot(std::unique_ptr<KDNode> node) {
        root = std::move(node);
    }
    KDNode* getRoot() {
        return root.get();
    }
};


/**
 *
 */


/**
 * builds a KDtree
 * @param arcs arcs with their indexes,
 * @param node current node
 * @param depth depth of the node in the tree
 * @param left boundary of the build
 * @param right boundary of the build
 */
void KDBuild(std::vector<posArc>& arcs,KDNode* node,int depth,int left,int right);

/**
 * walks a KD tree to find neighboring arcs
 * @param node root of search
 * @param arc arc combined with it's index
 * @param depth depth of the current node in the tree
 * @param dist max distance of the neighboring arc
 * @param arcs vector of all arcs
 * @param arcIndexes indexes of neighboring arcs
 */
void findNear(KDNode *node, posArc arc, int depth, double dist,const std::vector<std::vector<cv::Point2i>> &arcs , std::vector<int>& arcIndexes);
#endif //ARC_MATRIX_KDTREE_H
