// 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.

#pragma once

#include <functional>
#include <memory>
#include <optional>
#include <vector>

#include "flutter/fml/macros.h"
#include "impeller/entity/contents/contents.h"
#include "impeller/entity/contents/filters/filter_contents.h"
#include "impeller/entity/entity.h"
#include "impeller/entity/entity_pass_delegate.h"
#include "impeller/entity/inline_pass_context.h"
#include "impeller/renderer/render_target.h"
#include "impeller/typographer/lazy_glyph_atlas.h"

namespace impeller {

class ContentContext;

class EntityPass {
 public:
  using Element = std::variant<Entity, std::unique_ptr<EntityPass>>;
  using BackdropFilterProc =
      std::function<std::shared_ptr<FilterContents>(FilterInput::Ref)>;

  EntityPass();

  ~EntityPass();

  void SetDelegate(std::unique_ptr<EntityPassDelegate> delgate);

  size_t GetSubpassesDepth() const;

  std::unique_ptr<EntityPass> Clone() const;

  void AddEntity(Entity entity);

  void SetElements(std::vector<Element> elements);

  const std::shared_ptr<LazyGlyphAtlas>& GetLazyGlyphAtlas() const;

  EntityPass* AddSubpass(std::unique_ptr<EntityPass> pass);

  EntityPass* GetSuperpass() const;

  bool Render(ContentContext& renderer, RenderTarget render_target) const;

  void IterateAllEntities(std::function<bool(Entity&)> iterator);

  void SetTransformation(Matrix xformation);

  void SetStencilDepth(size_t stencil_depth);

  void SetBlendMode(Entity::BlendMode blend_mode);

  void SetBackdropFilter(std::optional<BackdropFilterProc> proc);

  std::optional<Rect> GetSubpassCoverage(const EntityPass& subpass) const;

  std::optional<Rect> GetElementsCoverage() const;

 private:
  struct EntityResult {
    enum Status {
      /// The entity was successfully resolved and can be rendered.
      kSuccess,
      /// An unexpected rendering error occurred while resolving the Entity.
      kFailure,
      /// The entity should be skipped because rendering it will contribute
      /// nothing to the frame.
      kSkip,
    };

    /// @brief  The resulting entity that should be rendered. If `std::nullopt`,
    ///         there is nothing to render.
    Entity entity;
    /// @brief  This is set to `false` if there was an unexpected rendering
    ///         error while resolving the Entity.
    Status status = kFailure;

    static EntityResult Success(Entity e) { return {e, kSuccess}; }
    static EntityResult Failure() { return {{}, kFailure}; }
    static EntityResult Skip() { return {{}, kSkip}; }
  };

  EntityResult GetEntityForElement(const EntityPass::Element& element,
                                   ContentContext& renderer,
                                   InlinePassContext& pass_context,
                                   Point position,
                                   uint32_t pass_depth,
                                   size_t stencil_depth_floor) const;

  bool OnRender(ContentContext& renderer,
                RenderTarget render_target,
                Point position,
                Point parent_position,
                uint32_t pass_depth,
                size_t stencil_depth_floor = 0,
                std::shared_ptr<Contents> backdrop_contents = nullptr) const;

  std::vector<Element> elements_;

  EntityPass* superpass_ = nullptr;
  Matrix xformation_;
  size_t stencil_depth_ = 0u;
  Entity::BlendMode blend_mode_ = Entity::BlendMode::kSourceOver;

  /// This flag is set to `true` whenever an entity is added to the pass that
  /// requires reading the pass texture during rendering. This can happen in the
  /// following scenarios:
  ///   1. An entity with an "advanced blend" is added to the pass.
  ///   2. A subpass with a backdrop filter is added to the pass.
  bool reads_from_pass_texture_ = false;

  std::optional<BackdropFilterProc> backdrop_filter_proc_ = std::nullopt;

  std::unique_ptr<EntityPassDelegate> delegate_ =
      EntityPassDelegate::MakeDefault();
  std::shared_ptr<LazyGlyphAtlas> lazy_glyph_atlas_ =
      std::make_shared<LazyGlyphAtlas>();

  FML_DISALLOW_COPY_AND_ASSIGN(EntityPass);
};

struct CanvasStackEntry {
  Matrix xformation;
  size_t stencil_depth = 0u;
  bool is_subpass = false;
  bool contains_clips = false;
};

}  // namespace impeller
