/*
 * Copyright (c) 2016-2020 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_CLGAUSSIAN5X5_H
#define ARM_COMPUTE_CLGAUSSIAN5X5_H

#include "arm_compute/core/Types.h"
#include "arm_compute/runtime/CL/CLTensor.h"
#include "arm_compute/runtime/IFunction.h"
#include "arm_compute/runtime/IMemoryManager.h"
#include "arm_compute/runtime/MemoryGroup.h"

#include <cstdint>
#include <memory>

namespace arm_compute
{
class CLCompileContext;
class CLFillBorderKernel;
class CLGaussian5x5HorKernel;
class CLGaussian5x5VertKernel;
class ICLTensor;

/** Basic function to execute gaussian filter 5x5. This function calls the following OpenCL kernels:
 *
 * -# @ref CLFillBorderKernel (executed if border_mode == CONSTANT or border_mode == REPLICATE)
 * -# @ref CLGaussian5x5HorKernel
 * -# @ref CLGaussian5x5VertKernel
 *
 * @deprecated This function is deprecated and is intended to be removed in 21.05 release
 *
 */
class CLGaussian5x5 : public IFunction
{
public:
    /** Default Constructor.
     *
     * @param[in] memory_manager (Optional) Memory manager.
     */
    CLGaussian5x5(std::shared_ptr<IMemoryManager> memory_manager = nullptr);
    /** Prevent instances of this class from being copied */
    CLGaussian5x5(const CLGaussian5x5 &) = delete;
    /** Default move constructor */
    CLGaussian5x5(CLGaussian5x5 &&) = default;
    /** Prevent instances of this class from being copied */
    CLGaussian5x5 &operator=(const CLGaussian5x5 &) = delete;
    /** Default move assignment operator */
    CLGaussian5x5 &operator=(CLGaussian5x5 &&) = default;
    /** Default destructor */
    ~CLGaussian5x5();
    /** Initialise the function's source, destinations and border mode.
     *
     * @param[in,out] input                 Source tensor. Data types supported: U8. (Written to only for @p border_mode != UNDEFINED)
     * @param[out]    output                Destination tensor, Data types supported: U8.
     * @param[in]     border_mode           Border mode to use for the convolution.
     * @param[in]     constant_border_value (Optional) Constant value to use for borders if border_mode is set to CONSTANT.
     */
    void configure(ICLTensor *input, ICLTensor *output, BorderMode border_mode, uint8_t constant_border_value = 0);
    /** Initialise the function's source, destinations and border mode.
     *
     * @param[in]     compile_context       The compile context to be used.
     * @param[in,out] input                 Source tensor. Data types supported: U8. (Written to only for @p border_mode != UNDEFINED)
     * @param[out]    output                Destination tensor, Data types supported: U8.
     * @param[in]     border_mode           Border mode to use for the convolution.
     * @param[in]     constant_border_value (Optional) Constant value to use for borders if border_mode is set to CONSTANT.
     */
    void configure(const CLCompileContext &compile_context, ICLTensor *input, ICLTensor *output, BorderMode border_mode, uint8_t constant_border_value = 0);

    // Inherited methods overridden:
    void run() override;

protected:
    MemoryGroup                              _memory_group;   /**< Function's memory group */
    std::unique_ptr<CLGaussian5x5HorKernel>  _kernel_hor;     /**< Horizontal pass kernel */
    std::unique_ptr<CLGaussian5x5VertKernel> _kernel_vert;    /**< Vertical pass kernel */
    std::unique_ptr<CLFillBorderKernel>      _border_handler; /**< Kernel to handle image borders */
    CLImage                                  _tmp;            /**< Temporary buffer */
};
}
#endif /*ARM_COMPUTE_CLGAUSSIAN5X5_H */
