// 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 "flutter/display_list/skia/dl_sk_conversions.h"

#include "third_party/skia/include/core/SkColorFilter.h"
#include "third_party/skia/include/effects/SkGradientShader.h"
#include "third_party/skia/include/effects/SkImageFilters.h"

namespace flutter {

// clang-format off
constexpr float kInvertColorMatrix[20] = {
  -1.0,    0,    0, 1.0, 0,
     0, -1.0,    0, 1.0, 0,
     0,    0, -1.0, 1.0, 0,
   1.0,  1.0,  1.0, 1.0, 0
};
// clang-format on

SkPaint ToSk(const DlPaint& paint, bool force_stroke) {
  SkPaint sk_paint;

  sk_paint.setAntiAlias(paint.isAntiAlias());
  sk_paint.setColor(ToSk(paint.getColor()));
  sk_paint.setBlendMode(ToSk(paint.getBlendMode()));
  sk_paint.setStyle(force_stroke ? SkPaint::kStroke_Style
                                 : ToSk(paint.getDrawStyle()));
  sk_paint.setStrokeWidth(paint.getStrokeWidth());
  sk_paint.setStrokeMiter(paint.getStrokeMiter());
  sk_paint.setStrokeCap(ToSk(paint.getStrokeCap()));
  sk_paint.setStrokeJoin(ToSk(paint.getStrokeJoin()));
  sk_paint.setImageFilter(ToSk(paint.getImageFilterPtr()));
  auto color_filter = ToSk(paint.getColorFilterPtr());
  if (paint.isInvertColors()) {
    auto invert_filter = SkColorFilters::Matrix(kInvertColorMatrix);
    if (color_filter) {
      invert_filter = invert_filter->makeComposed(color_filter);
    }
    color_filter = invert_filter;
  }
  sk_paint.setColorFilter(color_filter);

  auto color_source = paint.getColorSourcePtr();
  if (color_source) {
    // On the Impeller backend, we will only support dithering of *gradients*,
    // and it will be enabled by default (without the option to disable it).
    // Until Skia support is completely removed, we only want to respect the
    // dither flag for gradients (otherwise it will also apply to, for example,
    // images, which is not supported in Impeller).
    //
    // See https://github.com/flutter/flutter/issues/112498.
    if (color_source->isGradient()) {
      // Originates from `dart:ui#Paint.enableDithering`.
      auto user_specified_dither = paint.isDither();
      sk_paint.setDither(user_specified_dither);
    }
    sk_paint.setShader(ToSk(color_source));
  }

  sk_paint.setMaskFilter(ToSk(paint.getMaskFilterPtr()));
  sk_paint.setPathEffect(ToSk(paint.getPathEffectPtr()));

  return sk_paint;
}

sk_sp<SkShader> ToSk(const DlColorSource* source) {
  if (!source) {
    return nullptr;
  }
  static auto ToSkColors = [](const DlGradientColorSourceBase* gradient) {
    return reinterpret_cast<const SkColor*>(gradient->colors());
  };
  switch (source->type()) {
    case DlColorSourceType::kColor: {
      const DlColorColorSource* color_source = source->asColor();
      FML_DCHECK(color_source != nullptr);
      return SkShaders::Color(ToSk(color_source->color()));
    }
    case DlColorSourceType::kImage: {
      const DlImageColorSource* image_source = source->asImage();
      FML_DCHECK(image_source != nullptr);
      auto image = image_source->image();
      if (!image || !image->skia_image()) {
        return nullptr;
      }
      return image->skia_image()->makeShader(
          ToSk(image_source->horizontal_tile_mode()),
          ToSk(image_source->vertical_tile_mode()),
          ToSk(image_source->sampling()), image_source->matrix_ptr());
    }
    case DlColorSourceType::kLinearGradient: {
      const DlLinearGradientColorSource* linear_source =
          source->asLinearGradient();
      FML_DCHECK(linear_source != nullptr);
      SkPoint pts[] = {linear_source->start_point(),
                       linear_source->end_point()};
      return SkGradientShader::MakeLinear(
          pts, ToSkColors(linear_source), linear_source->stops(),
          linear_source->stop_count(), ToSk(linear_source->tile_mode()), 0,
          linear_source->matrix_ptr());
    }
    case DlColorSourceType::kRadialGradient: {
      const DlRadialGradientColorSource* radial_source =
          source->asRadialGradient();
      FML_DCHECK(radial_source != nullptr);
      return SkGradientShader::MakeRadial(
          radial_source->center(), radial_source->radius(),
          ToSkColors(radial_source), radial_source->stops(),
          radial_source->stop_count(), ToSk(radial_source->tile_mode()), 0,
          radial_source->matrix_ptr());
    }
    case DlColorSourceType::kConicalGradient: {
      const DlConicalGradientColorSource* conical_source =
          source->asConicalGradient();
      FML_DCHECK(conical_source != nullptr);
      return SkGradientShader::MakeTwoPointConical(
          conical_source->start_center(), conical_source->start_radius(),
          conical_source->end_center(), conical_source->end_radius(),
          ToSkColors(conical_source), conical_source->stops(),
          conical_source->stop_count(), ToSk(conical_source->tile_mode()), 0,
          conical_source->matrix_ptr());
    }
    case DlColorSourceType::kSweepGradient: {
      const DlSweepGradientColorSource* sweep_source =
          source->asSweepGradient();
      FML_DCHECK(sweep_source != nullptr);
      return SkGradientShader::MakeSweep(
          sweep_source->center().x(), sweep_source->center().y(),
          ToSkColors(sweep_source), sweep_source->stops(),
          sweep_source->stop_count(), ToSk(sweep_source->tile_mode()),
          sweep_source->start(), sweep_source->end(), 0,
          sweep_source->matrix_ptr());
    }
    case DlColorSourceType::kRuntimeEffect: {
      const DlRuntimeEffectColorSource* runtime_source =
          source->asRuntimeEffect();
      FML_DCHECK(runtime_source != nullptr);
      auto runtime_effect = runtime_source->runtime_effect();
      if (!runtime_effect || !runtime_effect->skia_runtime_effect()) {
        return nullptr;
      }

      auto samplers = runtime_source->samplers();
      std::vector<sk_sp<SkShader>> sk_samplers(samplers.size());
      for (size_t i = 0; i < samplers.size(); i++) {
        auto sampler = samplers[i];
        if (sampler == nullptr) {
          return nullptr;
        }
        sk_samplers[i] = ToSk(sampler);
      }

      auto uniform_data = runtime_source->uniform_data();
      auto ref = new std::shared_ptr<std::vector<uint8_t>>(uniform_data);
      auto sk_uniform_data = SkData::MakeWithProc(
          uniform_data->data(), uniform_data->size(),
          [](const void* ptr, void* context) {
            delete reinterpret_cast<std::shared_ptr<std::vector<uint8_t>>*>(
                context);
          },
          ref);

      return runtime_effect->skia_runtime_effect()->makeShader(
          sk_uniform_data, sk_samplers.data(), sk_samplers.size());
    }
#ifdef IMPELLER_ENABLE_3D
    case DlColorSourceType::kScene: {
      return nullptr;
    }
#endif  // IMPELLER_ENABLE_3D
  }
}

sk_sp<SkImageFilter> ToSk(const DlImageFilter* filter) {
  if (!filter) {
    return nullptr;
  }
  switch (filter->type()) {
    case DlImageFilterType::kBlur: {
      const DlBlurImageFilter* blur_filter = filter->asBlur();
      FML_DCHECK(blur_filter != nullptr);
      return SkImageFilters::Blur(blur_filter->sigma_x(),
                                  blur_filter->sigma_y(),
                                  ToSk(blur_filter->tile_mode()), nullptr);
    }
    case DlImageFilterType::kDilate: {
      const DlDilateImageFilter* dilate_filter = filter->asDilate();
      FML_DCHECK(dilate_filter != nullptr);
      return SkImageFilters::Dilate(dilate_filter->radius_x(),
                                    dilate_filter->radius_y(), nullptr);
    }
    case DlImageFilterType::kErode: {
      const DlErodeImageFilter* erode_filter = filter->asErode();
      FML_DCHECK(erode_filter != nullptr);
      return SkImageFilters::Erode(erode_filter->radius_x(),
                                   erode_filter->radius_y(), nullptr);
    }
    case DlImageFilterType::kMatrix: {
      const DlMatrixImageFilter* matrix_filter = filter->asMatrix();
      FML_DCHECK(matrix_filter != nullptr);
      return SkImageFilters::MatrixTransform(
          matrix_filter->matrix(), ToSk(matrix_filter->sampling()), nullptr);
    }
    case DlImageFilterType::kCompose: {
      const DlComposeImageFilter* compose_filter = filter->asCompose();
      FML_DCHECK(compose_filter != nullptr);
      return SkImageFilters::Compose(ToSk(compose_filter->outer()),
                                     ToSk(compose_filter->inner()));
    }
    case DlImageFilterType::kColorFilter: {
      const DlColorFilterImageFilter* cf_filter = filter->asColorFilter();
      FML_DCHECK(cf_filter != nullptr);
      return SkImageFilters::ColorFilter(ToSk(cf_filter->color_filter()),
                                         nullptr);
    }
    case DlImageFilterType::kLocalMatrix: {
      const DlLocalMatrixImageFilter* lm_filter = filter->asLocalMatrix();
      FML_DCHECK(lm_filter != nullptr);
      sk_sp<SkImageFilter> skia_filter = ToSk(lm_filter->image_filter());
      // The image_filter property itself might have been null, or the
      // construction of the SkImageFilter might be optimized to null
      // for any number of reasons. In any case, if the filter is null
      // or optimizaed away, let's then optimize away this local matrix
      // case by returning null.
      if (!skia_filter) {
        return nullptr;
      }
      return skia_filter->makeWithLocalMatrix(lm_filter->matrix());
    }
  }
}

sk_sp<SkColorFilter> ToSk(const DlColorFilter* filter) {
  if (!filter) {
    return nullptr;
  }
  switch (filter->type()) {
    case DlColorFilterType::kBlend: {
      const DlBlendColorFilter* blend_filter = filter->asBlend();
      FML_DCHECK(blend_filter != nullptr);
      return SkColorFilters::Blend(ToSk(blend_filter->color()),
                                   ToSk(blend_filter->mode()));
    }
    case DlColorFilterType::kMatrix: {
      const DlMatrixColorFilter* matrix_filter = filter->asMatrix();
      FML_DCHECK(matrix_filter != nullptr);
      float matrix[20];
      matrix_filter->get_matrix(matrix);
      return SkColorFilters::Matrix(matrix);
    }
    case DlColorFilterType::kSrgbToLinearGamma: {
      return SkColorFilters::SRGBToLinearGamma();
    }
    case DlColorFilterType::kLinearToSrgbGamma: {
      return SkColorFilters::LinearToSRGBGamma();
    }
  }
}

sk_sp<SkMaskFilter> ToSk(const DlMaskFilter* filter) {
  if (!filter) {
    return nullptr;
  }
  switch (filter->type()) {
    case DlMaskFilterType::kBlur: {
      const DlBlurMaskFilter* blur_filter = filter->asBlur();
      FML_DCHECK(blur_filter != nullptr);
      return SkMaskFilter::MakeBlur(ToSk(blur_filter->style()),
                                    blur_filter->sigma(),
                                    blur_filter->respectCTM());
    }
  }
}

sk_sp<SkPathEffect> ToSk(const DlPathEffect* effect) {
  if (!effect) {
    return nullptr;
  }
  switch (effect->type()) {
    case DlPathEffectType::kDash: {
      const DlDashPathEffect* dash_effect = effect->asDash();
      FML_DCHECK(dash_effect != nullptr);
      return SkDashPathEffect::Make(dash_effect->intervals(),
                                    dash_effect->count(), dash_effect->phase());
    }
  }
}

sk_sp<SkVertices> ToSk(const DlVertices* vertices) {
  const SkColor* sk_colors =
      reinterpret_cast<const SkColor*>(vertices->colors());
  return SkVertices::MakeCopy(ToSk(vertices->mode()), vertices->vertex_count(),
                              vertices->vertices(),
                              vertices->texture_coordinates(), sk_colors,
                              vertices->index_count(), vertices->indices());
}

}  // namespace flutter
