namespace mrpt::vision::detail

namespace detail {

// structs

template <typename distance_t, typename element_t>
struct TSIFTDesc2KDTree_Adaptor;

template <typename distance_t, typename element_t>
struct TSURFDesc2KDTree_Adaptor;

// global functions

template <typename FEATLIST>
void trackFeatures_checkResponses(
    FEATLIST& featureList,
    const CImage& cur_gray,
    const float minimum_KLT_response,
    const unsigned int KLT_response_half_win,
    const unsigned int max_x,
    const unsigned int max_y
    );

void trackFeatures_checkResponses< CFeatureList >(
    CFeatureList& featureList,
    const CImage& cur_gray,
    const float minimum_KLT_response,
    const unsigned int KLT_response_half_win,
    const unsigned int max_x,
    const unsigned int max_y
    );

template <class FEAT_LIST>
void trackFeatures_checkResponses_impl_simple(
    FEAT_LIST& featureList,
    const CImage& cur_gray,
    const float minimum_KLT_response,
    const unsigned int KLT_response_half_win,
    const unsigned int max_x_,
    const unsigned int max_y_
    );

void trackFeatures_checkResponses< TKeyPointList >(
    TKeyPointList& featureList,
    const CImage& cur_gray,
    const float minimum_KLT_response,
    const unsigned int KLT_response_half_win,
    const unsigned int max_x,
    const unsigned int max_y
    );

void trackFeatures_checkResponses< TKeyPointfList >(
    TKeyPointfList& featureList,
    const CImage& cur_gray,
    const float minimum_KLT_response,
    const unsigned int KLT_response_half_win,
    const unsigned int max_x,
    const unsigned int max_y
    );

template <typename FEATLIST>
void trackFeatures_updatePatch(
    FEATLIST& featureList,
    const CImage& cur_gray
    );

void trackFeatures_updatePatch< CFeatureList >(
    CFeatureList& featureList,
    const CImage& cur_gray
    );

void trackFeatures_updatePatch< TKeyPointList >(
    ] TKeyPointList& featureList,
    ] const CImage& cur_gray
    );

void trackFeatures_updatePatch< TKeyPointfList >(
    ] TKeyPointfList& featureList,
    ] const CImage& cur_gray
    );

template <typename FEATLIST>
void trackFeatures_addNewFeats(
    FEATLIST& featureList,
    const TKeyPointList& new_feats,
    const std::vector<size_t>& sorted_indices,
    const size_t nNewToCheck,
    const size_t maxNumFeatures,
    const float minimum_KLT_response_to_add,
    const double threshold_sqr_dist_to_add_new,
    const size_t patchSize,
    const CImage& cur_gray,
    TFeatureID& max_feat_ID_at_input
    );

void trackFeatures_addNewFeats< CFeatureList >(
    CFeatureList& featureList,
    const TKeyPointList& new_feats,
    const std::vector<size_t>& sorted_indices,
    const size_t nNewToCheck,
    const size_t maxNumFeatures,
    const float minimum_KLT_response_to_add,
    const double threshold_sqr_dist_to_add_new,
    const size_t patchSize,
    const CImage& cur_gray,
    TFeatureID& max_feat_ID_at_input
    );

template <class FEAT_LIST>
void trackFeatures_addNewFeats_simple_list(
    FEAT_LIST& featureList,
    const TKeyPointList& new_feats,
    const std::vector<size_t>& sorted_indices,
    const size_t nNewToCheck,
    const size_t maxNumFeatures,
    const float minimum_KLT_response_to_add,
    const double threshold_sqr_dist_to_add_new,
    ] const size_t patchSize,
    ] const CImage& cur_gray,
    TFeatureID& max_feat_ID_at_input
    );

void trackFeatures_addNewFeats< TKeyPointList >(
    TKeyPointList& featureList,
    const TKeyPointList& new_feats,
    const std::vector<size_t>& sorted_indices,
    const size_t nNewToCheck,
    const size_t maxNumFeatures,
    const float minimum_KLT_response_to_add,
    const double threshold_sqr_dist_to_add_new,
    const size_t patchSize,
    const CImage& cur_gray,
    TFeatureID& max_feat_ID_at_input
    );

void trackFeatures_addNewFeats< TKeyPointfList >(
    TKeyPointfList& featureList,
    const TKeyPointList& new_feats,
    const std::vector<size_t>& sorted_indices,
    const size_t nNewToCheck,
    const size_t maxNumFeatures,
    const float minimum_KLT_response_to_add,
    const double threshold_sqr_dist_to_add_new,
    const size_t patchSize,
    const CImage& cur_gray,
    TFeatureID& max_feat_ID_at_input
    );

template <typename FEATLIST>
size_t trackFeatures_deleteOOB(
    FEATLIST& trackedFeats,
    const size_t img_width,
    const size_t img_height,
    const int MIN_DIST_MARGIN_TO_STOP_TRACKING
    );

template <typename FEATLIST>
size_t trackFeatures_deleteOOB_impl_simple_feat(
    FEATLIST& trackedFeats,
    const size_t img_width,
    const size_t img_height,
    const int MIN_DIST_MARGIN_TO_STOP_TRACKING
    );

size_t trackFeatures_deleteOOB(
    TKeyPointList& trackedFeats,
    const size_t img_width,
    const size_t img_height,
    const int MIN_DIST_MARGIN_TO_STOP_TRACKING
    );

size_t trackFeatures_deleteOOB(
    TKeyPointfList& trackedFeats,
    const size_t img_width,
    const size_t img_height,
    const int MIN_DIST_MARGIN_TO_STOP_TRACKING
    );

size_t trackFeatures_deleteOOB(
    CFeatureList& trackedFeats,
    const size_t img_width,
    const size_t img_height,
    const int MIN_DIST_MARGIN_TO_STOP_TRACKING
    );

} // namespace detail