// 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/aiks/color_source.h"

#include <memory>
#include <vector>

#include "impeller/aiks/paint.h"
#include "impeller/core/sampler_descriptor.h"
#include "impeller/entity/contents/conical_gradient_contents.h"
#include "impeller/entity/contents/filters/color_filter_contents.h"
#include "impeller/entity/contents/linear_gradient_contents.h"
#include "impeller/entity/contents/radial_gradient_contents.h"
#include "impeller/entity/contents/runtime_effect_contents.h"
#include "impeller/entity/contents/solid_color_contents.h"
#include "impeller/entity/contents/sweep_gradient_contents.h"
#include "impeller/entity/contents/tiled_texture_contents.h"
#include "impeller/geometry/color.h"
#include "impeller/geometry/matrix.h"
#include "impeller/geometry/scalar.h"
#include "impeller/runtime_stage/runtime_stage.h"

#if IMPELLER_ENABLE_3D
#include "impeller/entity/contents/scene_contents.h"  // nogncheck
#include "impeller/scene/node.h"                      // nogncheck
#endif                                                // IMPELLER_ENABLE_3D

namespace impeller {

ColorSource::ColorSource() noexcept
    : proc_([](const Paint& paint) -> std::shared_ptr<ColorSourceContents> {
        auto contents = std::make_shared<SolidColorContents>();
        contents->SetColor(paint.color);
        return contents;
      }){};

ColorSource::~ColorSource() = default;

ColorSource ColorSource::MakeColor() {
  return {};
}

ColorSource ColorSource::MakeLinearGradient(Point start_point,
                                            Point end_point,
                                            std::vector<Color> colors,
                                            std::vector<Scalar> stops,
                                            Entity::TileMode tile_mode,
                                            Matrix effect_transform) {
  ColorSource result;
  result.type_ = Type::kLinearGradient;
  result.proc_ = [start_point, end_point, colors = std::move(colors),
                  stops = std::move(stops), tile_mode,
                  effect_transform](const Paint& paint) {
    auto contents = std::make_shared<LinearGradientContents>();
    contents->SetOpacityFactor(paint.color.alpha);
    contents->SetColors(colors);
    contents->SetStops(stops);
    contents->SetEndPoints(start_point, end_point);
    contents->SetTileMode(tile_mode);
    contents->SetDither(paint.dither);
    contents->SetEffectTransform(effect_transform);

    std::vector<Point> bounds{start_point, end_point};
    auto intrinsic_size = Rect::MakePointBounds(bounds.begin(), bounds.end());
    if (intrinsic_size.has_value()) {
      contents->SetColorSourceSize(intrinsic_size->size);
    }
    return contents;
  };
  return result;
}

ColorSource ColorSource::MakeConicalGradient(Point center,
                                             Scalar radius,
                                             std::vector<Color> colors,
                                             std::vector<Scalar> stops,
                                             Point focus_center,
                                             Scalar focus_radius,
                                             Entity::TileMode tile_mode,
                                             Matrix effect_transform) {
  ColorSource result;
  result.type_ = Type::kConicalGradient;
  result.proc_ = [center, radius, colors = std::move(colors),
                  stops = std::move(stops), focus_center, focus_radius,
                  tile_mode, effect_transform](const Paint& paint) {
    std::shared_ptr<ConicalGradientContents> contents =
        std::make_shared<ConicalGradientContents>();
    contents->SetOpacityFactor(paint.color.alpha);
    contents->SetColors(colors);
    contents->SetStops(stops);
    contents->SetCenterAndRadius(center, radius);
    contents->SetTileMode(tile_mode);
    contents->SetDither(paint.dither);
    contents->SetEffectTransform(effect_transform);
    contents->SetFocus(focus_center, focus_radius);

    auto radius_pt = Point(radius, radius);
    std::vector<Point> bounds{center + radius_pt, center - radius_pt};
    auto intrinsic_size = Rect::MakePointBounds(bounds.begin(), bounds.end());
    if (intrinsic_size.has_value()) {
      contents->SetColorSourceSize(intrinsic_size->size);
    }
    return contents;
  };
  return result;
}

ColorSource ColorSource::MakeRadialGradient(Point center,
                                            Scalar radius,
                                            std::vector<Color> colors,
                                            std::vector<Scalar> stops,
                                            Entity::TileMode tile_mode,
                                            Matrix effect_transform) {
  ColorSource result;
  result.type_ = Type::kRadialGradient;
  result.proc_ = [center, radius, colors = std::move(colors),
                  stops = std::move(stops), tile_mode,
                  effect_transform](const Paint& paint) {
    auto contents = std::make_shared<RadialGradientContents>();
    contents->SetOpacityFactor(paint.color.alpha);
    contents->SetColors(colors);
    contents->SetStops(stops);
    contents->SetCenterAndRadius(center, radius);
    contents->SetTileMode(tile_mode);
    contents->SetDither(paint.dither);
    contents->SetEffectTransform(effect_transform);

    auto radius_pt = Point(radius, radius);
    std::vector<Point> bounds{center + radius_pt, center - radius_pt};
    auto intrinsic_size = Rect::MakePointBounds(bounds.begin(), bounds.end());
    if (intrinsic_size.has_value()) {
      contents->SetColorSourceSize(intrinsic_size->size);
    }
    return contents;
  };
  return result;
}

ColorSource ColorSource::MakeSweepGradient(Point center,
                                           Degrees start_angle,
                                           Degrees end_angle,
                                           std::vector<Color> colors,
                                           std::vector<Scalar> stops,
                                           Entity::TileMode tile_mode,
                                           Matrix effect_transform) {
  ColorSource result;
  result.type_ = Type::kSweepGradient;
  result.proc_ = [center, start_angle, end_angle, colors = std::move(colors),
                  stops = std::move(stops), tile_mode,
                  effect_transform](const Paint& paint) {
    auto contents = std::make_shared<SweepGradientContents>();
    contents->SetOpacityFactor(paint.color.alpha);
    contents->SetCenterAndAngles(center, start_angle, end_angle);
    contents->SetColors(colors);
    contents->SetStops(stops);
    contents->SetTileMode(tile_mode);
    contents->SetDither(paint.dither);
    contents->SetEffectTransform(effect_transform);

    return contents;
  };
  return result;
}

ColorSource ColorSource::MakeImage(std::shared_ptr<Texture> texture,
                                   Entity::TileMode x_tile_mode,
                                   Entity::TileMode y_tile_mode,
                                   SamplerDescriptor sampler_descriptor,
                                   Matrix effect_transform) {
  ColorSource result;
  result.type_ = Type::kImage;
  result.proc_ = [texture = std::move(texture), x_tile_mode, y_tile_mode,
                  sampler_descriptor = std::move(sampler_descriptor),
                  effect_transform](const Paint& paint) {
    auto contents = std::make_shared<TiledTextureContents>();
    contents->SetOpacityFactor(paint.color.alpha);
    contents->SetTexture(texture);
    contents->SetTileModes(x_tile_mode, y_tile_mode);
    contents->SetSamplerDescriptor(sampler_descriptor);
    contents->SetEffectTransform(effect_transform);
    if (paint.color_filter) {
      TiledTextureContents::ColorFilterProc filter_proc =
          [color_filter = paint.color_filter](FilterInput::Ref input) {
            return color_filter->WrapWithGPUColorFilter(
                std::move(input), ColorFilterContents::AbsorbOpacity::kNo);
          };
      contents->SetColorFilter(filter_proc);
    }
    contents->SetColorSourceSize(Size::Ceil(texture->GetSize()));
    return contents;
  };
  return result;
}

ColorSource ColorSource::MakeRuntimeEffect(
    std::shared_ptr<RuntimeStage> runtime_stage,
    std::shared_ptr<std::vector<uint8_t>> uniform_data,
    std::vector<RuntimeEffectContents::TextureInput> texture_inputs) {
  ColorSource result;
  result.type_ = Type::kRuntimeEffect;
  result.proc_ = [runtime_stage = std::move(runtime_stage),
                  uniform_data = std::move(uniform_data),
                  texture_inputs =
                      std::move(texture_inputs)](const Paint& paint) {
    auto contents = std::make_shared<RuntimeEffectContents>();
    contents->SetOpacityFactor(paint.color.alpha);
    contents->SetRuntimeStage(runtime_stage);
    contents->SetUniformData(uniform_data);
    contents->SetTextureInputs(texture_inputs);
    return contents;
  };
  return result;
}

#if IMPELLER_ENABLE_3D
ColorSource ColorSource::MakeScene(std::shared_ptr<scene::Node> scene_node,
                                   Matrix camera_transform) {
  ColorSource result;
  result.type_ = Type::kScene;
  result.proc_ = [scene_node = std::move(scene_node),
                  camera_transform](const Paint& paint) {
    auto contents = std::make_shared<SceneContents>();
    contents->SetOpacityFactor(paint.color.alpha);
    contents->SetNode(scene_node);
    contents->SetCameraTransform(camera_transform);
    return contents;
  };
  return result;
}
#endif  // IMPELLER_ENABLE_3D

ColorSource::Type ColorSource::GetType() const {
  return type_;
}

std::shared_ptr<ColorSourceContents> ColorSource::GetContents(
    const Paint& paint) const {
  return proc_(paint);
}

}  // namespace impeller
