// 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.

#ifndef FLUTTER_FLOW_LAYERS_CLIP_SHAPE_LAYER_H_
#define FLUTTER_FLOW_LAYERS_CLIP_SHAPE_LAYER_H_

#include "flutter/flow/layers/container_layer.h"
#include "flutter/flow/paint_utils.h"

namespace flutter {

template <class T>
class ClipShapeLayer : public ContainerLayer {
 public:
  using ClipShape = T;
  ClipShapeLayer(const ClipShape& clip_shape, Clip clip_behavior)
      : clip_shape_(clip_shape), clip_behavior_(clip_behavior) {
    FML_DCHECK(clip_behavior != Clip::none);
  }

  void Diff(DiffContext* context, const Layer* old_layer) override {
    DiffContext::AutoSubtreeRestore subtree(context);
    auto* prev = static_cast<const ClipShapeLayer<ClipShape>*>(old_layer);
    if (!context->IsSubtreeDirty()) {
      FML_DCHECK(prev);
      if (clip_behavior_ != prev->clip_behavior_ ||
          clip_shape_ != prev->clip_shape_) {
        context->MarkSubtreeDirty(context->GetOldLayerPaintRegion(old_layer));
      }
    }
    if (context->PushCullRect(clip_shape_bounds())) {
      DiffChildren(context, prev);
    }
    context->SetLayerPaintRegion(this, context->CurrentSubtreeRegion());
  }

  void Preroll(PrerollContext* context, const SkMatrix& matrix) override {
    SkRect previous_cull_rect = context->cull_rect;
    if (!context->cull_rect.intersect(clip_shape_bounds())) {
      context->cull_rect.setEmpty();
    }
    Layer::AutoPrerollSaveLayerState save =
        Layer::AutoPrerollSaveLayerState::Create(context, UsesSaveLayer());
    OnMutatorsStackPushClipShape(context->mutators_stack);

    // Collect inheritance information on our children in Preroll so that
    // we can pass it along by default.
    context->subtree_can_inherit_opacity = true;

    SkRect child_paint_bounds = SkRect::MakeEmpty();
    PrerollChildren(context, matrix, &child_paint_bounds);
    if (child_paint_bounds.intersect(clip_shape_bounds())) {
      set_paint_bounds(child_paint_bounds);
    }

    // If we use a SaveLayer then we can accept opacity on behalf
    // of our children and apply it in the saveLayer.
    if (UsesSaveLayer()) {
      context->subtree_can_inherit_opacity = true;
    }

    context->mutators_stack.Pop();
    context->cull_rect = previous_cull_rect;
  }

  void Paint(PaintContext& context) const override {
    FML_DCHECK(needs_painting(context));

    SkAutoCanvasRestore save(context.internal_nodes_canvas, true);
    OnCanvasClipShape(context.internal_nodes_canvas);

    if (!UsesSaveLayer()) {
      PaintChildren(context);
      return;
    }

    AutoCachePaint cache_paint(context);
    TRACE_EVENT0("flutter", "Canvas::saveLayer");
    context.internal_nodes_canvas->saveLayer(paint_bounds(),
                                             cache_paint.paint());

    PaintChildren(context);

    context.internal_nodes_canvas->restore();
    if (context.checkerboard_offscreen_layers) {
      DrawCheckerboard(context.internal_nodes_canvas, paint_bounds());
    }
  }

  bool UsesSaveLayer() const {
    return clip_behavior_ == Clip::antiAliasWithSaveLayer;
  }

 protected:
  virtual const SkRect& clip_shape_bounds() const = 0;
  virtual void OnMutatorsStackPushClipShape(MutatorsStack& mutators_stack) = 0;
  virtual void OnCanvasClipShape(SkCanvas* canvas) const = 0;
  virtual ~ClipShapeLayer() = default;

  const ClipShape& clip_shape() const { return clip_shape_; }
  Clip clip_behavior() const { return clip_behavior_; }

 private:
  const ClipShape clip_shape_;
  Clip clip_behavior_;

  FML_DISALLOW_COPY_AND_ASSIGN(ClipShapeLayer);
};

}  // namespace flutter

#endif  // FLUTTER_FLOW_LAYERS_CLIP_SHAPE_LAYER_H_
