// 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/entity/contents/color_source_text_contents.h"

#include "impeller/entity/contents/content_context.h"
#include "impeller/entity/contents/texture_contents.h"
#include "impeller/renderer/render_pass.h"

namespace impeller {

ColorSourceTextContents::ColorSourceTextContents() = default;

ColorSourceTextContents::~ColorSourceTextContents() = default;

void ColorSourceTextContents::SetTextContents(
    std::shared_ptr<TextContents> text_contents) {
  text_contents_ = std::move(text_contents);
}

void ColorSourceTextContents::SetColorSourceContents(
    std::shared_ptr<ColorSourceContents> color_source_contents) {
  color_source_contents_ = std::move(color_source_contents);
}

std::optional<Rect> ColorSourceTextContents::GetCoverage(
    const Entity& entity) const {
  return text_contents_->GetCoverage(entity);
}

void ColorSourceTextContents::SetTextPosition(Point position) {
  position_ = position;
}

bool ColorSourceTextContents::Render(const ContentContext& renderer,
                                     const Entity& entity,
                                     RenderPass& pass) const {
  auto text_bounds = text_contents_->GetTextFrameBounds();
  if (!text_bounds.has_value()) {
    return true;
  }

  text_contents_->SetColor(Color::Black());
  color_source_contents_->SetGeometry(
      Geometry::MakeRect(Rect::MakeSize(text_bounds->size)));

  // offset the color source so it behaves as if it were drawn in the original
  // position.
  auto effect_transform =
      color_source_contents_->GetInverseMatrix().Invert().Translate(-position_);
  color_source_contents_->SetEffectTransform(effect_transform);

  auto new_texture = renderer.MakeSubpass(
      "Text Color Blending", ISize::Ceil(text_bounds.value().size),
      [&](const ContentContext& context, RenderPass& pass) {
        Entity sub_entity;
        sub_entity.SetContents(text_contents_);
        sub_entity.SetBlendMode(BlendMode::kSource);
        if (!sub_entity.Render(context, pass)) {
          return false;
        }

        sub_entity.SetContents(color_source_contents_);
        sub_entity.SetBlendMode(BlendMode::kSourceIn);
        return sub_entity.Render(context, pass);
      });
  if (!new_texture) {
    return false;
  }

  auto dest_rect = Rect::MakeSize(new_texture->GetSize()).Shift(position_);

  auto texture_contents = TextureContents::MakeRect(dest_rect);
  texture_contents->SetTexture(new_texture);
  texture_contents->SetSourceRect(Rect::MakeSize(new_texture->GetSize()));
  return texture_contents->Render(renderer, entity, pass);
}

}  // namespace impeller
