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

#include <memory>

#include "tools/mdbviz/Model.h"

#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkPicture.h"
#include "include/core/SkStream.h"
#include "tools/debugger/DebugCanvas.h"

Model::Model() : fCurOp(0) {
    SkImageInfo ii = SkImageInfo::MakeN32Premul(1024, 1024);
    fBM.allocPixels(ii, 0);
}

Model::~Model() {
    this->resetOpList();
}

Model::ErrorCode Model::load(const char* filename) {
    std::unique_ptr<SkStream> stream = SkStream::MakeFromFile(filename);
    if (!stream) {
        return ErrorCode::kCouldntOpenFile;
    }
    sk_sp<SkPicture> pic(SkPicture::MakeFromStream(stream.get()));
    if (!pic) {
        return ErrorCode::kCouldntDecodeSKP;
    }

    {
        std::unique_ptr<DebugCanvas> temp(
                new DebugCanvas(SkScalarCeilToInt(pic->cullRect().width()),
                                SkScalarCeilToInt(pic->cullRect().height())));

        temp->setPicture(pic.get());
        pic->playback(temp.get());
        temp->setPicture(nullptr);
        this->resetOpList();
        temp->detachCommands(&fOps);
    }

    this->setCurOp(fOps.count()-1);

    return ErrorCode::kOK;
}

const char* Model::ErrorString(ErrorCode err) {
    static const char* kStrings[] = {
        "OK",
        "Couldn't read file",
        "Couldn't decode picture"
    };

    return kStrings[(int)err];
}

const char* Model::getOpName(int index) const {
    return DrawCommand::GetCommandString(fOps[index]->getType());
}

bool Model::isHierarchyPush(int index) const {
    DrawCommand::OpType type = fOps[index]->getType();

    return DrawCommand::kSave_OpType == type || DrawCommand::kSaveLayer_OpType == type ||
           DrawCommand::kBeginDrawPicture_OpType == type;
}

bool Model::isHierarchyPop(int index) const {
    DrawCommand::OpType type = fOps[index]->getType();

    return DrawCommand::kRestore_OpType == type || DrawCommand::kEndDrawPicture_OpType == type;
}

void Model::setCurOp(int curOp) {
    SkASSERT(curOp < fOps.count());

    if (curOp == fCurOp) {
        return; // the render state is already up to date
    }

    fCurOp = curOp;
    this->drawTo(fCurOp);
}

void Model::drawTo(int index) {
    SkASSERT(index < fOps.count());

    SkCanvas canvas(fBM);

    int saveCount = canvas.save();

    for (int i = 0; i <= index; ++i) {
        if (fOps[i]->isVisible()) {
            fOps[i]->execute(&canvas);
        }
    }

    canvas.restoreToCount(saveCount);
}

void Model::resetOpList() {
    for (int i = 0; i < fOps.count(); ++i) {
        delete fOps[i];
    }
    fOps.reset();
    fCurOp = 0;
}
