// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "impeller/typographer/backends/skia/text_frame_skia.h"

#include <vector>

#include "flutter/fml/logging.h"
#include "impeller/typographer/backends/skia/typeface_skia.h"
#include "include/core/SkFontTypes.h"
#include "include/core/SkRect.h"
#include "third_party/skia/include/core/SkFont.h"
#include "third_party/skia/include/core/SkFontMetrics.h"
#include "third_party/skia/src/core/SkStrikeSpec.h"    // nogncheck
#include "third_party/skia/src/core/SkTextBlobPriv.h"  // nogncheck

namespace impeller {

static Font ToFont(const SkTextBlobRunIterator& run, Scalar scale) {
  auto& font = run.font();
  auto typeface = std::make_shared<TypefaceSkia>(font.refTypefaceOrDefault());

  SkFontMetrics sk_metrics;
  font.getMetrics(&sk_metrics);

  Font::Metrics metrics;
  metrics.scale = scale;
  metrics.point_size = font.getSize();
  metrics.embolden = font.isEmbolden();
  metrics.skewX = font.getSkewX();
  metrics.scaleX = font.getScaleX();

  return Font{std::move(typeface), metrics};
}

static Rect ToRect(const SkRect& rect) {
  return Rect::MakeLTRB(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom);
}

TextFrame TextFrameFromTextBlob(const sk_sp<SkTextBlob>& blob, Scalar scale) {
  if (!blob) {
    return {};
  }

  TextFrame frame;

  for (SkTextBlobRunIterator run(blob.get()); !run.done(); run.next()) {
    TextRun text_run(ToFont(run, scale));

    // TODO(jonahwilliams): ask Skia for a public API to look this up.
    // https://github.com/flutter/flutter/issues/112005
    SkStrikeSpec strikeSpec = SkStrikeSpec::MakeWithNoDevice(run.font());
    SkBulkGlyphMetricsAndPaths paths{strikeSpec};

    const auto glyph_count = run.glyphCount();
    const auto* glyphs = run.glyphs();
    switch (run.positioning()) {
      case SkTextBlobRunIterator::kDefault_Positioning:
        FML_DLOG(ERROR) << "Unimplemented.";
        break;
      case SkTextBlobRunIterator::kHorizontal_Positioning:
        FML_DLOG(ERROR) << "Unimplemented.";
        break;
      case SkTextBlobRunIterator::kFull_Positioning: {
        std::vector<SkRect> glyph_bounds;
        glyph_bounds.resize(glyph_count);
        run.font().getBounds(glyphs, glyph_count, glyph_bounds.data(), nullptr);

        for (auto i = 0u; i < glyph_count; i++) {
          // kFull_Positioning has two scalars per glyph.
          const SkPoint* glyph_points = run.points();
          const auto* point = glyph_points + i;
          Glyph::Type type = paths.glyph(glyphs[i])->isColor()
                                 ? Glyph::Type::kBitmap
                                 : Glyph::Type::kPath;

          text_run.AddGlyph(Glyph{glyphs[i], type, ToRect(glyph_bounds[i])},
                            Point{point->x(), point->y()});
        }
        break;
      }
      case SkTextBlobRunIterator::kRSXform_Positioning:
        FML_DLOG(ERROR) << "Unimplemented.";
        break;
      default:
        FML_DLOG(ERROR) << "Unimplemented.";
        continue;
    }
    frame.AddTextRun(text_run);
  }

  return frame;
}

}  // namespace impeller
