// 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_DISPLAY_LIST_GEOMETRY_DL_REGION_H_
#define FLUTTER_DISPLAY_LIST_GEOMETRY_DL_REGION_H_

#include "third_party/skia/include/core/SkRect.h"

#include <memory>
#include <vector>

namespace flutter {

/// Represents a region as a collection of non-overlapping rectangles.
/// Implements a subset of SkRegion functionality optimized for quickly
/// converting set of overlapping rectangles to non-overlapping rectangles.
class DlRegion {
 public:
  /// Creates an empty region.
  DlRegion() = default;

  /// Creates region by bulk adding the rectangles.
  /// Matches SkRegion::op(rect, SkRegion::kUnion_Op) behavior.
  explicit DlRegion(const std::vector<SkIRect>& rects);

  /// Creates region covering area of a rectangle.
  explicit DlRegion(const SkIRect& rect);

  DlRegion(const DlRegion&) = default;
  DlRegion(DlRegion&&) = default;

  DlRegion& operator=(const DlRegion&) = default;
  DlRegion& operator=(DlRegion&&) = default;

  /// Creates union region of region a and b.
  /// Matches SkRegion a; a.op(b, SkRegion::kUnion_Op) behavior.
  static DlRegion MakeUnion(const DlRegion& a, const DlRegion& b);

  /// Creates intersection region of region a and b.
  /// Matches SkRegion a; a.op(b, SkRegion::kIntersect_Op) behavior.
  static DlRegion MakeIntersection(const DlRegion& a, const DlRegion& b);

  /// Returns list of non-overlapping rectangles that cover current region.
  /// If |deband| is false, each span line will result in separate rectangles,
  /// closely matching SkRegion::Iterator behavior.
  /// If |deband| is true, matching rectangles from adjacent span lines will be
  /// merged into single rectangle.
  std::vector<SkIRect> getRects(bool deband = true) const;

  /// Returns maximum and minimum axis values of rectangles in this region.
  /// If region is empty returns SKIRect::MakeEmpty().
  const SkIRect& bounds() const { return bounds_; }

  /// Returns whether this region intersects with a rectangle.
  bool intersects(const SkIRect& rect) const;

  /// Returns whether this region intersects with another region.
  bool intersects(const DlRegion& region) const;

  /// Returns true if region is empty (contains no rectangles).
  bool isEmpty() const { return lines_.empty(); }

  /// Returns true if region is not empty and contains more than one rectangle.
  bool isComplex() const;

  /// Returns true if region can be represented by single rectangle or is
  /// empty.
  bool isSimple() const { return !isComplex(); }

 private:
  typedef std::uint32_t SpanChunkHandle;

  struct Span {
    int32_t left;
    int32_t right;

    Span() = default;
    Span(int32_t left, int32_t right) : left(left), right(right) {}
  };

  /// Holds spans for the region. Having custom allocated memory that doesn't
  /// do zero initialization every time the buffer gets resized improves
  /// performance measurably.
  class SpanBuffer {
   public:
    SpanBuffer() = default;
    SpanBuffer(const SpanBuffer&);
    SpanBuffer(SpanBuffer&& m);
    SpanBuffer& operator=(const SpanBuffer&);
    SpanBuffer& operator=(SpanBuffer&& m);

    void reserve(size_t capacity);
    size_t capacity() const { return capacity_; }

    SpanChunkHandle storeChunk(const Span* begin, const Span* end);
    size_t getChunkSize(SpanChunkHandle handle) const;
    void getSpans(SpanChunkHandle handle,
                  const DlRegion::Span*& begin,
                  const DlRegion::Span*& end) const;

    ~SpanBuffer();

   private:
    void setChunkSize(SpanChunkHandle handle, size_t size);

    size_t capacity_ = 0;
    size_t size_ = 0;

    // Spans for the region chunks. First span in each chunk contains the
    // chunk size.
    Span* spans_ = nullptr;
  };

  struct SpanLine {
    int32_t top;
    int32_t bottom;
    SpanChunkHandle chunk_handle;
  };

  void setRects(const std::vector<SkIRect>& rects);

  void appendLine(int32_t top,
                  int32_t bottom,
                  const Span* begin,
                  const Span* end);
  void appendLine(int32_t top,
                  int32_t bottom,
                  const SpanBuffer& buffer,
                  SpanChunkHandle handle) {
    const Span *begin, *end;
    buffer.getSpans(handle, begin, end);
    appendLine(top, bottom, begin, end);
  }

  typedef std::vector<Span> SpanVec;
  SpanLine makeLine(int32_t top, int32_t bottom, const SpanVec&);
  SpanLine makeLine(int32_t top,
                    int32_t bottom,
                    const Span* begin,
                    const Span* end);
  static size_t unionLineSpans(std::vector<Span>& res,
                               const SpanBuffer& a_buffer,
                               SpanChunkHandle a_handle,
                               const SpanBuffer& b_buffer,
                               SpanChunkHandle b_handle);
  static size_t intersectLineSpans(std::vector<Span>& res,
                                   const SpanBuffer& a_buffer,
                                   SpanChunkHandle a_handle,
                                   const SpanBuffer& b_buffer,
                                   SpanChunkHandle b_handle);

  bool spansEqual(SpanLine& line, const Span* begin, const Span* end) const;

  static bool spansIntersect(const Span* begin1,
                             const Span* end1,
                             const Span* begin2,
                             const Span* end2);

  static void getIntersectionIterators(
      const std::vector<SpanLine>& a_lines,
      const std::vector<SpanLine>& b_lines,
      std::vector<SpanLine>::const_iterator& a_it,
      std::vector<SpanLine>::const_iterator& b_it);

  std::vector<SpanLine> lines_;
  SkIRect bounds_ = SkIRect::MakeEmpty();
  SpanBuffer span_buffer_;
};

}  // namespace flutter

#endif  // FLUTTER_DISPLAY_LIST_GEOMETRY_DL_REGION_H_
