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

#pragma once
#include "Font.hpp"

namespace Dawn {
  /** Which character (ASCII) to start the font from */
  #define TRUETYPE_FIRST_CHAR 32

  /** How many characters (after the first char) to generate */
  #define TRUETYPE_NUM_CHARS 96

  /** Refer to STBTT docs for OpenGL Fill Mode v d3d Fill Modes */
  #define TRUETYPE_FILL_MODE 0

  typedef stbtt_bakedchar truetypechar_t;
  typedef stbtt_aligned_quad truetypequad_t;

  class TrueTypeFont : public Font {
    protected:
      /**
       * Calculate the quad information for a given character.
       * 
       * @param font Font to get the character from.
       * @param quad Pointer to the quad to store the quad information in.
       * @param x Pointer to the X position for the quad.
       * @param y Pointer to the Y position for the quad.
       * @param c Character to get the quad and position information for.
       */
      void bakeQuad(truetypequad_t *quad, float_t *x, float_t *y, char c);
      
      /**
       * Returns the font scale to use for rendering your desired font size at a 
       * font size that is different than the precompiled font size for this
       * true type font. For example, let's say you render your font size at 36
       * when you are precompiling it, but rather than creating a new font just
       * to add a size  24, you can instead use this method to get the scale to
       * use to downscale your font to match.
       * 
       * @param font TrueType font to get the scale of.
       * @param fontSize Font size you desire.
       * @return The scale used to get the font size that will match.
       */
      float_t getScale(float_t fontSize);

      /**
       * Returns the size of a space character for a given font.
       * 
       * @param fontSize Font size of the font to get the space size for.
       * @return The size of the space character.
       */
      float_t getSpaceSize(float_t fontSize);
            
      /**
       * Returns the initial line height of a font.
       * 
       * @param fontSize Font size for the font to get the line height of.
       * @return The line height initial value.
       */
      float_t getInitialLineHeight(float_t fontSize);

    public:
      Texture texture;
      int32_t fontSize;
      truetypechar_t characterData[TRUETYPE_NUM_CHARS];

      void buffer(
        std::string text,
        float_t fontSize,
        float_t maxWidth,
        Mesh *mesh,
        struct FontMeasure *info
      ) override;
      bool_t isReady() override;
      Texture * getTexture()  override;
      void draw(Mesh *mesh, int32_t startCharacter, int32_t length) override;
      float_t getLineHeight(float_t fontSize) override;
      float_t getDefaultFontSize() override;
  };
}