/******************************************************************************
*	File		-	grid.h
*	Author		-	Joey Pollack
*	Date		-	2022/01/25 (y/m/d)
*	Mod Date	-	2022/01/25 (y/m/d)
*	Description	-	A 2D fixed-size array of data. Size must be set when
*                   this container is created and can not be changed later.
*                   The 0, 0 position is the center of the grid (so the indices
*                   of a 10x10 grid go from 4, 4 to -4, -4).
******************************************************************************/

#ifndef GRID_H_
#define GRID_H_

#include <core/types.h>

namespace lunarium
{
    template<typename T>
    class Grid
    {
    public:
        Grid(Sizei size);

        T* operator[](Vec2i at);
        T GetAt(Vec2i at);
        void SetAt(Vec2i at, T value);

        void SetAll(T value);

    private:

        struct Node
        {
            T Data;
        };

        Sizei mHalfSize;
        Sizei mSize;
        Node** mGrid;
    };  


////////////////////////////////////////////////////////////
//				IMPLEMENTATION
////////////////////////////////////////////////////////////

    template<typename T>
    Grid<T>::Grid(Sizei size)
        : mSize(size)
    {
        mHalfSize.Width = size.Width / 2;
        mHalfSize.Height = size.Height / 2;

        mGrid = new Node*[size.Width];
        for (int i = 0; i < size.Width; i++)
        {
            mGrid[i] = new Node[size.Height];
        }
    }

    template<typename T>
    T* Grid<T>::operator[](Vec2i at)
    {
        return &mGrid[at.X + mHalfSize.Width][at.Y + mHalfSize.Height].Data;
    }

    template<typename T>
    T Grid<T>::GetAt(Vec2i at)
    {
        return mGrid[at.X + mHalfSize.Width][at.Y + mHalfSize.Height].Data;
    }

    template<typename T>
    void Grid<T>::SetAt(Vec2i at, T value)
    {
        mGrid[at.X + mHalfSize.Width][at.Y + mHalfSize.Height].Data = value;
    }

    template<typename T>
    void Grid<T>::SetAll(T value)
    {
        for (int i = 0; i < mSize.Width; i++)
        {
            for (int j = 0; j < mSize.Height; j++)
            {
                mGrid[i][j].Data = value;
            }
        }
    }
}
#endif // GRID_H_