/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkTestSVGTypeface_DEFINED
#define SkTestSVGTypeface_DEFINED

#include "SkFontArguments.h"
#include "SkMutex.h"
#include "SkPaint.h"
#include "SkPoint.h"
#include "SkRect.h"
#include "SkRefCnt.h"
#include "SkScalar.h"
#include "SkString.h"
#include "SkTArray.h"
#include "SkTHash.h"
#include "SkTypeface.h"
#include "SkTypes.h"

#include <memory>

class SkDescriptor;
class SkFontDescriptor;
class SkFontStyle;
class SkGlyph;
class SkPath;
class SkScalerContext;
class SkStreamAsset;
class SkSVGDOM;
class SkWStream;
struct SkAdvancedTypefaceMetrics;
struct SkScalerContextEffects;
struct SkScalerContextRec;

struct SkSVGTestTypefaceGlyphData {
    const char* fSvgResourcePath;
    SkPoint fOrigin;
    SkScalar fAdvance;
    SkUnichar fUnicode; //TODO: this limits to 1:1
};

class SkTestSVGTypeface : public SkTypeface {
public:
    SkTestSVGTypeface(const char* name,
                      int upem,
                      const SkPaint::FontMetrics& metrics,
                      const SkSVGTestTypefaceGlyphData* data, int dataCount,
                      const SkFontStyle& style);
    ~SkTestSVGTypeface() override;
    void getAdvance(SkGlyph* glyph) const;
    void getFontMetrics(SkPaint::FontMetrics* metrics) const;

    static sk_sp<SkTestSVGTypeface> Default();
    void exportTtxCbdt(SkWStream*) const;
    void exportTtxSbix(SkWStream*) const;
    void exportTtxColr(SkWStream*) const;

    struct GlyfLayerInfo {
        GlyfLayerInfo(int layerColorIndex, SkIRect bounds)
            : fLayerColorIndex(layerColorIndex)
            , fBounds(bounds) {}
        int fLayerColorIndex;
        SkIRect fBounds;
    };
    struct GlyfInfo {
        GlyfInfo() : fBounds(SkIRect::MakeEmpty()) {}
        SkIRect fBounds;
        SkTArray<GlyfLayerInfo> fLayers;
    };
protected:
    void exportTtxCommon(SkWStream*, const char* type, const SkTArray<GlyfInfo>* = nullptr) const;

    SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&,
                                           const SkDescriptor* desc) const override;
    void onFilterRec(SkScalerContextRec* rec) const override;
    void getGlyphToUnicodeMap(SkUnichar*) const override;
    std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override;

    SkStreamAsset* onOpenStream(int* ttcIndex) const override {
        return nullptr;
    }

    void onGetFontDescriptor(SkFontDescriptor* desc, bool* isLocal) const override;

    int onCharsToGlyphs(const void* chars, Encoding encoding,
                        uint16_t glyphs[], int glyphCount) const override;

    int onCountGlyphs() const override {
        return fGlyphCount;
    }

    int onGetUPEM() const override {
        return fUpem;
    }

    void onGetFamilyName(SkString* familyName) const override;
    SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override;

    int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],
                                     int coordinateCount) const override
    {
        return 0;
    }

    int onGetTableTags(SkFontTableTag tags[]) const override {
        return 0;
    }

    size_t onGetTableData(SkFontTableTag tag, size_t offset,
                          size_t length, void* data) const override {
        return 0;
    }
private:
    struct Glyph {
        Glyph();
        ~Glyph();
        sk_sp<SkSVGDOM> fSvg;
        SkMutex fSvgMutex;
        SkPoint fOrigin;
        SkScalar fAdvance;
    };
    SkString fName;
    int fUpem;
    const SkPaint::FontMetrics fFontMetrics;
    std::unique_ptr<Glyph[]> fGlyphs;
    int fGlyphCount;
    SkTHashMap<SkUnichar, SkGlyphID> fCMap;
    friend class SkTestSVGScalerContext;
};

#endif
