// Copyright (c) 2010 The Chromium 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 PDF_PAINT_AGGREGATOR_H_
#define PDF_PAINT_AGGREGATOR_H_

#include <vector>

#include "ppapi/cpp/image_data.h"
#include "ppapi/cpp/rect.h"

// This class is responsible for aggregating multiple invalidation and scroll
// commands to produce a scroll and repaint sequence. You can use this manually
// to track your updates, but most applications will use the PaintManager to
// additionally handle the necessary callbacks on top of the PaintAggregator
// functionality.
//
// See http://code.google.com/p/ppapi/wiki/2DPaintingModel
class PaintAggregator {
 public:
  // Stores information about a rectangle that has finished painting.  The
  // PaintManager will paint it only when everything else on the screen is also
  // ready.
  struct ReadyRect {
    pp::Point offset;
    pp::Rect rect;
    pp::ImageData image_data;
  };

  struct PaintUpdate {
    PaintUpdate();
    PaintUpdate(const PaintUpdate& that);
    ~PaintUpdate();

    // True if there is a scroll applied. This indicates that the scroll delta
    // and scroll_rect are nonzero (just as a convenience).
    bool has_scroll;

    // The amount to scroll by. Either the X or Y may be nonzero to indicate a
    // scroll in that direction, but there will never be a scroll in both
    // directions at the same time (this will be converted to a paint of the
    // region instead).
    //
    // If there is no scroll, this will be (0, 0).
    pp::Point scroll_delta;

    // The rectangle that should be scrolled by the scroll_delta. If there is no
    // scroll, this will be (0, 0, 0, 0). We only track one scroll command at
    // once. If there are multiple ones, they will be converted to invalidates.
    pp::Rect scroll_rect;

    // A list of all the individual dirty rectangles. This is an aggregated list
    // of all invalidate calls. Different rectangles may be unified to produce a
    // minimal list with no overlap that is more efficient to paint. This list
    // also contains the region exposed by any scroll command.
    std::vector<pp::Rect> paint_rects;
  };

  PaintAggregator();

  // There is a PendingUpdate if InvalidateRect or ScrollRect were called and
  // ClearPendingUpdate was not called.
  bool HasPendingUpdate() const;
  void ClearPendingUpdate();

  PaintUpdate GetPendingUpdate();

  // Sets the result of a call to the plugin to paint.  This includes rects that
  // are finished painting (ready), and ones that are still in-progress
  // (pending).
  void SetIntermediateResults(const std::vector<ReadyRect>& ready,
                              const std::vector<pp::Rect>& pending);

  // Returns the rectangles that are ready to be painted.
  std::vector<ReadyRect> GetReadyRects() const;

  // The given rect should be repainted.
  void InvalidateRect(const pp::Rect& rect);

  // The given rect should be scrolled by the given amounts.
  void ScrollRect(const pp::Rect& clip_rect, const pp::Point& amount);

 private:
  // This structure is an internal version of PaintUpdate. It's different in
  // two respects:
  //
  //  - The scroll damange (area exposed by the scroll operation, if any) is
  //    maintained separately from the dirty rects generated by calling
  //    InvalidateRect. We need to know this distinction for some operations.
  //
  //  - The paint bounds union is computed on the fly so we don't have to keep
  //    a rectangle up to date as we do different operations.
  class InternalPaintUpdate {
   public:
    InternalPaintUpdate();
    ~InternalPaintUpdate();

    // Computes the rect damaged by scrolling within |scroll_rect| by
    // |scroll_delta|. This rect must be repainted. It is not included in
    // paint_rects.
    pp::Rect GetScrollDamage() const;

    pp::Point scroll_delta;
    pp::Rect scroll_rect;

    // Does not include the scroll damage rect unless
    // synthesized_scroll_damage_rect_ is set.
    std::vector<pp::Rect> paint_rects;

    // Rectangles that are finished painting.
    std::vector<ReadyRect> ready_rects;

    // Whether we have added the scroll damage rect to paint_rects yet or not.
    bool synthesized_scroll_damage_rect_;
  };

  pp::Rect ScrollPaintRect(const pp::Rect& paint_rect,
                           const pp::Point& amount) const;
  void InvalidateScrollRect();

  // Internal method used by InvalidateRect. If |check_scroll| is true, then the
  // method checks if there's a pending scroll and if so also invalidates |rect|
  // in the new scroll position.
  void InvalidateRectInternal(const pp::Rect& rect, bool check_scroll);

  InternalPaintUpdate update_;
};

#endif  // PDF_PAINT_AGGREGATOR_H_
