// Copyright 2021 Google LLC.
#include "experimental/sktext/src/Paint.h"

namespace skia {
namespace text {

bool Paint::drawText(std::u16string text, SkCanvas* canvas, SkScalar x, SkScalar y) {

    return drawText(std::move(text), canvas, TextDirection::kLtr, TextAlign::kLeft, SK_ColorBLACK, SK_ColorWHITE, SkString("Roboto"), 14, SkFontStyle::Normal(), x, y);
}

bool Paint::drawText(std::u16string text, SkCanvas* canvas, SkScalar width) {
    return drawText(std::move(text), canvas,
                    TextDirection::kLtr, TextAlign::kLeft, SK_ColorBLACK, SK_ColorWHITE, SkString("Roboto"), 14, SkFontStyle::Normal(),
                    SkSize::Make(width, SK_ScalarInfinity), 0, 0);
}

bool Paint::drawText(std::u16string text, SkCanvas* canvas,
                     TextDirection textDirection, TextAlign textAlign,
                     SkColor foreground, SkColor background,
                     const SkString& fontFamily, SkScalar fontSize, SkFontStyle fontStyle, SkScalar x, SkScalar y) {
    return drawText(std::move(text), canvas,
                    textDirection, textAlign, foreground, background,
                    fontFamily, fontSize, fontStyle, SkSize::Make(SK_ScalarInfinity, SK_ScalarInfinity), x, y);
}

bool Paint::drawText(std::u16string text, SkCanvas* canvas,
                         TextDirection textDirection, TextAlign textAlign,
                         SkColor foreground, SkColor background,
                         const SkString& fontFamily, SkScalar fontSize, SkFontStyle fontStyle, SkSize reqSize, SkScalar x, SkScalar y) {

    size_t textSize = text.size();
    sk_sp<TrivialFontChain> fontChain = sk_make_sp<TrivialFontChain>(fontFamily.c_str(), fontSize);
    Block fontBlock(text.size(), fontChain);


    auto formattedText = Paint::layout(std::move(text), textDirection, textAlign, reqSize, SkSpan<Block>(&fontBlock, 1));
    if (formattedText == nullptr) {
        return false;
    }

    SkPaint backgroundPaint; backgroundPaint.setColor(background);
    SkPaint foregroundPaint; foregroundPaint.setColor(foreground);
    DecoratedBlock decoratedBlock(textSize, foregroundPaint, backgroundPaint);
    Paint paint;
    paint.paint(canvas, SkPoint::Make(x, y), formattedText, SkSpan<DecoratedBlock>(&decoratedBlock, 1));

    return true;
}

void Paint::onBeginLine(TextRange, float baselineY) { }
void Paint::onEndLine(TextRange, float baselineY) { }
void Paint::onPlaceholder(TextRange, const SkRect& bounds) { }
void Paint::onGlyphRun(SkFont font,
                       TextRange textRange,
                       int glyphCount,
                       const uint16_t glyphs[],
                       const SkPoint  positions[],
                       const SkPoint offsets[]) {

    DecoratedBlock decoratedBlock = findDecoratedBlock(textRange);

    SkTextBlobBuilder builder;
    const auto& blobBuffer = builder.allocRunPos(font , SkToInt(glyphCount));
    sk_careful_memcpy(blobBuffer.glyphs, glyphs, glyphCount * sizeof(uint16_t));
    sk_careful_memcpy(blobBuffer.points(), positions, glyphCount * sizeof(SkPoint));
    fCanvas->drawTextBlob(builder.make(), fXY.fX, fXY.fY, decoratedBlock.foregroundColor);
}

sk_sp<FormattedText> Paint::layout(std::u16string text,
                            TextDirection textDirection, TextAlign textAlign,
                            SkSize reqSize,
                            SkSpan<Block> fontBlocks) {
    auto unicodeText = Text::parse(SkSpan<uint16_t>((uint16_t*)text.data(), text.size()));
    auto shapedText = unicodeText->shape(fontBlocks, textDirection);
    auto wrappedText = shapedText->wrap(reqSize.width(), reqSize.height(), unicodeText->getUnicode());
    auto formattedText = wrappedText->format(textAlign, textDirection);

    return formattedText;
}

DecoratedBlock Paint::findDecoratedBlock(TextRange textRange) {
    TextIndex start = 0;
    for (auto& block : fDecoratedBlocks) {
        if (start + block.charCount < textRange.fStart) {
            start += block.charCount;
            continue;
        } else if (start > textRange.fEnd) {
            break;
        }
        return block;
    }
    return DecoratedBlock(0, SkPaint(), SkPaint());
}

void Paint::paint(SkCanvas* canvas, SkPoint xy, sk_sp<FormattedText> formattedText, SkSpan<DecoratedBlock> decoratedBlocks) {
    fCanvas = canvas;
    fXY = xy;

    SkTArray<size_t> chunks;
    chunks.resize(decoratedBlocks.size());
    for (size_t i = 0; i < decoratedBlocks.size(); ++i) {
        chunks[i] = decoratedBlocks[i].charCount;
    }

    formattedText->visit(this, SkSpan<size_t>(chunks.data(), chunks.size()));
}

} // namespace text
} // namespace skia
