/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SkTypes.h"
#if defined(SK_BUILD_FOR_WIN)

#include "SkDWrite.h"
#include "SkDWriteFontFileStream.h"
#include "SkHRESULT.h"
#include "SkMutex.h"
#include "SkRemotableFontMgr.h"
#include "SkStream.h"
#include "SkString.h"
#include "SkTArray.h"
#include "SkTScopedComPtr.h"
#include "SkTypeface_win_dw.h"
#include "SkTypes.h"
#include "SkUtils.h"

#include <dwrite.h>

class SK_API SkRemotableFontMgr_DirectWrite : public SkRemotableFontMgr {
private:
    struct DataId {
        IUnknown* fLoader;  // In COM only IUnknown pointers may be safely used for identity.
        void* fKey;
        UINT32 fKeySize;

        DataId() { }

        DataId(DataId&& that) : fLoader(that.fLoader), fKey(that.fKey), fKeySize(that.fKeySize) {
            that.fLoader = nullptr;
            that.fKey = nullptr;
            SkDEBUGCODE(that.fKeySize = 0xFFFFFFFF;)
        }

        ~DataId() {
            if (fLoader) {
                fLoader->Release();
            }
            sk_free(fKey);
        }
    };

    mutable SkTArray<DataId> fDataIdCache;
    mutable SkMutex fDataIdCacheMutex;

    int FindOrAdd(IDWriteFontFileLoader* fontFileLoader,
                  const void* refKey, UINT32 refKeySize) const
    {
        SkTScopedComPtr<IUnknown> fontFileLoaderId;
        HR_GENERAL(fontFileLoader->QueryInterface(&fontFileLoaderId),
                   "Failed to re-convert to IDWriteFontFileLoader.",
                   SkFontIdentity::kInvalidDataId);

        SkAutoMutexAcquire ama(fDataIdCacheMutex);
        int count = fDataIdCache.count();
        int i;
        for (i = 0; i < count; ++i) {
            const DataId& current = fDataIdCache[i];
            if (fontFileLoaderId.get() == current.fLoader &&
                refKeySize == current.fKeySize &&
                0 == memcmp(refKey, current.fKey, refKeySize))
            {
                return i;
            }
        }
        DataId& added = fDataIdCache.push_back();
        added.fLoader = fontFileLoaderId.release();  // Ref is passed.
        added.fKey = sk_malloc_throw(refKeySize);
        memcpy(added.fKey, refKey, refKeySize);
        added.fKeySize = refKeySize;

        return i;
    }

public:


    /** localeNameLength must include the null terminator. */
    SkRemotableFontMgr_DirectWrite(IDWriteFontCollection* fontCollection,
                                   WCHAR* localeName, int localeNameLength)
        : fFontCollection(SkRefComPtr(fontCollection))
        , fLocaleName(localeNameLength)
    {
        memcpy(fLocaleName.get(), localeName, localeNameLength * sizeof(WCHAR));
    }

    HRESULT FontToIdentity(IDWriteFont* font, SkFontIdentity* fontId) const {
        SkTScopedComPtr<IDWriteFontFace> fontFace;
        HRM(font->CreateFontFace(&fontFace), "Could not create font face.");

        UINT32 numFiles;
        HR(fontFace->GetFiles(&numFiles, nullptr));
        if (numFiles > 1) {
            return E_FAIL;
        }

        // data id
        SkTScopedComPtr<IDWriteFontFile> fontFile;
        HR(fontFace->GetFiles(&numFiles, &fontFile));

        SkTScopedComPtr<IDWriteFontFileLoader> fontFileLoader;
        HR(fontFile->GetLoader(&fontFileLoader));

        const void* refKey;
        UINT32 refKeySize;
        HR(fontFile->GetReferenceKey(&refKey, &refKeySize));

        fontId->fDataId = FindOrAdd(fontFileLoader.get(), refKey, refKeySize);

        // index
        fontId->fTtcIndex = fontFace->GetIndex();

        // style
        fontId->fFontStyle = get_style(font);
        return S_OK;
    }

    SkRemotableFontIdentitySet* getIndex(int familyIndex) const override {
        SkTScopedComPtr<IDWriteFontFamily> fontFamily;
        HRNM(fFontCollection->GetFontFamily(familyIndex, &fontFamily),
             "Could not get requested family.");

        int count = fontFamily->GetFontCount();
        SkFontIdentity* fontIds;
        sk_sp<SkRemotableFontIdentitySet> fontIdSet(
            new SkRemotableFontIdentitySet(count, &fontIds));
        for (int fontIndex = 0; fontIndex < count; ++fontIndex) {
            SkTScopedComPtr<IDWriteFont> font;
            HRNM(fontFamily->GetFont(fontIndex, &font), "Could not get font.");

            HRN(FontToIdentity(font.get(), &fontIds[fontIndex]));
        }
        return fontIdSet.release();
    }

    virtual SkFontIdentity matchIndexStyle(int familyIndex,
                                           const SkFontStyle& pattern) const override
    {
        SkFontIdentity identity = { SkFontIdentity::kInvalidDataId };

        SkTScopedComPtr<IDWriteFontFamily> fontFamily;
        HR_GENERAL(fFontCollection->GetFontFamily(familyIndex, &fontFamily),
                   "Could not get requested family.",
                   identity);

        const DWriteStyle dwStyle(pattern);
        SkTScopedComPtr<IDWriteFont> font;
        HR_GENERAL(fontFamily->GetFirstMatchingFont(dwStyle.fWeight, dwStyle.fWidth,
                                                    dwStyle.fSlant, &font),
                   "Could not match font in family.",
                   identity);

        HR_GENERAL(FontToIdentity(font.get(), &identity), nullptr, identity);

        return identity;
    }

    static HRESULT getDefaultFontFamilyName(SkSMallocWCHAR* name) {
        NONCLIENTMETRICSW metrics;
        metrics.cbSize = sizeof(metrics);
        if (0 == SystemParametersInfoW(SPI_GETNONCLIENTMETRICS,
                                       sizeof(metrics),
                                       &metrics,
                                       0)) {
            return E_UNEXPECTED;
        }

        size_t len = wcsnlen_s(metrics.lfMessageFont.lfFaceName, LF_FACESIZE) + 1;
        if (0 != wcsncpy_s(name->reset(len), len, metrics.lfMessageFont.lfFaceName, _TRUNCATE)) {
            return E_UNEXPECTED;
        }

        return S_OK;
    }

    SkRemotableFontIdentitySet* matchName(const char familyName[]) const override {
        SkSMallocWCHAR dwFamilyName;
        if (nullptr == familyName) {
            HR_GENERAL(getDefaultFontFamilyName(&dwFamilyName),
                       nullptr, SkRemotableFontIdentitySet::NewEmpty());
        } else {
            HR_GENERAL(sk_cstring_to_wchar(familyName, &dwFamilyName),
                       nullptr, SkRemotableFontIdentitySet::NewEmpty());
        }

        UINT32 index;
        BOOL exists;
        HR_GENERAL(fFontCollection->FindFamilyName(dwFamilyName.get(), &index, &exists),
                   "Failed while finding family by name.",
                   SkRemotableFontIdentitySet::NewEmpty());
        if (!exists) {
            return SkRemotableFontIdentitySet::NewEmpty();
        }

        return this->getIndex(index);
    }

    virtual SkFontIdentity matchNameStyle(const char familyName[],
                                          const SkFontStyle& style) const override
    {
        SkFontIdentity identity = { SkFontIdentity::kInvalidDataId };

        SkSMallocWCHAR dwFamilyName;
        if (nullptr == familyName) {
            HR_GENERAL(getDefaultFontFamilyName(&dwFamilyName), nullptr, identity);
        } else {
            HR_GENERAL(sk_cstring_to_wchar(familyName, &dwFamilyName), nullptr, identity);
        }

        UINT32 index;
        BOOL exists;
        HR_GENERAL(fFontCollection->FindFamilyName(dwFamilyName.get(), &index, &exists),
                   "Failed while finding family by name.",
                   identity);
        if (!exists) {
            return identity;
        }

        return this->matchIndexStyle(index, style);
    }

    class FontFallbackRenderer : public IDWriteTextRenderer {
    public:
        FontFallbackRenderer(const SkRemotableFontMgr_DirectWrite* outer, UINT32 character)
            : fRefCount(1), fOuter(SkSafeRef(outer)), fCharacter(character) {
          fIdentity.fDataId = SkFontIdentity::kInvalidDataId;
        }

        virtual ~FontFallbackRenderer() { }

        // IDWriteTextRenderer methods
        virtual HRESULT STDMETHODCALLTYPE DrawGlyphRun(
            void* clientDrawingContext,
            FLOAT baselineOriginX,
            FLOAT baselineOriginY,
            DWRITE_MEASURING_MODE measuringMode,
            DWRITE_GLYPH_RUN const* glyphRun,
            DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription,
            IUnknown* clientDrawingEffect) override
        {
            SkTScopedComPtr<IDWriteFont> font;
            HRM(fOuter->fFontCollection->GetFontFromFontFace(glyphRun->fontFace, &font),
                "Could not get font from font face.");

            // It is possible that the font passed does not actually have the requested character,
            // due to no font being found and getting the fallback font.
            // Check that the font actually contains the requested character.
            BOOL exists;
            HRM(font->HasCharacter(fCharacter, &exists), "Could not find character.");

            if (exists) {
                HR(fOuter->FontToIdentity(font.get(), &fIdentity));
            }

            return S_OK;
        }

        virtual HRESULT STDMETHODCALLTYPE DrawUnderline(
            void* clientDrawingContext,
            FLOAT baselineOriginX,
            FLOAT baselineOriginY,
            DWRITE_UNDERLINE const* underline,
            IUnknown* clientDrawingEffect) override
        { return E_NOTIMPL; }

        virtual HRESULT STDMETHODCALLTYPE DrawStrikethrough(
            void* clientDrawingContext,
            FLOAT baselineOriginX,
            FLOAT baselineOriginY,
            DWRITE_STRIKETHROUGH const* strikethrough,
            IUnknown* clientDrawingEffect) override
        { return E_NOTIMPL; }

        virtual HRESULT STDMETHODCALLTYPE DrawInlineObject(
            void* clientDrawingContext,
            FLOAT originX,
            FLOAT originY,
            IDWriteInlineObject* inlineObject,
            BOOL isSideways,
            BOOL isRightToLeft,
            IUnknown* clientDrawingEffect) override
        { return E_NOTIMPL; }

        // IDWritePixelSnapping methods
        virtual HRESULT STDMETHODCALLTYPE IsPixelSnappingDisabled(
            void* clientDrawingContext,
            BOOL* isDisabled) override
        {
            *isDisabled = FALSE;
            return S_OK;
        }

        virtual HRESULT STDMETHODCALLTYPE GetCurrentTransform(
            void* clientDrawingContext,
            DWRITE_MATRIX* transform) override
        {
            const DWRITE_MATRIX ident = {1.0, 0.0, 0.0, 1.0, 0.0, 0.0};
            *transform = ident;
            return S_OK;
        }

        virtual HRESULT STDMETHODCALLTYPE GetPixelsPerDip(
            void* clientDrawingContext,
            FLOAT* pixelsPerDip) override
        {
            *pixelsPerDip = 1.0f;
            return S_OK;
        }

        // IUnknown methods
        ULONG STDMETHODCALLTYPE AddRef() override {
            return InterlockedIncrement(&fRefCount);
        }

        ULONG STDMETHODCALLTYPE Release() override {
            ULONG newCount = InterlockedDecrement(&fRefCount);
            if (0 == newCount) {
                delete this;
            }
            return newCount;
        }

        virtual HRESULT STDMETHODCALLTYPE QueryInterface(
            IID const& riid, void** ppvObject) override
        {
            if (__uuidof(IUnknown) == riid ||
                __uuidof(IDWritePixelSnapping) == riid ||
                __uuidof(IDWriteTextRenderer) == riid)
            {
                *ppvObject = this;
                this->AddRef();
                return S_OK;
            }
            *ppvObject = nullptr;
            return E_FAIL;
        }

        const SkFontIdentity FallbackIdentity() { return fIdentity; }

    protected:
        ULONG fRefCount;
        sk_sp<const SkRemotableFontMgr_DirectWrite> fOuter;
        UINT32 fCharacter;
        SkFontIdentity fIdentity;
    };

    virtual SkFontIdentity matchNameStyleCharacter(const char familyName[],
                                                   const SkFontStyle& pattern,
                                                   const char* bcp47[], int bcp47Count,
                                                   SkUnichar character) const override
    {
        SkFontIdentity identity = { SkFontIdentity::kInvalidDataId };

        IDWriteFactory* dwFactory = sk_get_dwrite_factory();
        if (nullptr == dwFactory) {
            return identity;
        }

        // TODO: use IDWriteFactory2::GetSystemFontFallback when available.

        const DWriteStyle dwStyle(pattern);

        SkSMallocWCHAR dwFamilyName;
        if (nullptr == familyName) {
            HR_GENERAL(getDefaultFontFamilyName(&dwFamilyName), nullptr, identity);
        } else {
            HR_GENERAL(sk_cstring_to_wchar(familyName, &dwFamilyName), nullptr, identity);
        }

        const SkSMallocWCHAR* dwBcp47;
        SkSMallocWCHAR dwBcp47Local;
        if (bcp47Count < 1) {
            dwBcp47 = &fLocaleName;
        } else {
            //TODO: support fallback stack.
            HR_GENERAL(sk_cstring_to_wchar(bcp47[bcp47Count-1], &dwBcp47Local), nullptr, identity);
            dwBcp47 = &dwBcp47Local;
        }

        SkTScopedComPtr<IDWriteTextFormat> fallbackFormat;
        HR_GENERAL(dwFactory->CreateTextFormat(dwFamilyName,
                                               fFontCollection.get(),
                                               dwStyle.fWeight,
                                               dwStyle.fSlant,
                                               dwStyle.fWidth,
                                               72.0f,
                                               *dwBcp47,
                                               &fallbackFormat),
                   "Could not create text format.",
                   identity);

        WCHAR str[16];
        UINT32 strLen = static_cast<UINT32>(
            SkUTF16_FromUnichar(character, reinterpret_cast<uint16_t*>(str)));
        SkTScopedComPtr<IDWriteTextLayout> fallbackLayout;
        HR_GENERAL(dwFactory->CreateTextLayout(str, strLen, fallbackFormat.get(),
                                               200.0f, 200.0f,
                                               &fallbackLayout),
                   "Could not create text layout.",
                   identity);

        SkTScopedComPtr<FontFallbackRenderer> fontFallbackRenderer(
            new FontFallbackRenderer(this, character));

        HR_GENERAL(fallbackLayout->Draw(nullptr, fontFallbackRenderer.get(), 50.0f, 50.0f),
                   "Could not draw layout with renderer.",
                   identity);

        return fontFallbackRenderer->FallbackIdentity();
    }

    SkStreamAsset* getData(int dataId) const override {
        SkAutoMutexAcquire ama(fDataIdCacheMutex);
        if (dataId >= fDataIdCache.count()) {
            return nullptr;
        }
        const DataId& id = fDataIdCache[dataId];

        SkTScopedComPtr<IDWriteFontFileLoader> loader;
        HRNM(id.fLoader->QueryInterface(&loader), "QuerryInterface IDWriteFontFileLoader failed");

        SkTScopedComPtr<IDWriteFontFileStream> fontFileStream;
        HRNM(loader->CreateStreamFromKey(id.fKey, id.fKeySize, &fontFileStream),
             "Could not create font file stream.");

        return new SkDWriteFontFileStream(fontFileStream.get());
    }

private:
    SkTScopedComPtr<IDWriteFontCollection> fFontCollection;
    SkSMallocWCHAR fLocaleName;

    typedef SkRemotableFontMgr INHERITED;
};

SkRemotableFontMgr* SkRemotableFontMgr_New_DirectWrite() {
    IDWriteFactory* factory = sk_get_dwrite_factory();
    if (nullptr == factory) {
        return nullptr;
    }

    SkTScopedComPtr<IDWriteFontCollection> sysFontCollection;
    HRNM(factory->GetSystemFontCollection(&sysFontCollection, FALSE),
         "Could not get system font collection.");

    WCHAR localeNameStorage[LOCALE_NAME_MAX_LENGTH];
    WCHAR* localeName = nullptr;
    int localeNameLen = 0;

    // Dynamically load GetUserDefaultLocaleName function, as it is not available on XP.
    SkGetUserDefaultLocaleNameProc getUserDefaultLocaleNameProc = nullptr;
    HRESULT hr = SkGetGetUserDefaultLocaleNameProc(&getUserDefaultLocaleNameProc);
    if (nullptr == getUserDefaultLocaleNameProc) {
        SK_TRACEHR(hr, "Could not get GetUserDefaultLocaleName.");
    } else {
        localeNameLen = getUserDefaultLocaleNameProc(localeNameStorage, LOCALE_NAME_MAX_LENGTH);
        if (localeNameLen) {
            localeName = localeNameStorage;
        };
    }

    return new SkRemotableFontMgr_DirectWrite(sysFontCollection.get(), localeName, localeNameLen);
}
#endif//defined(SK_BUILD_FOR_WIN)
