// Copyright (c) 2022 Dominic Masters
// 
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT

#pragma once
#include "UIComponent.hpp"
#include "util/mathutils.hpp"

namespace Dawn {
  struct UIGridPosition {
    int32_t x;
    int32_t y;
    enum UIComponentAlign alignX;
    enum UIComponentAlign alignY;
  };


  class UIGrid : public UIComponent {
    private:
      int32_t rows = 1;
      int32_t columns = 1;
      float_t gutterX = 0;
      float_t gutterY = 0;
      float_t sizeRow, sizeCol;
      std::map<UIComponent*, struct UIGridPosition> gridChildren;
      bool_t alignmentListenerLocked = false;

      /**
       * Internal method to update the alignment of a child.
       * 
       * @param child Child UI component.
       * @param pos Positional information of the child UI item..
       */
      void alignChild(UIComponent *child, struct UIGridPosition pos);

      void onChildAligned(UIComponent *child);

    protected:
      void updatePositions() override;
      std::vector<struct ShaderPassItem> getSelfPassItems(
        glm::mat4 projection,
        glm::mat4 view,
        glm::mat4 transform
      ) override;

    public:
      UIGrid(UICanvas *canvas);

      /**
       * Sets the dimensions of the grid.
       * 
       * @param columns Count of columns in the grid.
       * @param rows Count of rows in the grid.
       * @param gutterX Gutter spacing between the cells of the grid.
       * @param gutterY Gutter spacing between the cells of the grid.
       */
      void setGridSize(
        int32_t columns, int32_t rows, 
        float_t gutterX, float_t gutterY
      );

      /**
       * Adds a UI component to the grid.
       * 
       * @param component Component to add to the grid.
       * @param column Column Position.
       * @param row Row Position.
       * @param alignX X alignment of the component within the cell.
       * @param alignY Y alignment of the component within the cell.
       */
      void addToGrid(
        UIComponent *ui,
        int32_t x, int32_t y,
        enum UIComponentAlign alignX, enum UIComponentAlign alignY
      );

      int32_t getRows();
      int32_t getColumns();

      void removeChild(UIComponent *component) override;
  };
}