/*
 * Copyright (c) 2016, 2017 ARM Limited.
 *
 * SPDX-License-Identifier: MIT
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#ifndef __ARM_COMPUTE_LKTRACKERKERNEL_H__
#define __ARM_COMPUTE_LKTRACKERKERNEL_H__

#include "arm_compute/core/IArray.h"
#include "arm_compute/core/NEON/INEKernel.h"
#include "arm_compute/core/Types.h"

#include <cstddef>
#include <cstdint>
#include <tuple>
#include <utility>

namespace arm_compute
{
class ITensor;

/** Internal keypoint class for Lucas-Kanade Optical Flow */
struct NELKInternalKeypoint
{
    float x{ 0.f };                 /**< x coordinate of the keypoint */
    float y{ 0.f };                 /**< y coordinate of the keypoint */
    bool  tracking_status{ false }; /**< the tracking status of the keypoint */
};

using INELKInternalKeypointArray = IArray<NELKInternalKeypoint>;

/** Interface for the Lucas-Kanade tracker kernel */
class NELKTrackerKernel : public INEKernel
{
public:
    /** Default constructor */
    NELKTrackerKernel();
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    NELKTrackerKernel(const NELKTrackerKernel &) = delete;
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    NELKTrackerKernel &operator=(const NELKTrackerKernel &) = delete;
    /** Allow instances of this class to be moved */
    NELKTrackerKernel(NELKTrackerKernel &&) = default;
    /** Allow instances of this class to be moved */
    NELKTrackerKernel &operator=(NELKTrackerKernel &&) = default;
    /** Default destructor */
    ~NELKTrackerKernel() = default;

    /** Initialise the kernel input and output
     *
     * @param[in]      input_old            Pointer to the input old tensor. Data type supported: U8
     * @param[in]      input_new            Pointer to the input new tensor. Data type supported. U8
     * @param[in]      old_scharr_gx        Pointer to the input scharr X tensor. Data type supported: S16
     * @param[in]      old_scharr_gy        Pointer to the input scharr Y tensor. Data type supported: S16
     * @param[in]      old_points           Pointer to the IKeyPointArray storing old key points
     * @param[in]      new_points_estimates Pointer to the IKeyPointArray storing new estimates key points
     * @param[out]     new_points           Pointer to the IKeyPointArray storing new key points
     * @param[in, out] old_points_internal  Pointer to the array of NELKInternalKeypoint for old points
     * @param[out]     new_points_internal  Pointer to the array of NELKInternalKeypoint for new points
     * @param[in]      termination          The criteria to terminate the search of each keypoint.
     * @param[in]      use_initial_estimate The flag to indicate whether the initial estimated position should be used
     * @param[in]      epsilon              The error for terminating the algorithm
     * @param[in]      num_iterations       The maximum number of iterations before terminate the algorithm
     * @param[in]      window_dimension     The size of the window on which to perform the algorithm
     * @param[in]      level                The pyramid level
     * @param[in]      num_levels           The number of pyramid levels
     * @param[in]      pyramid_scale        Scale factor used for generating the pyramid
     */
    void configure(const ITensor *input_old, const ITensor *input_new, const ITensor *old_scharr_gx, const ITensor *old_scharr_gy,
                   const IKeyPointArray *old_points, const IKeyPointArray *new_points_estimates, IKeyPointArray *new_points,
                   INELKInternalKeypointArray *old_points_internal, INELKInternalKeypointArray *new_points_internal,
                   Termination termination, bool use_initial_estimate, float epsilon, unsigned int num_iterations, size_t window_dimension,
                   size_t level, size_t num_levels, float pyramid_scale);

    // Inherited methods overridden:
    void run(const Window &window) override;
    BorderSize border_size() const override;

private:
    /** Initialise the array of keypoints in the provide range
     *
     * @param[in] start Index of first element in the keypoints array to be initialised
     * @param[in] end   Index after last elelemnt in the keypoints array to be initialised
     */
    void init_keypoints(int start, int end);
    /** Compute the structure tensor A^T * A based on the scharr gradients I_x and I_y
     *
     * @param[in]  keypoint    Keypoint for which gradients are computed
     * @param[out] bilinear_ix Intermediate interpolated data for X gradient
     * @param[out] bilinear_iy Intermediate interpolated data for Y gradient
     *
     * @return Values A11, A12, A22
     */
    std::tuple<int, int, int> compute_spatial_gradient_matrix(const NELKInternalKeypoint &keypoint, int *bilinear_ix, int *bilinear_iy);
    /** Compute the vector A^T * b, i.e. -sum(I_d * I_t) for d in {x,y}
     *
     * @param[in] old_keypoint Old keypoint for which gradient is computed
     * @param[in] new_keypoint New keypoint for which gradient is computed
     * @param[in] bilinear_ix  Intermediate interpolated data for X gradient
     * @param[in] bilinear_iy  Intermediate interpolated data for Y gradient
     *
     * @return Values b1, b2
     */
    std::pair<int, int> compute_image_mismatch_vector(const NELKInternalKeypoint &old_keypoint, const NELKInternalKeypoint &new_keypoint, const int *bilinear_ix, const int *bilinear_iy);

    const ITensor              *_input_old;
    const ITensor              *_input_new;
    const ITensor              *_old_scharr_gx;
    const ITensor              *_old_scharr_gy;
    IKeyPointArray             *_new_points;
    const IKeyPointArray       *_new_points_estimates;
    const IKeyPointArray       *_old_points;
    INELKInternalKeypointArray *_old_points_internal;
    INELKInternalKeypointArray *_new_points_internal;
    Termination                 _termination;
    bool                        _use_initial_estimate;
    float                       _pyramid_scale;
    float                       _epsilon;
    unsigned int                _num_iterations;
    int                         _window_dimension;
    unsigned int                _level;
    unsigned int                _num_levels;
    ValidRegion                 _valid_region;
};
}
#endif /*__ARM_COMPUTE_NELKTRACKERKERNEL_H__ */
