/*
 * Copyright (c) 2019 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_NEON_CROP_RESIZE_H__
#define __ARM_COMPUTE_NEON_CROP_RESIZE_H__

#include "arm_compute/core/NEON/kernels/NECropKernel.h"
#include "arm_compute/runtime/NEON/functions/NEScale.h"

#include <cstdint>
#include <memory>

namespace arm_compute
{
// Forward Declarations
class ITensor;

/** Function to perform cropping and resizing */
class NECropResize : public IFunction
{
public:
    /** Default constructor */
    NECropResize();
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    NECropResize(const NECropResize &) = delete;
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    NECropResize &operator=(const NECropResize &) = delete;
    /** Allow instances of this class to be moved */
    NECropResize(NECropResize &&) = default;
    /** Allow instances of this class to be moved */
    NECropResize &operator=(NECropResize &&) = default;
    /** Default destructor */
    virtual ~NECropResize() = default;

    /** Configure kernel
     *
     * @note Supported tensor rank: up to 4
     * @note Box indices may be outside of the bounds, in which case @p extrapolation_value is used.
     * @note Start and end indices of boxes are inclusive.
     *
     * @param[in]  input               Source tensor containing N batches of 3D images to be cropped. Data type supported: U16/S16/U32/S32/F16/F32
     * @param[in]  boxes               Tensor containing the boxes used to crop the images. Data type supported: F32
     * @param[in]  box_ind             One dimensional tensor containing the batch index of the 3D image in @p input that the corresponding
     *                                 box in @p boxes will be applied to. Data type supported: F32
     * @param[out] output              Destination tensor containing a cropped and resized image for each box in @p boxes. Data type supported: F32
     * @param[in]  crop_size           The dimensions that each cropped image will be resized to.
     * @param[in]  method              The policy to be used when resizing image. Default is bilinear.
     * @param[in]  extrapolation_value Value to be used for values outside of the image for cropping and resizing. Default is 0.
     */
    void configure(const ITensor *input, const ITensor *boxes, const ITensor *box_ind, ITensor *output, Coordinates2D crop_size,
                   InterpolationPolicy method = InterpolationPolicy::BILINEAR, float extrapolation_value = 0);

    /** Static function to check if given info will lead to a valid configuration of @ref NESlice
     *
     * @note Supported tensor rank: up to 4
     * @note Box indices may be outside of the bounds, in which case @p extrapolation_value is used.
     * @note Start and end indices of boxes are inclusive.
     *
     * @param[in] input               Source tensor containing N batches of 3D images to be cropped. Data type supported: U16/S16/U32/S32/F16/F32
     * @param[in] boxes               Tensor info for the tensor containing the boxes used to crop the images. Data type supported: F32
     * @param[in] box_ind             Tensor info for the one dimensional tensor containing the batch index of the 3D image in @p input
     *                                that the corresponding box in @p boxes will be applied to. Data type supported: F32
     * @param[in] output              Tensor info for the destination tensor containing a cropped and resized image for each box in @p boxes.
     *                                Data type supported: F32
     * @param[in] crop_size           The dimensions that each cropped image will be resized to.
     * @param[in] method              The policy to be used when resizing image. Default is bilinear.
     * @param[in] extrapolation_value Value to be used for values outside of the image for cropping and resizing. Default is 0.
     *
     * @return A status
     */
    static Status validate(const ITensorInfo *input, const ITensorInfo *boxes, const ITensorInfo *box_ind, const ITensorInfo *output,
                           Coordinates2D crop_size, InterpolationPolicy method, float extrapolation_value);

    void run() override;

    ITensor            *_output;
    size_t              _num_boxes;
    InterpolationPolicy _method;
    float               _extrapolation_value;

    std::vector<std::unique_ptr<NECropKernel>> _crop;
    std::vector<std::unique_ptr<NEScale>>      _scale;
    std::vector<std::unique_ptr<Tensor>>       _crop_results;
    std::vector<std::unique_ptr<Tensor>>       _scaled_results;
};
} // namespace arm_compute
#endif /* __ARM_COMPUTE_NEON_CROP_RESIZE_H__ */
