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

#include "include/core/SkMatrix.h"
#include "include/core/SkPictureRecorder.h"
#include "src/core/SkPictureData.h"
#include "src/core/SkPicturePlayback.h"
#include "src/core/SkPictureRecord.h"
#include "src/core/SkRecordDraw.h"
#include "src/core/SkRecordedDrawable.h"

void SkRecordedDrawable::onDraw(SkCanvas* canvas) {
    SkDrawable* const* drawables = nullptr;
    int drawableCount = 0;
    if (fDrawableList) {
        drawables = fDrawableList->begin();
        drawableCount = fDrawableList->count();
    }
    SkRecordDraw(*fRecord, canvas, nullptr, drawables, drawableCount, fBBH.get(), nullptr);
}

SkPicture* SkRecordedDrawable::onNewPictureSnapshot() {
    // TODO: should we plumb-down the BBHFactory and recordFlags from our host
    //       PictureRecorder?
    std::unique_ptr<SkBigPicture::SnapshotArray> pictList{
        fDrawableList ? fDrawableList->newDrawableSnapshot() : nullptr
    };

    size_t subPictureBytes = 0;
    for (int i = 0; pictList && i < pictList->count(); i++) {
        subPictureBytes += pictList->begin()[i]->approximateBytesUsed();
    }
    return new SkBigPicture(fBounds, fRecord, std::move(pictList), fBBH, subPictureBytes);
}

void SkRecordedDrawable::flatten(SkWriteBuffer& buffer) const {
    // Write the bounds.
    buffer.writeRect(fBounds);

    // Create an SkPictureRecord to record the draw commands.
    SkPictInfo info;
    SkPictureRecord pictureRecord(SkISize::Make(fBounds.width(), fBounds.height()), 0);

    // If the query contains the whole picture, don't bother with the bounding box hierarchy.
    SkBBoxHierarchy* bbh;
    if (pictureRecord.getLocalClipBounds().contains(fBounds)) {
        bbh = nullptr;
    } else {
        bbh = fBBH.get();
    }

    // Record the draw commands.
    pictureRecord.beginRecording();
    SkRecordDraw(*fRecord, &pictureRecord, nullptr, fDrawableList->begin(), fDrawableList->count(),
                bbh, nullptr);
    pictureRecord.endRecording();

    // Flatten the recorded commands and drawables.
    SkPictureData pictureData(pictureRecord, info);
    pictureData.flatten(buffer);
}

sk_sp<SkFlattenable> SkRecordedDrawable::CreateProc(SkReadBuffer& buffer) {
    // Read the bounds.
    SkRect bounds;
    buffer.readRect(&bounds);

    // Unflatten into a SkPictureData.
    SkPictInfo info;
    info.setVersion(buffer.getVersion());
    info.fCullRect = bounds;
    std::unique_ptr<SkPictureData> pictureData(SkPictureData::CreateFromBuffer(buffer, info));
    if (!pictureData) {
        return nullptr;
    }

    // Create a drawable.
    SkPicturePlayback playback(pictureData.get());
    SkPictureRecorder recorder;
    playback.draw(recorder.beginRecording(bounds), nullptr, &buffer);
    return recorder.finishRecordingAsDrawable();
}
