#pragma once

#include "IFontEngine.h"
#include "FontGlyph.h"
#include "FontItem.h"

#include <wrl.h>

#include <vector>
#include <unordered_map>

class GlyphOutlineGeometrySink;
class OffScreenTextRenderer;

struct IDWriteFactory;
struct IDWriteTextFormat;
struct IDWriteTextLayout;
struct IDWriteFontFace;
struct IDWriteFontFamily;

class DirectWriteFontEngine : public IFontEngine
{
public:
    void initialize() override;

    void loadFontFace(const std::filesystem::path& fontFile, float penSize = 16) override {};

    void loadFontFaceFromName(const std::string& fontName, float penSize = 16);

    std::unique_ptr<FontGlyph> loadGlyph(uint32_t charCode) override;

    std::unique_ptr<GlyphRunOutlines> getGlyphRunOutlines(const std::vector<uint32_t>& charCodes);

    IDWriteFontFamily* getSystemFontFamily(const std::string& fontName);

    bool loadSystemFontFamily(const std::string& fontName);

    IDWriteFontFace* getDefaultFontFace(const std::string& fontName);

    bool loadDefaultFontFace(const std::string& fontName);

    double getHorizontalAdvance(const FontItem& fontItem, const std::string& content) override;

private:
    void initializeOffScreenRenderer();

    bool mIsValid{ false };

    std::unordered_map<std::string, Microsoft::WRL::ComPtr<IDWriteFontFace> > mDefaultFontFaces;
    std::unordered_map<std::string, Microsoft::WRL::ComPtr<IDWriteFontFamily> > mSystemFontFamilies;

    Microsoft::WRL::ComPtr<IDWriteFactory> mDWriteFactory;
    Microsoft::WRL::ComPtr<IDWriteTextFormat> mTextFormat;
    Microsoft::WRL::ComPtr<IDWriteTextLayout> mTextLayout;
    Microsoft::WRL::ComPtr<OffScreenTextRenderer> mOffScreenRenderer;
};