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

#include "BisectSlide.h"

#include "SkOSPath.h"
#include "SkPicture.h"
#include "SkStream.h"

#ifdef SK_XML
#include "SkDOM.h"
#include "../experimental/svg/model/SkSVGDOM.h"
#endif

sk_sp<BisectSlide> BisectSlide::Create(const char filepath[]) {
    SkFILEStream stream(filepath);
    if (!stream.isValid()) {
        SkDebugf("BISECT: invalid input file at \"%s\"\n", filepath);
        return nullptr;
    }

    sk_sp<BisectSlide> bisect(new BisectSlide(filepath));
    if (bisect->fFilePath.endsWith(".svg")) {
#ifdef SK_XML
        SkDOM xml;
        if (!xml.build(stream)) {
            SkDebugf("BISECT: XML parsing failed: \"%s\"\n", filepath);
            return nullptr;
        }
        sk_sp<SkSVGDOM> svg = SkSVGDOM::MakeFromDOM(xml);
        if (!svg) {
            SkDebugf("BISECT: couldn't load svg at \"%s\"\n", filepath);
            return nullptr;
        }
        svg->setContainerSize(SkSize::Make(bisect->getDimensions()));
        svg->render(bisect.get());
#else
        return nullptr;
#endif
    } else {
        sk_sp<SkPicture> skp = SkPicture::MakeFromStream(&stream);
        if (!skp) {
            SkDebugf("BISECT: couldn't load skp at \"%s\"\n", filepath);
            return nullptr;
        }
        skp->playback(bisect.get());
    }

    return bisect;
}

BisectSlide::BisectSlide(const char filepath[])
        : SkCanvas(4096, 4096, nullptr)
        , fFilePath(filepath) {
    const char* basename = strrchr(fFilePath.c_str(), SkOSPath::SEPARATOR);
    fName.printf("BISECT_%s", basename ? basename + 1 : fFilePath.c_str());
}

// Called through SkPicture::playback only during creation.
void BisectSlide::onDrawPath(const SkPath& path, const SkPaint& paint) {
    SkRect bounds;
    SkIRect ibounds;
    this->getTotalMatrix().mapRect(&bounds, path.getBounds());
    bounds.roundOut(&ibounds);
    fDrawBounds.join(ibounds);
    fFoundPaths.push_back() = {path, paint, this->getTotalMatrix()};
}

bool BisectSlide::onChar(SkUnichar c) {
    switch (c) {
        case 'X':
            if (!fTossedPaths.empty()) {
                SkTSwap(fFoundPaths, fTossedPaths);
                if ('X' == fTrail.back()) {
                    fTrail.pop_back();
                } else {
                    fTrail.push_back('X');
                }
            }
            return true;

        case 'x':
            if (fFoundPaths.count() > 1) {
                int midpt = (fFoundPaths.count() + 1) / 2;
                fPathHistory.emplace(fFoundPaths, fTossedPaths);
                fTossedPaths.reset(fFoundPaths.begin() + midpt, fFoundPaths.count() - midpt);
                fFoundPaths.resize_back(midpt);
                fTrail.push_back('x');
            }
            return true;

        case 'Z': {
            if (!fPathHistory.empty()) {
                fFoundPaths = fPathHistory.top().first;
                fTossedPaths = fPathHistory.top().second;
                fPathHistory.pop();
                char ch;
                do {
                    ch = fTrail.back();
                    fTrail.pop_back();
                } while (ch != 'x');
            }
            return true;
        }

        case 'D':
            SkDebugf("viewer --bisect %s", fFilePath.c_str());
            if (!fTrail.empty()) {
                SkDebugf(" ");
                for (char ch : fTrail) {
                    SkDebugf("%c", ch);
                }
            }
            SkDebugf("\n");
            for (const FoundPath& foundPath : fFoundPaths) {
                foundPath.fPath.dump();
            }
            return true;
    }

    return false;
}

void BisectSlide::draw(SkCanvas* canvas) {
    SkAutoCanvasRestore acr(canvas, true);
    canvas->translate(-fDrawBounds.left(), -fDrawBounds.top());

    for (const FoundPath& path : fFoundPaths) {
        SkAutoCanvasRestore acr(canvas, true);
        canvas->concat(path.fViewMatrix);
        canvas->drawPath(path.fPath, path.fPaint);
    }
}
