/*
 * 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 "SampleCode.h"
#include "SkCanvas.h"
#include "SkCommandLineFlags.h"
#include "SkDOM.h"
#include "SkSVGDOM.h"
#include "SkOSPath.h"
#include "SkPath.h"
#include "SkPicture.h"
#include "SkStream.h"
#include <stack>

DEFINE_string(pathfinderTrail, "", "List of keystrokes to execute upon loading a pathfinder.");

/**
 * This is a simple utility designed to extract the paths from an SKP file and then isolate a single
 * one of them. Use the 'x' and 'X' keys to guide a binary search:
 *
 *   'x': Throw out half the paths.
 *   'X': Toggle which half gets tossed and which half is kept.
 *   'Z': Back up one level.
 *   'D': Dump the path.
 */
class PathFinderView : public SampleView, public SkCanvas {
public:
    PathFinderView(const char name[] = nullptr)
        : SkCanvas(4096, 4096, nullptr)
        , fFilename(name) {
        SkFILEStream stream(fFilename.c_str());
        if (!stream.isValid()) {
            SkDebugf("invalid input file at \"%s\"\n", fFilename.c_str());
            return;
        }
        if (fFilename.endsWith(".svg")) {
            SkDOM xml;
            if (!xml.build(stream)) {
                SkDebugf("XML parsing failed: \"%s\"\n", fFilename.c_str());
                return;
            }
            sk_sp<SkSVGDOM> svg = SkSVGDOM::MakeFromDOM(xml);
            if (!svg) {
                SkDebugf("couldn't load svg at \"%s\"\n", fFilename.c_str());
                return;
            }
            svg->setContainerSize(SkSize::Make(500, 500));
            svg->render(this);
        } else {
            sk_sp<SkPicture> pic = SkPicture::MakeFromStream(&stream);
            if (!pic) {
                SkDebugf("couldn't load skp at \"%s\"\n", fFilename.c_str());
                return;
            }
            pic->playback(this);
        }
        for (int i = 0; i < FLAGS_pathfinderTrail.count(); ++i) {
            const char* key = FLAGS_pathfinderTrail[i];
            while (*key) {
                this->handleKeystroke(*key++);
            }
        }
    }

    ~PathFinderView() override {}

private:
    // Called through SkPicture::playback during construction.
    void onDrawPath(const SkPath& path, const SkPaint& paint) override {
        fPaths.push_back() = {path, paint, this->getTotalMatrix()};
    }

    // overrides from SkEventSink
    bool onQuery(SkEvent* evt) override {
        if (SampleCode::TitleQ(*evt)) {
            SkString name("PATHFINDER:");
            const char* basename = strrchr(fFilename.c_str(), SkOSPath::SEPARATOR);
            name.append(basename ? basename+1: fFilename.c_str());
            SampleCode::TitleR(evt, name.c_str());
            return true;
        }
        SkUnichar key;
        if (SampleCode::CharQ(*evt, &key)) {
            if (this->handleKeystroke(key)) {
                return true;
            }
        }
        return this->INHERITED::onQuery(evt);
    }

    bool handleKeystroke(SkUnichar key) {
        switch (key) {
            case 'X':
                if (!fTossedPaths.empty()) {
                    SkTSwap(fPaths, fTossedPaths);
                    if ('X' == fTrail.back()) {
                        fTrail.pop_back();
                    } else {
                        fTrail.push_back('X');
                    }
                    this->inval(nullptr);
                }
                return true;
            case 'x':
                if (fPaths.count() > 1) {
                    int midpt = (fPaths.count() + 1) / 2;
                    fPathHistory.emplace(fPaths, fTossedPaths);
                    fTossedPaths.reset(fPaths.begin() + midpt, fPaths.count() - midpt);
                    fPaths.resize_back(midpt);
                    fTrail.push_back('x');
                    this->inval(nullptr);
                }
                return true;
            case 'Z': {
                if (!fPathHistory.empty()) {
                    fPaths = fPathHistory.top().first;
                    fTossedPaths = fPathHistory.top().second;
                    fPathHistory.pop();
                    char ch;
                    do {
                        ch = fTrail.back();
                        fTrail.pop_back();
                    } while (ch != 'x');
                    this->inval(nullptr);
                }
                return true;
            }
            case 'D':
                SkDebugf("SampleApp --pathfinder %s", fFilename.c_str());
                if (!fTrail.empty()) {
                    SkDebugf(" --pathfinderTrail ", fFilename.c_str());
                    for (char ch : fTrail) {
                        SkDebugf("%c", ch);
                    }
                }
                SkDebugf("\n");
                for (const FoundPath& foundPath : fPaths) {
                    foundPath.fPath.dump();
                }
                return true;
        }
        return false;
    }

    void onDrawContent(SkCanvas* canvas) override {
        for (const FoundPath& path : fPaths) {
            SkAutoCanvasRestore acr(canvas, true);
            canvas->concat(path.fViewMatrix);
            canvas->drawPath(path.fPath, path.fPaint);
        }
    }

    struct FoundPath {
        SkPath     fPath;
        SkPaint    fPaint;
        SkMatrix   fViewMatrix;
    };

    SkString              fFilename;
    SkTArray<FoundPath>   fPaths;
    SkTArray<FoundPath>   fTossedPaths;
    SkTArray<char>        fTrail;

    std::stack<std::pair<SkTArray<FoundPath>, SkTArray<FoundPath>>> fPathHistory;

    typedef SampleView INHERITED;
};

SampleView* CreateSamplePathFinderView(const char filename[]) {
    return new PathFinderView(filename);
}
