/*
 * 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_WINDOW_H
#define ARM_COMPUTE_WINDOW_H

#include <algorithm>
#include <array>
#include <cstddef>

#include "arm_compute/core/Coordinates.h"
#include "arm_compute/core/Error.h"
#include "arm_compute/core/ITensorInfo.h"
#include "arm_compute/core/Utils.h"

namespace arm_compute
{
/** Describe a multidimensional execution window. */
class Window
{
public:
    /** Alias for dimension 0 also known as X dimension */
    static constexpr size_t DimX = 0;
    /** Alias for dimension 1 also known as Y dimension */
    static constexpr size_t DimY = 1;
    /** Alias for dimension 2 also known as Z dimension */
    static constexpr size_t DimZ = 2;

    /** Default constructor: create a window containing a single element. */
    constexpr Window()
        : _dims(), _is_broadcasted(utility::generate_array<bool, Coordinates::num_max_dimensions, false>::value)
    {
    }
    /** Copy constructor
     *
     * @param[in] src Copy the values from src to a new object
     */
    Window(const Window &src);
    /** Copy assignment operator
     *
     * @param[in] rhs Copy the values from rhs to the current object
     *
     * @return Reference to the updated object
     */
    Window &operator=(const Window &rhs);

    /** Describe one of the image's dimensions with a start, end and step.
     *
     * Iteration through the elements of the dimension is done like this:
     * for(int v = start(); v < end(); v += step())
     * {
     *   ...
     * }
     */
    class Dimension
    {
    public:
        /** Constructor, by default creates a dimension of 1.
         *
         * @param[in] start Start of the dimension
         * @param[in] end   End of the dimension
         * @param[in] step  Step between two elements of the dimension when iterating.
         *
         */
        constexpr Dimension(int start = 0, int end = 1, int step = 1)
            : _start(start), _end(end), _step(step)
        {
        }
        /** Default assignment operator to allow dimensions to be copied */
        Dimension &operator=(const Dimension &d) = default;
        /** Return the start of the dimension */
        constexpr int start() const
        {
            return _start;
        }
        /** Return the end of the dimension */
        constexpr int end() const
        {
            return _end;
        }
        /** Return the step of the dimension */
        constexpr int step() const
        {
            return _step;
        }
        /** Set the dimension's step
         *
         * @param[in] step The new step
         */
        void set_step(int step)
        {
            _step = step;
        }
        /** Set the dimension's end
         *
         * @param[in] end The new end
         */
        void set_end(int end)
        {
            _end = end;
        }

    private:
        int _start; /**< Start of the dimension */
        int _end;   /**< End of the dimension */
        int _step;
    };

    /** Read only access to a given dimension of the window
     *
     * @note Precondition: dimension < Coordinates::num_max_dimensions
     *
     * @param[in] dimension The dimension to access
     *
     * @return The requested dimension
     */
    constexpr const Dimension &operator[](size_t dimension) const;

    /** Alias to access the first dimension of the window
     *
     * @return First dimension of the window
     */
    constexpr const Dimension &x() const
    {
        return _dims.at(Window::DimX);
    }

    /** Alias to access the second dimension of the window
     *
     * @return Second dimension of the window
     */
    constexpr const Dimension &y() const
    {
        return _dims.at(Window::DimY);
    }

    /** Alias to access the third dimension of the window
     *
     * @return Third dimension of the window
     */
    constexpr const Dimension &z() const
    {
        return _dims.at(Window::DimZ);
    }

    /** Set the values of a given dimension
     *
     * @param[in] dimension The dimension to set
     * @param[in] dim       The values to set the dimension to
     */
    void set(size_t dimension, const Dimension &dim);

    /** Set the dimension as broadcasted dimension
     *
     * @param[in] dimension The dimension to set
     */
    void set_broadcasted(size_t dimension);

    /** Return whether a dimension has been broadcasted
     *
     * @param[in] dimension The requested dimension
     *
     * @return true if the dimension has been broadcasted
     */
    bool is_broadcasted(size_t dimension) const;

    /** Use the tensor's dimensions to fill the window dimensions.
     *
     * @param[in] shape           @ref TensorShape to copy the dimensions from.
     * @param[in] first_dimension Only copy dimensions which are greater or equal to this value.
     */
    void use_tensor_dimensions(const TensorShape &shape, size_t first_dimension = Window::DimX);

    /** Shift the values of a given dimension by the given shift_value
     *
     * @param[in] dimension   The dimension to shift
     * @param[in] shift_value Value to shift the start and end values of.
     */
    void shift(size_t dimension, int shift_value);

    /** Shift down all the dimensions of a window
     *
     * i.e new_dims[n] = old_dims[n+shift_value].
     *
     * @param[in] shift_value Number of dimensions to shift the window by.
     *
     * @return The window with the shifted dimensions.
     */
    Window shift_dimensions(unsigned int shift_value) const;

    /** Adjust the start or end of a given dimension by the given value
     *
     * @param[in] dimension    The dimension to adjust
     * @param[in] adjust_value The adjusted value.
     * @param[in] is_at_start  The flag to indicate whether adjust the start or end of the dimension.
     */
    void adjust(size_t dimension, int adjust_value, bool is_at_start);

    /** Scale the values of a given dimension by the given scale_value
     *
     * @note The end of the window is rounded up to be a multiple of step after the scaling.
     *
     * @param[in] dimension   The dimension to scale
     * @param[in] scale_value Value to scale the start, end and step values of.
     */
    void scale(size_t dimension, float scale_value);

    /** Set the step of a given dimension.
     *
     * @param[in] dimension Dimension to update
     * @param[in] step      The new dimension's step value
     */
    void set_dimension_step(size_t dimension, int step);

    /** Will validate all the window's dimensions' values when asserts are enabled
     *
     * No-op when asserts are disabled
     */
    void validate() const;

    /** Return the number of iterations needed to iterate through a given dimension
     *
     * @param[in] dimension The requested dimension
     *
     * @return The number of iterations
     */
    constexpr size_t num_iterations(size_t dimension) const;
    /** Return the total number of iterations needed to iterate through the entire window
     *
     * @return Number of total iterations
     */
    size_t num_iterations_total() const;
    /** Return the shape of the window in number of steps */
    TensorShape shape() const;
    /** Split a window into a set of sub windows along a given dimension
     *
     * For example to split a window into 3 sub-windows along the Y axis, you would have to do:<br/>
     * Window sub0 = window.split_window( 1, 0, 3);<br/>
     * Window sub1 = window.split_window( 1, 1, 3);<br/>
     * Window sub2 = window.split_window( 1, 2, 3);<br/>
     *
     * @param[in] dimension Dimension along which the split will be performed
     * @param[in] id        Id of the sub-window to return. Must be in the range (0, total-1)
     * @param[in] total     Total number of sub-windows the window will be split into.
     *
     * @return The subwindow "id" out of "total"
     */
    Window split_window(size_t dimension, size_t id, size_t total) const;
    /** First 1D slice of the window
     *
     * @return The first slice of the window.
     */
    Window first_slice_window_1D() const
    {
        return first_slice_window<1>();
    };
    /** First 2D slice of the window
     *
     * @return The first slice of the window.
     */
    Window first_slice_window_2D() const
    {
        return first_slice_window<2>();
    };
    /** First 3D slice of the window
     *
     * @return The first slice of the window.
     */
    Window first_slice_window_3D() const
    {
        return first_slice_window<3>();
    };
    /** First 4D slice of the window
     *
     * @return The first slice of the window.
     */
    Window first_slice_window_4D() const
    {
        return first_slice_window<4>();
    };
    /** Slide the passed 1D window slice.
     *
     * If slice contains the last slice then it will remain unchanged and false will be returned.
     *
     * @param[in,out] slice Current slice, to be updated to the next slice.
     *
     * @return true if slice contains a new slice, false if slice already contained the last slice
     */
    bool slide_window_slice_1D(Window &slice) const
    {
        return slide_window_slice<1>(slice);
    }
    /** Slide the passed 2D window slice.
     *
     * If slice contains the last slice then it will remain unchanged and false will be returned.
     *
     * @param[in,out] slice Current slice, to be updated to the next slice.
     *
     * @return true if slice contains a new slice, false if slice already contained the last slice
     */
    bool slide_window_slice_2D(Window &slice) const
    {
        return slide_window_slice<2>(slice);
    }
    /** Slide the passed 3D window slice.
     *
     * If slice contains the last slice then it will remain unchanged and false will be returned.
     *
     * @param[in,out] slice Current slice, to be updated to the next slice.
     *
     * @return true if slice contains a new slice, false if slice already contained the last slice
     */
    bool slide_window_slice_3D(Window &slice) const
    {
        return slide_window_slice<3>(slice);
    }
    /** Slide the passed 4D window slice.
     *
     * If slice contains the last slice then it will remain unchanged and false will be returned.
     *
     * @param[in,out] slice Current slice, to be updated to the next slice.
     *
     * @return true if slice contains a new slice, false if slice already contained the last slice
     */
    bool slide_window_slice_4D(Window &slice) const
    {
        return slide_window_slice<4>(slice);
    }

    /** Collapse the dimensions between @p first and @p last if possible.
     *
     * A dimension is collapsable if it starts from 0 and matches the corresponding dimension in the full_window
     *
     * @param[in]  full_window   Full window @p window has been created from.
     * @param[in]  first         Start dimension into which the following are collapsed.
     * @param[in]  last          End (exclusive) dimension to collapse.
     * @param[out] has_collapsed (Optional) Whether the window was collapsed.
     *
     * @return Collapsed window.
     */
    Window collapse_if_possible(const Window &full_window, size_t first, size_t last, bool *has_collapsed = nullptr) const;

    /** Collapse the dimensions higher than @p first if possible.
     *
     * A dimension is collapsable if it starts from 0 and matches the corresponding dimension in the full_window
     *
     * @param[in]  full_window   Full window @p window has been created from.
     * @param[in]  first         Start dimension into which the following are collapsed.
     * @param[out] has_collapsed (Optional) Whether the window was collapsed.
     *
     * @return Collapsed window.
     */
    Window collapse_if_possible(const Window &full_window, size_t first, bool *has_collapsed = nullptr) const
    {
        return collapse_if_possible(full_window, first, Coordinates::num_max_dimensions, has_collapsed);
    }

    /** Collapse the dimensions between @p first and @p last.
     *
     * A dimension is collapsable if it starts from 0 and matches the corresponding dimension in the full_window
     *
     * @param[in] full_window Full window @p window has been created from.
     * @param[in] first       Start dimension into which the following are collapsed.
     * @param[in] last        End (exclusive) dimension to collapse.
     *
     * @return Collapsed window if successful.
     */
    Window collapse(const Window &full_window, size_t first, size_t last = Coordinates::num_max_dimensions) const;

    /** Don't advance in the dimension where @p shape is less equal to 1.
     *
     * @param[in] shape A TensorShape.
     *
     * @return Broadcast window.
     */
    Window broadcast_if_dimension_le_one(const TensorShape &shape) const;

    /** Don't advance in the dimension where shape of @p info is less equal to 1.
     *
     * @param[in] info An ITensorInfo.
     *
     * @return Broadcast window.
     */
    Window broadcast_if_dimension_le_one(const ITensorInfo &info) const
    {
        return broadcast_if_dimension_le_one(info.tensor_shape());
    }
    /** Friend function that swaps the contents of two windows
     *
     * @param[in] lhs First window to swap.
     * @param[in] rhs Second window to swap.
     */
    friend void swap(Window &lhs, Window &rhs);

private:
    /** First slice of the window
     *
     * @return The first slice of the window.
     */
    template <unsigned int window_dimension>
    Window                 first_slice_window() const;

    /** Slide the passed window slice.
     *
     * If slice contains the last slice then it will remain unchanged and false will be returned.
     *
     * @param[in,out] slice Current slice, to be updated to the next slice.
     *
     * @return true if slice contains a new slice, false if slice already contained the last slice
     */
    template <unsigned int window_dimension>
    bool slide_window_slice(Window &slice) const;

private:
    std::array<Dimension, Coordinates::num_max_dimensions> _dims;
    std::array<bool, Coordinates::num_max_dimensions>      _is_broadcasted;
};
} // namespace arm_compute
#include "Window.inl"
#endif /*ARM_COMPUTE_WINDOW_H */
