// 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/shell/common/canvas_spy.h"

namespace flutter {

CanvasSpy::CanvasSpy(SkCanvas* target_canvas) {
  SkISize canvas_size = target_canvas->getBaseLayerSize();
  n_way_canvas_ =
      std::make_unique<SkNWayCanvas>(canvas_size.width(), canvas_size.height());
  did_draw_canvas_ = std::make_unique<DidDrawCanvas>(canvas_size.width(),
                                                     canvas_size.height());
  n_way_canvas_->addCanvas(target_canvas);
  n_way_canvas_->addCanvas(did_draw_canvas_.get());
}

SkCanvas* CanvasSpy::GetSpyingCanvas() {
  return n_way_canvas_.get();
}

DidDrawCanvas::DidDrawCanvas(int width, int height)
    : SkCanvasVirtualEnforcer<SkNoDrawCanvas>(width, height) {}

DidDrawCanvas::~DidDrawCanvas() {}

void DidDrawCanvas::MarkDrawIfNonTransparentPaint(const SkPaint& paint) {
  bool isTransparent = paint.getAlpha() == 0;
  did_draw_ |= !isTransparent;
}

bool CanvasSpy::DidDrawIntoCanvas() {
  return did_draw_canvas_->DidDrawIntoCanvas();
}

bool DidDrawCanvas::DidDrawIntoCanvas() {
  return did_draw_;
}

void DidDrawCanvas::willSave() {}

SkCanvas::SaveLayerStrategy DidDrawCanvas::getSaveLayerStrategy(
    const SaveLayerRec& rec) {
  return kNoLayer_SaveLayerStrategy;
}

bool DidDrawCanvas::onDoSaveBehind(const SkRect* bounds) {
  return false;
}

void DidDrawCanvas::willRestore() {}

void DidDrawCanvas::didConcat(const SkMatrix& matrix) {}

void DidDrawCanvas::didConcat44(const SkM44&) {}

void DidDrawCanvas::didScale(SkScalar, SkScalar) {}

void DidDrawCanvas::didTranslate(SkScalar, SkScalar) {}

void DidDrawCanvas::didSetMatrix(const SkMatrix& matrix) {}

void DidDrawCanvas::onClipRect(const SkRect& rect,
                               SkClipOp op,
                               ClipEdgeStyle edgeStyle) {}

void DidDrawCanvas::onClipRRect(const SkRRect& rrect,
                                SkClipOp op,
                                ClipEdgeStyle edgeStyle) {}

void DidDrawCanvas::onClipPath(const SkPath& path,
                               SkClipOp op,
                               ClipEdgeStyle edgeStyle) {}

void DidDrawCanvas::onClipRegion(const SkRegion& deviceRgn, SkClipOp op) {}

void DidDrawCanvas::onDrawPaint(const SkPaint& paint) {
  MarkDrawIfNonTransparentPaint(paint);
}

void DidDrawCanvas::onDrawBehind(const SkPaint& paint) {
  MarkDrawIfNonTransparentPaint(paint);
}

void DidDrawCanvas::onDrawPoints(PointMode mode,
                                 size_t count,
                                 const SkPoint pts[],
                                 const SkPaint& paint) {
  MarkDrawIfNonTransparentPaint(paint);
}

void DidDrawCanvas::onDrawRect(const SkRect& rect, const SkPaint& paint) {
  MarkDrawIfNonTransparentPaint(paint);
}

void DidDrawCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) {
  MarkDrawIfNonTransparentPaint(paint);
}

void DidDrawCanvas::onDrawOval(const SkRect& rect, const SkPaint& paint) {
  MarkDrawIfNonTransparentPaint(paint);
}

void DidDrawCanvas::onDrawArc(const SkRect& rect,
                              SkScalar startAngle,
                              SkScalar sweepAngle,
                              bool useCenter,
                              const SkPaint& paint) {
  MarkDrawIfNonTransparentPaint(paint);
}

void DidDrawCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
  MarkDrawIfNonTransparentPaint(paint);
}

void DidDrawCanvas::onDrawDRRect(const SkRRect& outer,
                                 const SkRRect& inner,
                                 const SkPaint& paint) {
  MarkDrawIfNonTransparentPaint(paint);
}

void DidDrawCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
  MarkDrawIfNonTransparentPaint(paint);
}

void DidDrawCanvas::onDrawImage(const SkImage* image,
                                SkScalar left,
                                SkScalar top,
                                const SkPaint* paint) {
  did_draw_ = true;
}

void DidDrawCanvas::onDrawImageRect(const SkImage* image,
                                    const SkRect* src,
                                    const SkRect& dst,
                                    const SkPaint* paint,
                                    SrcRectConstraint constraint) {
  did_draw_ = true;
}

void DidDrawCanvas::onDrawImageNine(const SkImage* image,
                                    const SkIRect& center,
                                    const SkRect& dst,
                                    const SkPaint* paint) {
  did_draw_ = true;
}

void DidDrawCanvas::onDrawImageLattice(const SkImage* image,
                                       const Lattice& lattice,
                                       const SkRect& dst,
                                       const SkPaint* paint) {
  did_draw_ = true;
}

void DidDrawCanvas::onDrawTextBlob(const SkTextBlob* blob,
                                   SkScalar x,
                                   SkScalar y,
                                   const SkPaint& paint) {
  MarkDrawIfNonTransparentPaint(paint);
}

void DidDrawCanvas::onDrawPicture(const SkPicture* picture,
                                  const SkMatrix* matrix,
                                  const SkPaint* paint) {
  did_draw_ = true;
}

void DidDrawCanvas::onDrawDrawable(SkDrawable* drawable,
                                   const SkMatrix* matrix) {
  did_draw_ = true;
}

void DidDrawCanvas::onDrawVerticesObject(const SkVertices* vertices,
                                         SkBlendMode bmode,
                                         const SkPaint& paint) {
  MarkDrawIfNonTransparentPaint(paint);
}

void DidDrawCanvas::onDrawPatch(const SkPoint cubics[12],
                                const SkColor colors[4],
                                const SkPoint texCoords[4],
                                SkBlendMode bmode,
                                const SkPaint& paint) {
  MarkDrawIfNonTransparentPaint(paint);
}

void DidDrawCanvas::onDrawAtlas(const SkImage* image,
                                const SkRSXform xform[],
                                const SkRect tex[],
                                const SkColor colors[],
                                int count,
                                SkBlendMode bmode,
                                const SkRect* cull,
                                const SkPaint* paint) {
  did_draw_ = true;
}

void DidDrawCanvas::onDrawShadowRec(const SkPath& path,
                                    const SkDrawShadowRec& rec) {
  did_draw_ = true;
}

void DidDrawCanvas::onDrawAnnotation(const SkRect& rect,
                                     const char key[],
                                     SkData* data) {
  did_draw_ = true;
}

void DidDrawCanvas::onDrawEdgeAAQuad(const SkRect& rect,
                                     const SkPoint clip[4],
                                     SkCanvas::QuadAAFlags aa,
                                     const SkColor4f& color,
                                     SkBlendMode mode) {
  did_draw_ = true;
}

void DidDrawCanvas::onDrawEdgeAAImageSet(const ImageSetEntry set[],
                                         int count,
                                         const SkPoint dstClips[],
                                         const SkMatrix preViewMatrices[],
                                         const SkPaint* paint,
                                         SrcRectConstraint constraint) {
  did_draw_ = true;
}

void DidDrawCanvas::onFlush() {}

}  // namespace flutter
