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

#ifndef SkottieTextShaper_DEFINED
#define SkottieTextShaper_DEFINED

#include "include/core/SkFont.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRefCnt.h"
#include "include/private/base/SkTypeTraits.h"
#include "include/utils/SkTextUtils.h"

#include <vector>

class SkCanvas;
class SkFontMgr;
class SkTypeface;
class SkString;

struct SkRect;

namespace skottie {

// Helper implementing After Effects text shaping semantics on top of SkShaper.

class Shaper final {
public:
    struct RunRec {
        SkFont fFont;
        size_t fSize;

        static_assert(::sk_is_trivially_relocatable<decltype(fFont)>::value);

        using sk_is_trivially_relocatable = std::true_type;
    };

    struct ShapedGlyphs {
        std::vector<RunRec>    fRuns;

        // Consolidated storage for all runs.
        std::vector<SkGlyphID> fGlyphIDs;
        std::vector<SkPoint>   fGlyphPos;

        // fClusters[i] is an input string index, pointing to the start of the UTF sequence
        // associated with fGlyphs[i].  The number of entries matches the number of glyphs.
        // Only available with Flags::kClusters.
        std::vector<size_t>    fClusters;

        enum class BoundsType { kConservative, kTight };
        SkRect computeBounds(BoundsType) const;

        void draw(SkCanvas*, const SkPoint& origin, const SkPaint&) const;
    };

    struct Fragment {
        ShapedGlyphs fGlyphs;
        SkPoint      fOrigin;

        // Only valid for kFragmentGlyphs
        float        fAdvance,
                     fAscent;
        uint32_t     fLineIndex;    // 0-based index for the line this fragment belongs to.
        bool         fIsWhitespace; // True if the first code point in the corresponding
                                    // cluster is whitespace.
    };

    struct Result {
        std::vector<Fragment> fFragments;
        size_t                fMissingGlyphCount = 0;
        // Relative text size scale, when using an auto-scaling ResizePolicy
        // (otherwise 1.0).  This is informative of the final text size, and is
        // not required to render the Result.
        float                 fScale = 1.0f;

        SkRect computeVisualBounds() const;
    };

    enum class VAlign : uint8_t {
        // Align the first line typographical top with the text box top (AE box text).
        kTop,
        // Align the first line typographical baseline with the text box top (AE point text).
        kTopBaseline,

        // Skottie vertical alignment extensions

        // These are based on a hybrid extent box defined (in Y) as
        //
        //   ------------------------------------------------------
        //   MIN(visual_top_extent   , typographical_top_extent   )
        //
        //                         ...
        //
        //   MAX(visual_bottom_extent, typographical_bottom_extent)
        //   ------------------------------------------------------
        kHybridTop,     // extent box top    -> text box top
        kHybridCenter,  // extent box center -> text box center
        kHybridBottom,  // extent box bottom -> text box bottom

        // Visual alignement modes -- these are using tight visual bounds for the paragraph.
        kVisualTop,     // visual top    -> text box top
        kVisualCenter,  // visual center -> text box center
        kVisualBottom,  // visual bottom -> text box bottom
    };

    enum class ResizePolicy : uint8_t {
        // Use the specified text size.
        kNone,
        // Resize the text such that the extent box fits (snuggly) in the text box,
        // both horizontally and vertically.
        kScaleToFit,
        // Same kScaleToFit if the text doesn't fit at the specified font size.
        // Otherwise, same as kNone.
        kDownscaleToFit,
    };

    enum class LinebreakPolicy : uint8_t {
        // Break lines such that they fit in a non-empty paragraph box, horizontally.
        kParagraph,
        // Only break lines when requested explicitly (\r), regardless of paragraph box dimensions.
        kExplicit,
    };

    // Initial text direction.
    enum class Direction : uint8_t { kLTR, kRTL };

    enum class Capitalization {
        kNone,
        kUpperCase,
    };

    enum Flags : uint32_t {
        kNone                       = 0x00,

        // Split out individual glyphs into separate Fragments
        // (useful when the caller intends to manipulate glyphs independently).
        kFragmentGlyphs             = 0x01,

        // Compute the advance and ascent for each fragment.
        kTrackFragmentAdvanceAscent = 0x02,

        // Return cluster information.
        kClusters                   = 0x04,
    };

    struct TextDesc {
        const sk_sp<SkTypeface>&  fTypeface;
        SkScalar                  fTextSize       = 0,
                                  fMinTextSize    = 0,  // when auto-sizing
                                  fMaxTextSize    = 0,  // when auto-sizing
                                  fLineHeight     = 0,
                                  fLineShift      = 0,
                                  fAscent         = 0;
        SkTextUtils::Align        fHAlign         = SkTextUtils::kLeft_Align;
        VAlign                    fVAlign         = Shaper::VAlign::kTop;
        ResizePolicy              fResize         = Shaper::ResizePolicy::kNone;
        LinebreakPolicy           fLinebreak      = Shaper::LinebreakPolicy::kExplicit;
        Direction                 fDirection      = Shaper::Direction::kLTR ;
        Capitalization            fCapitalization = Shaper::Capitalization::kNone;
        size_t                    fMaxLines       = 0;  // when auto-sizing, 0 -> no max
        uint32_t                  fFlags          = 0;
        const char*               fLocale         = nullptr;
    };

    // Performs text layout along an infinite horizontal line, starting at |point|.
    // Only explicit line breaks (\r) are observed.
    static Result Shape(const SkString& text, const TextDesc& desc, const SkPoint& point,
                        const sk_sp<SkFontMgr>&);

    // Performs text layout within |box|, injecting line breaks as needed to ensure
    // horizontal fitting.  The result is *not* guaranteed to fit vertically (it may extend
    // below the box bottom).
    static Result Shape(const SkString& text, const TextDesc& desc, const SkRect& box,
                        const sk_sp<SkFontMgr>&);

private:
    Shaper() = delete;
};

} // namespace skottie

#endif // SkottieTextShaper_DEFINED
