// 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"
#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();

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