/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkRecordDraw_DEFINED
#define SkRecordDraw_DEFINED

#include "include/core/SkBBHFactory.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkMatrix.h"
#include "src/core/SkBigPicture.h"
#include "src/core/SkRecord.h"

class SkDrawable;
class SkLayerInfo;

// Calculate conservative identity space bounds for each op in the record.
void SkRecordFillBounds(const SkRect& cullRect, const SkRecord&,
                        SkRect bounds[], SkBBoxHierarchy::Metadata[]);

// SkRecordFillBounds(), and gathers information about saveLayers and stores it for later
// use (e.g., layer hoisting). The gathered information is sufficient to determine
// where each saveLayer will land and which ops in the picture it represents.
void SkRecordComputeLayers(const SkRect& cullRect, const SkRecord&, SkRect bounds[],
                           const SkBigPicture::SnapshotArray*, SkLayerInfo* data);

// Draw an SkRecord into an SkCanvas.  A convenience wrapper around SkRecords::Draw.
void SkRecordDraw(const SkRecord&, SkCanvas*, SkPicture const* const drawablePicts[],
                  SkDrawable* const drawables[], int drawableCount,
                  const SkBBoxHierarchy*, SkPicture::AbortCallback*);

// Draw a portion of an SkRecord into an SkCanvas.
// When drawing a portion of an SkRecord the CTM on the passed in canvas must be
// the composition of the replay matrix with the record-time CTM (for the portion
// of the record that is being replayed). For setMatrix calls to behave correctly
// the initialCTM parameter must set to just the replay matrix.
void SkRecordPartialDraw(const SkRecord&, SkCanvas*,
                         SkPicture const* const drawablePicts[], int drawableCount,
                         int start, int stop, const SkM44& initialCTM);

namespace SkRecords {

// This is an SkRecord visitor that will draw that SkRecord to an SkCanvas.
class Draw : SkNoncopyable {
public:
    explicit Draw(SkCanvas* canvas, SkPicture const* const drawablePicts[],
                  SkDrawable* const drawables[], int drawableCount,
                  const SkM44* initialCTM = nullptr)
        : fInitialCTM(initialCTM ? *initialCTM : canvas->getLocalToDevice())
        , fCanvas(canvas)
        , fDrawablePicts(drawablePicts)
        , fDrawables(drawables)
        , fDrawableCount(drawableCount)
    {}

    // This operator calls methods on the |canvas|. The various draw() wrapper
    // methods around SkCanvas are defined by the DRAW() macro in
    // SkRecordDraw.cpp.
    template <typename T> void operator()(const T& r) {
        this->draw(r);
    }

protected:
    SkPicture const* const* drawablePicts() const { return fDrawablePicts; }
    int drawableCount() const { return fDrawableCount; }

private:
    // No base case, so we'll be compile-time checked that we implement all possibilities.
    template <typename T> void draw(const T&);

    const SkM44 fInitialCTM;
    SkCanvas* fCanvas;
    SkPicture const* const* fDrawablePicts;
    SkDrawable* const* fDrawables;
    int fDrawableCount;
};

}  // namespace SkRecords

#endif//SkRecordDraw_DEFINED
