// 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/lib/ui/painting/paint.h"

#include "flutter/display_list/dl_builder.h"
#include "flutter/fml/logging.h"
#include "flutter/lib/ui/floating_point.h"
#include "flutter/lib/ui/painting/color_filter.h"
#include "flutter/lib/ui/painting/image_filter.h"
#include "flutter/lib/ui/painting/shader.h"
#include "third_party/skia/include/core/SkColorFilter.h"
#include "third_party/skia/include/core/SkImageFilter.h"
#include "third_party/skia/include/core/SkMaskFilter.h"
#include "third_party/skia/include/core/SkShader.h"
#include "third_party/skia/include/core/SkString.h"
#include "third_party/tonic/typed_data/dart_byte_data.h"
#include "third_party/tonic/typed_data/typed_list.h"

namespace flutter {

// Indices for 32bit values.
constexpr int kIsAntiAliasIndex = 0;
constexpr int kColorIndex = 1;
constexpr int kBlendModeIndex = 2;
constexpr int kStyleIndex = 3;
constexpr int kStrokeWidthIndex = 4;
constexpr int kStrokeCapIndex = 5;
constexpr int kStrokeJoinIndex = 6;
constexpr int kStrokeMiterLimitIndex = 7;
constexpr int kFilterQualityIndex = 8;
constexpr int kMaskFilterIndex = 9;
constexpr int kMaskFilterBlurStyleIndex = 10;
constexpr int kMaskFilterSigmaIndex = 11;
constexpr int kInvertColorIndex = 12;
constexpr size_t kDataByteCount = 52;  // 4 * (last index + 1)
static_assert(kDataByteCount == sizeof(uint32_t) * (kInvertColorIndex + 1),
              "kDataByteCount must match the size of the data array.");

// Indices for objects.
constexpr int kShaderIndex = 0;
constexpr int kColorFilterIndex = 1;
constexpr int kImageFilterIndex = 2;
constexpr int kObjectCount = 3;  // One larger than largest object index.

// Must be kept in sync with the default in painting.dart.
constexpr uint32_t kColorDefault = 0xFF000000;

// Must be kept in sync with the default in painting.dart.
constexpr uint32_t kBlendModeDefault =
    static_cast<uint32_t>(SkBlendMode::kSrcOver);

// Must be kept in sync with the default in painting.dart, and also with the
// default SkPaintDefaults_MiterLimit in Skia (which is not in a public header).
constexpr float kStrokeMiterLimitDefault = 4.0f;

// Must be kept in sync with the MaskFilter private constants in painting.dart.
enum MaskFilterType { kNull, kBlur };

Paint::Paint(Dart_Handle paint_objects, Dart_Handle paint_data)
    : paint_objects_(paint_objects), paint_data_(paint_data) {}

const DlPaint* Paint::paint(DlPaint& paint,
                            const DisplayListAttributeFlags& flags) const {
  if (isNull()) {
    return nullptr;
  }
  tonic::DartByteData byte_data(paint_data_);
  FML_CHECK(byte_data.length_in_bytes() == kDataByteCount);

  const uint32_t* uint_data = static_cast<const uint32_t*>(byte_data.data());
  const float* float_data = static_cast<const float*>(byte_data.data());

  Dart_Handle values[kObjectCount];
  if (Dart_IsNull(paint_objects_)) {
    if (flags.applies_shader()) {
      paint.setColorSource(nullptr);
    }
    if (flags.applies_color_filter()) {
      paint.setColorFilter(nullptr);
    }
    if (flags.applies_image_filter()) {
      paint.setImageFilter(nullptr);
    }
  } else {
    FML_DCHECK(Dart_IsList(paint_objects_));
    intptr_t length = 0;
    Dart_ListLength(paint_objects_, &length);

    FML_CHECK(length == kObjectCount);
    if (Dart_IsError(
            Dart_ListGetRange(paint_objects_, 0, kObjectCount, values))) {
      return nullptr;
    }

    if (flags.applies_shader()) {
      Dart_Handle shader = values[kShaderIndex];
      if (Dart_IsNull(shader)) {
        paint.setColorSource(nullptr);
      } else {
        if (Shader* decoded = tonic::DartConverter<Shader*>::FromDart(shader)) {
          auto sampling =
              ImageFilter::SamplingFromIndex(uint_data[kFilterQualityIndex]);
          paint.setColorSource(decoded->shader(sampling));
        } else {
          paint.setColorSource(nullptr);
        }
      }
    }

    if (flags.applies_color_filter()) {
      Dart_Handle color_filter = values[kColorFilterIndex];
      if (Dart_IsNull(color_filter)) {
        paint.setColorFilter(nullptr);
      } else {
        ColorFilter* decoded =
            tonic::DartConverter<ColorFilter*>::FromDart(color_filter);
        paint.setColorFilter(decoded->filter());
      }
    }

    if (flags.applies_image_filter()) {
      Dart_Handle image_filter = values[kImageFilterIndex];
      if (Dart_IsNull(image_filter)) {
        paint.setImageFilter(nullptr);
      } else {
        ImageFilter* decoded =
            tonic::DartConverter<ImageFilter*>::FromDart(image_filter);
        paint.setImageFilter(decoded->filter());
      }
    }
  }

  if (flags.applies_anti_alias()) {
    paint.setAntiAlias(uint_data[kIsAntiAliasIndex] == 0);
  }

  if (flags.applies_alpha_or_color()) {
    uint32_t encoded_color = uint_data[kColorIndex];
    paint.setColor(DlColor(encoded_color ^ kColorDefault));
  }

  if (flags.applies_blend()) {
    uint32_t encoded_blend_mode = uint_data[kBlendModeIndex];
    uint32_t blend_mode = encoded_blend_mode ^ kBlendModeDefault;
    paint.setBlendMode(static_cast<DlBlendMode>(blend_mode));
  }

  if (flags.applies_style()) {
    uint32_t style = uint_data[kStyleIndex];
    paint.setDrawStyle(static_cast<DlDrawStyle>(style));
  }

  if (flags.is_stroked(paint.getDrawStyle())) {
    float stroke_width = float_data[kStrokeWidthIndex];
    paint.setStrokeWidth(stroke_width);

    float stroke_miter_limit = float_data[kStrokeMiterLimitIndex];
    paint.setStrokeMiter(stroke_miter_limit + kStrokeMiterLimitDefault);

    uint32_t stroke_cap = uint_data[kStrokeCapIndex];
    paint.setStrokeCap(static_cast<DlStrokeCap>(stroke_cap));

    uint32_t stroke_join = uint_data[kStrokeJoinIndex];
    paint.setStrokeJoin(static_cast<DlStrokeJoin>(stroke_join));
  }

  if (flags.applies_color_filter()) {
    paint.setInvertColors(uint_data[kInvertColorIndex] != 0);
  }

  if (flags.applies_path_effect()) {
    // The paint API exposed to Dart does not support path effects.  But other
    // operations such as text may set a path effect, which must be cleared.
    paint.setPathEffect(nullptr);
  }

  if (flags.applies_mask_filter()) {
    switch (uint_data[kMaskFilterIndex]) {
      case kNull:
        paint.setMaskFilter(nullptr);
        break;
      case kBlur:
        DlBlurStyle blur_style =
            static_cast<DlBlurStyle>(uint_data[kMaskFilterBlurStyleIndex]);
        double sigma = float_data[kMaskFilterSigmaIndex];
        paint.setMaskFilter(
            DlBlurMaskFilter::Make(blur_style, SafeNarrow(sigma)));
        break;
    }
  }

  return &paint;
}

void Paint::toDlPaint(DlPaint& paint) const {
  if (isNull()) {
    return;
  }
  FML_DCHECK(paint == DlPaint());

  tonic::DartByteData byte_data(paint_data_);
  FML_CHECK(byte_data.length_in_bytes() == kDataByteCount);

  const uint32_t* uint_data = static_cast<const uint32_t*>(byte_data.data());
  const float* float_data = static_cast<const float*>(byte_data.data());

  Dart_Handle values[kObjectCount];
  if (!Dart_IsNull(paint_objects_)) {
    FML_DCHECK(Dart_IsList(paint_objects_));
    intptr_t length = 0;
    Dart_ListLength(paint_objects_, &length);

    FML_CHECK(length == kObjectCount);
    if (Dart_IsError(
            Dart_ListGetRange(paint_objects_, 0, kObjectCount, values))) {
      return;
    }

    Dart_Handle shader = values[kShaderIndex];
    if (!Dart_IsNull(shader)) {
      if (Shader* decoded = tonic::DartConverter<Shader*>::FromDart(shader)) {
        auto sampling =
            ImageFilter::SamplingFromIndex(uint_data[kFilterQualityIndex]);
        paint.setColorSource(decoded->shader(sampling));
      }
    }

    Dart_Handle color_filter = values[kColorFilterIndex];
    if (!Dart_IsNull(color_filter)) {
      ColorFilter* decoded =
          tonic::DartConverter<ColorFilter*>::FromDart(color_filter);
      paint.setColorFilter(decoded->filter());
    }

    Dart_Handle image_filter = values[kImageFilterIndex];
    if (!Dart_IsNull(image_filter)) {
      ImageFilter* decoded =
          tonic::DartConverter<ImageFilter*>::FromDart(image_filter);
      paint.setImageFilter(decoded->filter());
    }
  }

  paint.setAntiAlias(uint_data[kIsAntiAliasIndex] == 0);

  uint32_t encoded_color = uint_data[kColorIndex];
  paint.setColor(DlColor(encoded_color ^ kColorDefault));

  uint32_t encoded_blend_mode = uint_data[kBlendModeIndex];
  uint32_t blend_mode = encoded_blend_mode ^ kBlendModeDefault;
  paint.setBlendMode(static_cast<DlBlendMode>(blend_mode));

  uint32_t style = uint_data[kStyleIndex];
  paint.setDrawStyle(static_cast<DlDrawStyle>(style));

  float stroke_width = float_data[kStrokeWidthIndex];
  paint.setStrokeWidth(stroke_width);

  float stroke_miter_limit = float_data[kStrokeMiterLimitIndex];
  paint.setStrokeMiter(stroke_miter_limit + kStrokeMiterLimitDefault);

  uint32_t stroke_cap = uint_data[kStrokeCapIndex];
  paint.setStrokeCap(static_cast<DlStrokeCap>(stroke_cap));

  uint32_t stroke_join = uint_data[kStrokeJoinIndex];
  paint.setStrokeJoin(static_cast<DlStrokeJoin>(stroke_join));

  paint.setInvertColors(uint_data[kInvertColorIndex] != 0);

  switch (uint_data[kMaskFilterIndex]) {
    case kNull:
      break;
    case kBlur:
      DlBlurStyle blur_style =
          static_cast<DlBlurStyle>(uint_data[kMaskFilterBlurStyleIndex]);
      float sigma = SafeNarrow(float_data[kMaskFilterSigmaIndex]);
      // Make could return a nullptr here if the values are NOP or
      // do not make sense. We could interpret that as if there was
      // no value passed from Dart at all (i.e. don't change the
      // setting in the paint object as in the kNull branch right
      // above here), but the maskfilter flag was actually set
      // indicating that the developer "tried" to set a mask, so we
      // should set the null value rather than do nothing.
      paint.setMaskFilter(DlBlurMaskFilter::Make(blur_style, sigma));
      break;
  }
}

}  // namespace flutter

namespace tonic {

flutter::Paint DartConverter<flutter::Paint>::FromArguments(
    Dart_NativeArguments args,
    int index,
    Dart_Handle& exception) {
  Dart_Handle paint_objects = Dart_GetNativeArgument(args, index);
  FML_DCHECK(!CheckAndHandleError(paint_objects));

  Dart_Handle paint_data = Dart_GetNativeArgument(args, index + 1);
  FML_DCHECK(!CheckAndHandleError(paint_data));

  return flutter::Paint(paint_objects, paint_data);
}

flutter::PaintData DartConverter<flutter::PaintData>::FromArguments(
    Dart_NativeArguments args,
    int index,
    Dart_Handle& exception) {
  return flutter::PaintData();
}

}  // namespace tonic
