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

#ifndef SkFontDescriptor_DEFINED
#define SkFontDescriptor_DEFINED

#include "include/core/SkFontArguments.h"
#include "include/core/SkFontStyle.h"
#include "include/core/SkScalar.h"
#include "include/core/SkStream.h"
#include "include/core/SkString.h"
#include "include/core/SkTypeface.h"
#include "include/private/SkFixed.h"
#include "include/private/SkNoncopyable.h"
#include "include/private/SkTemplates.h"

#include <memory>
#include <utility>

class SkFontData {
public:
    /** Makes a copy of the data in 'axis'. */
    SkFontData(std::unique_ptr<SkStreamAsset> stream, int index, int paletteIndex,
               const SkFixed* axis, int axisCount,
               const SkFontArguments::Palette::Override* paletteOverrides, int paletteOverrideCount)
        : fStream(std::move(stream))
        , fIndex(index)
        , fPaletteIndex(paletteIndex)
        , fAxisCount(axisCount)
        , fPaletteOverrideCount(paletteOverrideCount)
        , fAxis(fAxisCount)
        , fPaletteOverrides(fPaletteOverrideCount)
    {
        for (int i = 0; i < fAxisCount; ++i) {
            fAxis[i] = axis[i];
        }
        for (int i = 0; i < fPaletteOverrideCount; ++i) {
            fPaletteOverrides[i] = paletteOverrides[i];
        }
    }

    SkFontData(const SkFontData& that)
        : fStream(that.fStream->duplicate())
        , fIndex(that.fIndex)
        , fPaletteIndex(that.fPaletteIndex)
        , fAxisCount(that.fAxisCount)
        , fPaletteOverrideCount(that.fPaletteOverrideCount)
        , fAxis(fAxisCount)
        , fPaletteOverrides(fPaletteOverrideCount)
    {
        for (int i = 0; i < fAxisCount; ++i) {
            fAxis[i] = that.fAxis[i];
        }
        for (int i = 0; i < fPaletteOverrideCount; ++i) {
            fPaletteOverrides[i] = that.fPaletteOverrides[i];
        }
    }
    bool hasStream() const { return fStream != nullptr; }
    std::unique_ptr<SkStreamAsset> detachStream() { return std::move(fStream); }
    SkStreamAsset* getStream() { return fStream.get(); }
    SkStreamAsset const* getStream() const { return fStream.get(); }
    int getIndex() const { return fIndex; }
    int getAxisCount() const { return fAxisCount; }
    const SkFixed* getAxis() const { return fAxis.get(); }
    int getPaletteIndex() const { return fPaletteIndex; }
    int getPaletteOverrideCount() const { return fPaletteOverrideCount; }
    const SkFontArguments::Palette::Override* getPaletteOverrides() const {
        return fPaletteOverrides.get();
    }

private:
    std::unique_ptr<SkStreamAsset> fStream;
    int fIndex;
    int fPaletteIndex;
    int fAxisCount;
    int fPaletteOverrideCount;
    skia_private::AutoSTMalloc<4, SkFixed> fAxis;
    skia_private::AutoSTMalloc<4, SkFontArguments::Palette::Override> fPaletteOverrides;
};

class SkFontDescriptor : SkNoncopyable {
public:
    SkFontDescriptor();
    // Does not affect ownership of SkStream.
    static bool Deserialize(SkStream*, SkFontDescriptor* result);

    bool serialize(SkWStream*) const;

    SkFontStyle getStyle() const { return fStyle; }
    void setStyle(SkFontStyle style) { fStyle = style; }

    const char* getFamilyName() const { return fFamilyName.c_str(); }
    const char* getFullName() const { return fFullName.c_str(); }
    const char* getPostscriptName() const { return fPostscriptName.c_str(); }

    void setFamilyName(const char* name) { fFamilyName.set(name); }
    void setFullName(const char* name) { fFullName.set(name); }
    void setPostscriptName(const char* name) { fPostscriptName.set(name); }

    bool hasStream() const { return bool(fStream); }
    std::unique_ptr<SkStreamAsset> dupStream() const { return fStream->duplicate(); }
    int getCollectionIndex() const { return fCollectionIndex; }
    int getPaletteIndex() const { return fPaletteIndex; }
    int getVariationCoordinateCount() const { return fCoordinateCount; }
    const SkFontArguments::VariationPosition::Coordinate* getVariation() const {
        return fVariation.get();
    }
    int getPaletteEntryOverrideCount() const { return fPaletteEntryOverrideCount; }
    const SkFontArguments::Palette::Override* getPaletteEntryOverrides() const {
        return fPaletteEntryOverrides.get();
    }
    bool getSyntheticBold() const { return fSyntheticBold; }
    bool getSyntheticOblique() const { return fSyntheticOblique; }
    SkTypeface::FactoryId getFactoryId() {
        return fFactoryId;
    }

    std::unique_ptr<SkStreamAsset> detachStream() { return std::move(fStream); }
    void setStream(std::unique_ptr<SkStreamAsset> stream) { fStream = std::move(stream); }
    void setCollectionIndex(int collectionIndex) { fCollectionIndex = collectionIndex; }
    void setPaletteIndex(int paletteIndex) { fPaletteIndex = paletteIndex; }
    SkFontArguments::VariationPosition::Coordinate* setVariationCoordinates(int coordinateCount) {
        fCoordinateCount = coordinateCount;
        return fVariation.reset(coordinateCount);
    }
    SkFontArguments::Palette::Override* setPaletteEntryOverrides(int paletteEntryOverrideCount) {
        fPaletteEntryOverrideCount = paletteEntryOverrideCount;
        return fPaletteEntryOverrides.reset(paletteEntryOverrideCount);
    }
    void setSyntheticBold(bool bold) { fSyntheticBold = bold; }
    void setSyntheticOblique(bool oblique) { fSyntheticOblique = oblique; }
    void setFactoryId(SkTypeface::FactoryId factoryId) {
        fFactoryId = factoryId;
    }

    SkFontArguments getFontArguments() const {
        return SkFontArguments()
            .setCollectionIndex(this->getCollectionIndex())
            .setVariationDesignPosition({this->getVariation(),this->getVariationCoordinateCount()})
            .setPalette({this->getPaletteIndex(),
                         this->getPaletteEntryOverrides(),
                         this->getPaletteEntryOverrideCount()})
            .setSyntheticBold(fSyntheticBold)
            .setSyntheticOblique(fSyntheticOblique);
    }
    static SkFontStyle::Width SkFontStyleWidthForWidthAxisValue(SkScalar width);
    static SkScalar SkFontWidthAxisValueForStyleWidth(int width);

private:
    SkString fFamilyName;
    SkString fFullName;
    SkString fPostscriptName;
    SkFontStyle fStyle;

    std::unique_ptr<SkStreamAsset> fStream;
    int fCollectionIndex = 0;
    using Coordinates =
            skia_private::AutoSTMalloc<4, SkFontArguments::VariationPosition::Coordinate>;
    int fCoordinateCount = 0;
    Coordinates fVariation;
    int fPaletteIndex = 0;
    int fPaletteEntryOverrideCount = 0;
    skia_private::AutoTMalloc<SkFontArguments::Palette::Override> fPaletteEntryOverrides;
    bool fSyntheticBold = false;
    bool fSyntheticOblique = false;
    SkTypeface::FactoryId fFactoryId = 0;
};

#endif // SkFontDescriptor_DEFINED
