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

#pragma once
#include "display/mesh/Mesh.hpp"
#include "util/mathutils.hpp"
#include "display/Texture.hpp"
#include "display/mesh/QuadMesh.hpp"
#include "FontMeasure.hpp"

#define FONT_NEWLINE '\n'
#define FONT_SPACE ' '

namespace Dawn {
  class Font {
    public:
      /**
       * Buffer the characters of a string onto a primitive and get the result of the
       * buffer back as a resulting generic measurement information structure. Note
       * that measure is REQUIRED, and must be DISPOSED after it has been calculated.
       * 
       * @param text String to buffer.
       * @param fontSize Font size to use for the buffer operation.
       * @param maxWidth Maximum width (in pixels) to use to textwrap. -1 for no wrap.
       * @param mesh Mesh to buffer the string on to.
       * @param info Pointer to where you want to store resulting measurements.
       */
      virtual void buffer(
        std::string text,
        float_t fontSize,
        float_t maxWidth,
        Mesh *mesh,
        struct FontMeasure *info
      ) = 0;

      /**
       * Fonts need to be initialized before they can actually be used, but I
       * really want to keep things kind-of non-blocking, so for the time being
       * this hack works around it, fonts can decide to return false if they are
       * not "ready for buffering", and the item intending to use the font is
       * required to decide when it should actually request buffering.
       * 
       * @return True if ready for buffering, otherwise false.
       */
      virtual bool_t isReady() = 0;

      /**
       * Returns the texture that is used for a given font.
       * 
       * @return Pointer to the texture used by this font.
       */
      virtual Texture * getTexture() = 0;

      /**
       * Draw a previously buffered font primitive.
       * 
       * @param mesh Mesh to draw.
       * @param start Start character to draw.
       * @param length Count of characters to draw, set to -1 to draw all.
       */
      virtual void draw(Mesh *mesh, int32_t startCharacter, int32_t length) = 0;

      /**
       * Returns the line height of a given font and font size combination.
       * 
       * @param fontSize Font size to get the line height for.
       * @return The line height of this font at this font size.
       */
      virtual float_t getLineHeight(float_t fontSize) = 0;

      /**
       * Retreive the default font size of a given font. Useful if you want to use
       * the original font's font size for pixel-perfect rendering.
       * 
       * @return The font size fo that font item.
       */
      virtual float_t getDefaultFontSize() = 0;
  };
}