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

#pragma once
#include "scene/SceneItemComponent.hpp"
#include "display/RenderTarget.hpp"
#include "scene/components/display/Camera.hpp"
#include "display/shader/shaders/UIShader.hpp"

namespace Dawn {
  class UIComponentDimensional {
    public:
      /**
       * Returns the width of this dimensional UI item.
       * 
       * @return Width of this item.
       */
      virtual float_t getWidth() = 0;

      /**
       * Returns the height of this dimensional UI item.
       * 
       * @return Height of this item.
       */
      virtual float_t getHeight() = 0;

      /**
       * Returns the content width of this dimensional UI item.
       * 
       * @return Content width of this item.
       */
      virtual float_t getContentWidth() = 0;
      
      /**
       * Returns the content height of this dimensional UI item.
       * 
       * @return Content height of this item.
       */
      virtual float_t getContentHeight() = 0;
      
      /**
       * Returns the offset of the child elements of this UI item.
       * 
       * @return Offset of the child elements of this UI item.
       */
      virtual float_t getChildOffsetX() = 0;

      /**
       * Returns the offset of the child elements of this UI item.
       * 
       * @return Offset of the child elements of this UI item.
       */
      virtual float_t getChildOffsetY() = 0;
  };

  enum UIDrawType {
    UI_DRAW_TYPE_WORLD_ABSOLUTE,
    UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE,
    // UI_DRAW_TYPE_CAMERA_OVERLAY
  };

  class UICanvas : public SceneItemComponent, public UIComponentDimensional {
    private:
      std::function<void()> evtRenderResize;
      float_t w = 1;
      float_t h = 1;

      /**
       * Rebuffers all of the necessary shader buffer data for this canvas to 
       * the GPU.
       */
      void rebufferShaderParameters();

    public:
      UICanvasShaderBuffer shaderBuffer;

      /**
       * Creates a UI Canvas Scene Item Element, and attaches it to the provided
       * scene.
       * 
       * @param scene Scene to create the UI Canvas for.
       * @return Created UI Canvas.
       */
      static UICanvas * create(Scene *scene);

      //======================================================================//
      StateProperty<Camera*> camera;
      enum UIDrawType drawType = UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE;

      /**
       * Constructs the UI Canvas Scene Item Component.
       * 
       * @param item Item that this canvas item belongs to.
       */
      UICanvas(SceneItem *item);

      /**
       * Returns the scale of this canvas.
       * 
       * @return The scale of the canvas, where 1 is default scaling.
       */
      float_t getScale();

      float_t getWidth() override;
      float_t getHeight() override;
      float_t getContentWidth() override;
      float_t getContentHeight() override;
      float_t getChildOffsetX() override;
      float_t getChildOffsetY() override;
      void onStart() override;
      void onDispose() override;
  };
}