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

#include <math.h>
#include <optional>
#include <type_traits>

#include "flutter/display_list/dl_blend_mode.h"
#include "flutter/display_list/skia/dl_sk_conversions.h"
#include "flutter/fml/logging.h"

#include "third_party/skia/include/core/SkColorFilter.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

void DlSkPaintDispatchHelper::save_opacity(SkScalar child_opacity) {
  save_stack_.emplace_back(opacity_);
  set_opacity(child_opacity);
}
void DlSkPaintDispatchHelper::restore_opacity() {
  if (save_stack_.empty()) {
    return;
  }
  set_opacity(save_stack_.back().opacity);
  save_stack_.pop_back();
}

void DlSkPaintDispatchHelper::setAntiAlias(bool aa) {
  paint_.setAntiAlias(aa);
}
void DlSkPaintDispatchHelper::setInvertColors(bool invert) {
  invert_colors_ = invert;
  paint_.setColorFilter(makeColorFilter());
}
void DlSkPaintDispatchHelper::setStrokeCap(DlStrokeCap cap) {
  paint_.setStrokeCap(ToSk(cap));
}
void DlSkPaintDispatchHelper::setStrokeJoin(DlStrokeJoin join) {
  paint_.setStrokeJoin(ToSk(join));
}
void DlSkPaintDispatchHelper::setDrawStyle(DlDrawStyle style) {
  paint_.setStyle(ToSk(style));
}
void DlSkPaintDispatchHelper::setStrokeWidth(SkScalar width) {
  paint_.setStrokeWidth(width);
}
void DlSkPaintDispatchHelper::setStrokeMiter(SkScalar limit) {
  paint_.setStrokeMiter(limit);
}
void DlSkPaintDispatchHelper::setColor(DlColor color) {
  current_color_ = ToSk(color);
  paint_.setColor(ToSk(color));
  if (has_opacity()) {
    paint_.setAlphaf(paint_.getAlphaf() * opacity());
  }
}
void DlSkPaintDispatchHelper::setBlendMode(DlBlendMode mode) {
  paint_.setBlendMode(ToSk(mode));
}
void DlSkPaintDispatchHelper::setColorSource(const DlColorSource* source) {
  // On the Impeller backend, we only support dithering of *gradients*, and
  // so we need to set the dither flag whenever we render a gradient.
  //
  // In this method we can determine whether or not the source is a gradient,
  // but we don't have the other half of the information which is what
  // rendering op is being performed. So, we simply record whether the
  // source is a gradient here and let the |paint()| method figure out
  // the rest (i.e. whether the color source will be used).
  color_source_gradient_ = source && source->isGradient();
  paint_.setShader(ToSk(source));
}
void DlSkPaintDispatchHelper::setImageFilter(const DlImageFilter* filter) {
  paint_.setImageFilter(ToSk(filter));
}
void DlSkPaintDispatchHelper::setColorFilter(const DlColorFilter* filter) {
  sk_color_filter_ = ToSk(filter);
  paint_.setColorFilter(makeColorFilter());
}
void DlSkPaintDispatchHelper::setPathEffect(const DlPathEffect* effect) {
  paint_.setPathEffect(ToSk(effect));
}
void DlSkPaintDispatchHelper::setMaskFilter(const DlMaskFilter* filter) {
  paint_.setMaskFilter(ToSk(filter));
}

sk_sp<SkColorFilter> DlSkPaintDispatchHelper::makeColorFilter() const {
  if (!invert_colors_) {
    return sk_color_filter_;
  }
  sk_sp<SkColorFilter> invert_filter =
      SkColorFilters::Matrix(kInvertColorMatrix);
  if (sk_color_filter_) {
    invert_filter = invert_filter->makeComposed(sk_color_filter_);
  }
  return invert_filter;
}

}  // namespace flutter
