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

part of ui;

enum PointMode {
  points,
  lines,
  polygon,
}

enum ClipOp {
  difference,
  intersect,
}

enum VertexMode {
  triangles,
  triangleStrip,
  triangleFan,
}

class Vertices {
  factory Vertices(
    VertexMode mode,
    List<Offset> positions, {
    List<Offset>? textureCoordinates,
    List<Color>? colors,
    List<int>? indices,
  }) {
    if (engine.useCanvasKit) {
      return engine.CkVertices(
        mode,
        positions,
        textureCoordinates: textureCoordinates,
        colors: colors,
        indices: indices,
      );
    }
    return engine.SurfaceVertices(
      mode,
      positions,
      colors: colors,
      indices: indices,
    );
  }
  factory Vertices.raw(
    VertexMode mode,
    Float32List positions, {
    Float32List? textureCoordinates,
    Int32List? colors,
    Uint16List? indices,
  }) {
    if (engine.useCanvasKit) {
      return engine.CkVertices.raw(
        mode,
        positions,
        textureCoordinates: textureCoordinates,
        colors: colors,
        indices: indices,
      );
    }
    return engine.SurfaceVertices.raw(
      mode,
      positions,
      colors: colors,
      indices: indices,
    );
  }
}

abstract class PictureRecorder {
  factory PictureRecorder() {
    if (engine.useCanvasKit) {
      return engine.CkPictureRecorder();
    } else {
      return engine.EnginePictureRecorder();
    }
  }
  bool get isRecording;
  Picture endRecording();
}

abstract class Canvas {
  factory Canvas(PictureRecorder recorder, [Rect? cullRect]) {
    if (engine.useCanvasKit) {
      return engine.CanvasKitCanvas(recorder, cullRect);
    } else {
      return engine.SurfaceCanvas(
          recorder as engine.EnginePictureRecorder, cullRect);
    }
  }
  void save();
  void saveLayer(Rect? bounds, Paint paint);
  void restore();
  int getSaveCount();
  void translate(double dx, double dy);
  void scale(double sx, [double? sy]);
  void rotate(double radians);
  void skew(double sx, double sy);
  void transform(Float64List matrix4);
  Float64List getTransform();
  void clipRect(Rect rect,
      {ClipOp clipOp = ClipOp.intersect, bool doAntiAlias = true});
  void clipRRect(RRect rrect, {bool doAntiAlias = true});
  void clipPath(Path path, {bool doAntiAlias = true});
  Rect getLocalClipBounds();
  Rect getDestinationClipBounds();
  void drawColor(Color color, BlendMode blendMode);
  void drawLine(Offset p1, Offset p2, Paint paint);
  void drawPaint(Paint paint);
  void drawRect(Rect rect, Paint paint);
  void drawRRect(RRect rrect, Paint paint);
  void drawDRRect(RRect outer, RRect inner, Paint paint);
  void drawOval(Rect rect, Paint paint);
  void drawCircle(Offset c, double radius, Paint paint);
  void drawArc(Rect rect, double startAngle, double sweepAngle, bool useCenter,
      Paint paint);
  void drawPath(Path path, Paint paint);
  void drawImage(Image image, Offset offset, Paint paint);
  void drawImageRect(Image image, Rect src, Rect dst, Paint paint);
  void drawImageNine(Image image, Rect center, Rect dst, Paint paint);
  void drawPicture(Picture picture);
  void drawParagraph(Paragraph paragraph, Offset offset);
  void drawPoints(PointMode pointMode, List<Offset> points, Paint paint);
  void drawRawPoints(PointMode pointMode, Float32List points, Paint paint);

  void drawVertices(Vertices vertices, BlendMode blendMode, Paint paint);
  void drawAtlas(
    Image atlas,
    List<RSTransform> transforms,
    List<Rect> rects,
    List<Color>? colors,
    BlendMode? blendMode,
    Rect? cullRect,
    Paint paint,
  );
  void drawRawAtlas(
    Image atlas,
    Float32List rstTransforms,
    Float32List rects,
    Int32List? colors,
    BlendMode? blendMode,
    Rect? cullRect,
    Paint paint,
  );
  void drawShadow(
    Path path,
    Color color,
    double elevation,
    bool transparentOccluder,
  );
}

abstract class Picture {
  Future<Image> toImage(int width, int height);
  Image toImageSync(int width, int height);
  void dispose();
  bool get debugDisposed;
  int get approximateBytesUsed;
}

enum PathFillType {
  nonZero,
  evenOdd,
}
// Must be kept in sync with SkPathOp

enum PathOperation {
  difference,
  intersect,
  union,
  xor,
  reverseDifference,
}

abstract class PictureRasterizationException implements Exception {
  String get message;
  StackTrace? stack;
}
