/*
 * Copyright (c) 2016-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_CLARRAY_H
#define ARM_COMPUTE_CLARRAY_H

#include "arm_compute/core/CL/ICLArray.h"
#include "arm_compute/core/CL/OpenCL.h"
#include "arm_compute/core/Error.h"
#include "arm_compute/core/Types.h"
#include "arm_compute/runtime/CL/CLScheduler.h"

namespace arm_compute
{
/** CLArray implementation  */
template <class T>
class CLArray : public ICLArray<T>
{
public:
    /** Default constructor: empty array */
    CLArray()
        : ICLArray<T>(0), _buffer()
    {
    }
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    CLArray(const CLArray &) = delete;
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    CLArray &operator=(const CLArray &) = delete;
    /** Allow instances of this class to be move constructed */
    CLArray(CLArray &&) = default;
    /** Allow instances of this class to be moved */
    CLArray &operator=(CLArray &&) = default;
    /** Constructor: initializes an array which can contain up to max_num_points values
     *
     * @param[in] max_num_values Maximum number of values the array will be able to stored
     */
    CLArray(size_t max_num_values)
        : ICLArray<T>(max_num_values), _buffer(CLScheduler::get().context(), CL_MEM_ALLOC_HOST_PTR | CL_MEM_READ_WRITE, max_num_values * sizeof(T))
    {
    }
    /** Enqueue a map operation of the allocated buffer.
     *
     * @param[in] blocking If true, then the mapping will be ready to use by the time
     *                     this method returns, else it is the caller's responsibility
     *                     to flush the queue and wait for the mapping operation to have completed.
     */
    void map(bool blocking = true)
    {
        ICLArray<T>::map(CLScheduler::get().queue(), blocking);
    }
    using ICLArray<T>::map;
    /** Enqueue an unmap operation of the allocated and mapped buffer.
     *
     * @note This method simply enqueues the unmap operation, it is the caller's responsibility to flush the queue and make sure the unmap is finished before
     *       the memory is accessed by the device.
     */
    void unmap()
    {
        ICLArray<T>::unmap(CLScheduler::get().queue());
    }
    using ICLArray<T>::unmap;

    // Inherited methods overridden:
    const cl::Buffer &cl_buffer() const override
    {
        return _buffer;
    }

protected:
    // Inherited methods overridden:
    uint8_t *do_map(cl::CommandQueue &q, bool blocking) override
    {
        ARM_COMPUTE_ERROR_ON(nullptr == _buffer.get());
        return static_cast<uint8_t *>(q.enqueueMapBuffer(_buffer, blocking ? CL_TRUE : CL_FALSE, CL_MAP_READ | CL_MAP_WRITE, 0, this->max_num_values() * sizeof(T)));
    }
    void do_unmap(cl::CommandQueue &q, uint8_t *mapping) override
    {
        ARM_COMPUTE_ERROR_ON(nullptr == _buffer.get());
        q.enqueueUnmapMemObject(_buffer, mapping);
    }

private:
    cl::Buffer _buffer;
};

/** OpenCL Array of Key Points. */
using CLKeyPointArray = CLArray<KeyPoint>;
/** OpenCL Array of 2D Coordinates. */
using CLCoordinates2DArray = CLArray<Coordinates2D>;
/** OpenCL Array of Detection Windows. */
using CLDetectionWindowArray = CLArray<DetectionWindow>;
/** OpenCL Array of 2D Sizes. */
using CLSize2DArray = CLArray<Size2D>;
/** OpenCL Array of uint8s. */
using CLUInt8Array = CLArray<cl_uchar>;
/** OpenCL Array of uint16s. */
using CLUInt16Array = CLArray<cl_ushort>;
/** OpenCL Array of uint32s. */
using CLUInt32Array = CLArray<cl_uint>;
/** OpenCL Array of int16s. */
using CLInt16Array = CLArray<cl_short>;
/** OpenCL Array of int32s. */
using CLInt32Array = CLArray<cl_int>;
/** OpenCL Array of floats. */
using CLFloatArray = CLArray<cl_float>;
}
#endif /* ARM_COMPUTE_CLARRAY_H */
