#pragma once
#include <core/fwd.h>
#include <mutex>
struct Spiral
{
    /// Create a new spiral generator for the given size, offset into a larger frame, and block size
    Spiral(Vector2i size, Vector2i offset, size_t block_size);

    /// Return the maximum block size
    size_t max_block_size() const { return m_block_size; }

    /// Return the total number of blocks
    size_t block_count() { return m_block_count; }

    size_t block_counter() { return m_block_counter; }

    Vector2i blocks() { return m_blocks; }

    /// Reset the spiral to its initial state. Does not affect the number of passes.
    void reset();

    /**
     * \brief Return the offset, size and unique identifer of the next block.
     *
     * A size of zero indicates that the spiral traversal is done.
     */
    std::tuple<Vector2i, Vector2i, size_t> next_block();

protected:
    enum class Direction
    {
        Right = 0,
        Down,
        Left,
        Up
    };

    size_t m_block_counter, //< Number of blocks generated so far
        m_block_count,      //< Total number of blocks to be generated
        m_block_size;       //< Size of the (square) blocks (in pixels)

    Vector2i m_size, //< Size of the 2D image (in pixels).
        m_offset,    //< Offset to the crop region on the sensor (pixels).
        m_blocks;    //< Number of blocks in each direction.

    Vector2i m_position; //< Relative position of the current block.
    /// Direction where the spiral is currently headed.
    Direction m_current_direction;
    /// Step counters.
    int m_steps_left, m_steps;
    std::mutex m_mutex;
};