/*
 *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef MODULES_DESKTOP_CAPTURE_DESKTOP_REGION_H_
#define MODULES_DESKTOP_CAPTURE_DESKTOP_REGION_H_

#include <stdint.h>

#include <map>
#include <vector>

#include "modules/desktop_capture/desktop_geometry.h"
#include "rtc_base/system/rtc_export.h"

namespace webrtc {

// DesktopRegion represents a region of the screen or window.
//
// Internally each region is stored as a set of rows where each row contains one
// or more rectangles aligned vertically.
class RTC_EXPORT DesktopRegion {
 private:
  // The following private types need to be declared first because they are used
  // in the public Iterator.

  // RowSpan represents a horizontal span withing a single row.
  struct RowSpan {
    RowSpan(int32_t left, int32_t right);

    // Used by std::vector<>.
    bool operator==(const RowSpan& that) const {
      return left == that.left && right == that.right;
    }

    int32_t left;
    int32_t right;
  };

  typedef std::vector<RowSpan> RowSpanSet;

  // Row represents a single row of a region. A row is set of rectangles that
  // have the same vertical position.
  struct Row {
    Row(const Row&);
    Row(Row&&);
    Row(int32_t top, int32_t bottom);
    ~Row();

    int32_t top;
    int32_t bottom;

    RowSpanSet spans;
  };

  // Type used to store list of rows in the region. The bottom position of row
  // is used as the key so that rows are always ordered by their position. The
  // map stores pointers to make Translate() more efficient.
  typedef std::map<int, Row*> Rows;

 public:
  // Iterator that can be used to iterate over rectangles of a DesktopRegion.
  // The region must not be mutated while the iterator is used.
  class RTC_EXPORT Iterator {
   public:
    explicit Iterator(const DesktopRegion& target);
    ~Iterator();

    bool IsAtEnd() const;
    void Advance();

    const DesktopRect& rect() const { return rect_; }

   private:
    const DesktopRegion& region_;

    // Updates |rect_| based on the current |row_| and |row_span_|. If
    // |row_span_| matches spans on consecutive rows then they are also merged
    // into |rect_|, to generate more efficient output.
    void UpdateCurrentRect();

    Rows::const_iterator row_;
    Rows::const_iterator previous_row_;
    RowSpanSet::const_iterator row_span_;
    DesktopRect rect_;
  };

  DesktopRegion();
  explicit DesktopRegion(const DesktopRect& rect);
  DesktopRegion(const DesktopRect* rects, int count);
  DesktopRegion(const DesktopRegion& other);
  ~DesktopRegion();

  DesktopRegion& operator=(const DesktopRegion& other);

  bool is_empty() const { return rows_.empty(); }

  bool Equals(const DesktopRegion& region) const;

  // Reset the region to be empty.
  void Clear();

  // Reset region to contain just |rect|.
  void SetRect(const DesktopRect& rect);

  // Adds specified rect(s) or region to the region.
  void AddRect(const DesktopRect& rect);
  void AddRects(const DesktopRect* rects, int count);
  void AddRegion(const DesktopRegion& region);

  // Finds intersection of two regions and stores them in the current region.
  void Intersect(const DesktopRegion& region1, const DesktopRegion& region2);

  // Same as above but intersects content of the current region with |region|.
  void IntersectWith(const DesktopRegion& region);

  // Clips the region by the |rect|.
  void IntersectWith(const DesktopRect& rect);

  // Subtracts |region| from the current content of the region.
  void Subtract(const DesktopRegion& region);

  // Subtracts |rect| from the current content of the region.
  void Subtract(const DesktopRect& rect);

  // Adds (dx, dy) to the position of the region.
  void Translate(int32_t dx, int32_t dy);

  void Swap(DesktopRegion* region);

 private:
  // Comparison functions used for std::lower_bound(). Compare left or right
  // edges withs a given |value|.
  static bool CompareSpanLeft(const RowSpan& r, int32_t value);
  static bool CompareSpanRight(const RowSpan& r, int32_t value);

  // Adds a new span to the row, coalescing spans if necessary.
  static void AddSpanToRow(Row* row, int32_t left, int32_t right);

  // Returns true if the |span| exists in the given |row|.
  static bool IsSpanInRow(const Row& row, const RowSpan& rect);

  // Calculates the intersection of two sets of spans.
  static void IntersectRows(const RowSpanSet& set1,
                            const RowSpanSet& set2,
                            RowSpanSet* output);

  static void SubtractRows(const RowSpanSet& set_a,
                           const RowSpanSet& set_b,
                           RowSpanSet* output);

  // Merges |row| with the row above it if they contain the same spans. Doesn't
  // do anything if called with |row| set to rows_.begin() (i.e. first row of
  // the region). If the rows were merged |row| remains a valid iterator to the
  // merged row.
  void MergeWithPrecedingRow(Rows::iterator row);

  Rows rows_;
};

}  // namespace webrtc

#endif  // MODULES_DESKTOP_CAPTURE_DESKTOP_REGION_H_
