// 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/filters/inputs/filter_input.h"

#include <memory>
#include <utility>

#include "flutter/fml/logging.h"
#include "impeller/entity/contents/filters/filter_contents.h"
#include "impeller/entity/contents/filters/inputs/contents_filter_input.h"
#include "impeller/entity/contents/filters/inputs/filter_contents_filter_input.h"
#include "impeller/entity/contents/filters/inputs/placeholder_filter_input.h"
#include "impeller/entity/contents/filters/inputs/texture_filter_input.h"

namespace impeller {

FilterInput::Ref FilterInput::Make(Variant input, bool msaa_enabled) {
  if (auto filter = std::get_if<std::shared_ptr<FilterContents>>(&input)) {
    return std::static_pointer_cast<FilterInput>(
        std::shared_ptr<FilterContentsFilterInput>(
            new FilterContentsFilterInput(*filter)));
  }

  if (auto contents = std::get_if<std::shared_ptr<Contents>>(&input)) {
    return std::static_pointer_cast<FilterInput>(
        std::shared_ptr<ContentsFilterInput>(
            new ContentsFilterInput(*contents, msaa_enabled)));
  }

  if (auto texture = std::get_if<std::shared_ptr<Texture>>(&input)) {
    return Make(*texture, Matrix());
  }

  if (auto rect = std::get_if<Rect>(&input)) {
    return std::shared_ptr<PlaceholderFilterInput>(
        new PlaceholderFilterInput(*rect));
  }

  FML_UNREACHABLE();
}

FilterInput::Ref FilterInput::Make(std::shared_ptr<Texture> texture,
                                   Matrix local_transform) {
  return std::shared_ptr<TextureFilterInput>(
      new TextureFilterInput(std::move(texture), local_transform));
}

FilterInput::Vector FilterInput::Make(std::initializer_list<Variant> inputs) {
  FilterInput::Vector result;
  result.reserve(inputs.size());
  for (const auto& input : inputs) {
    result.push_back(Make(input));
  }
  return result;
}

Matrix FilterInput::GetLocalTransform(const Entity& entity) const {
  return Matrix();
}

std::optional<Rect> FilterInput::GetLocalCoverage(const Entity& entity) const {
  Entity local_entity = entity;
  local_entity.SetTransformation(GetLocalTransform(entity));
  return GetCoverage(local_entity);
}

Matrix FilterInput::GetTransform(const Entity& entity) const {
  return entity.GetTransformation() * GetLocalTransform(entity);
}

void FilterInput::PopulateGlyphAtlas(
    const std::shared_ptr<LazyGlyphAtlas>& lazy_glyph_atlas,
    Scalar scale) {}

FilterInput::~FilterInput() = default;

bool FilterInput::IsLeaf() const {
  return true;
}

void FilterInput::SetLeafInputs(const FilterInput::Vector& inputs) {}

void FilterInput::SetEffectTransform(const Matrix& matrix) {}

void FilterInput::SetIsForSubpass(bool is_for_subpass) {}

}  // namespace impeller
