/*
 * 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 "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;
    void getPath(SkGlyphID glyph, SkPath* path) 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;
    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 fGlyphs.count();
    }

    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(sk_sp<SkSVGDOM> svg, const SkSVGTestTypefaceGlyphData& data);
        ~Glyph();
        sk_sp<SkSVGDOM> fSvg;
        SkPoint fOrigin;
        SkScalar fAdvance;
    };
    SkString fName;
    int fUpem;
    const SkPaint::FontMetrics fFontMetrics;
    SkTArray<Glyph> fGlyphs;
    SkTHashMap<SkUnichar, SkGlyphID> fCMap;
    friend class SkTestSVGScalerContext;
};

#endif
