/*
 * Copyright 2011 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 "SkView.h"
#include "SkCanvas.h"

#include "SkAnimator.h"
#include "SkStream.h"
#include "SkDOM.h"

///////////////////////////////////////////////////////////////////////////////

class SkAnimatorView : public SkView {
public:
    SkAnimatorView();
    virtual ~SkAnimatorView();

    void setURIBase(const char dir[]);

    SkAnimator* getAnimator() const { return fAnimator; }

    bool    decodeFile(const char path[]);
    bool    decodeMemory(const void* buffer, size_t size);
    bool    decodeStream(SkStream* stream);

protected:
    // overrides
    virtual void onDraw(SkCanvas*);
    virtual bool onQuery(SkEvent* evt);

private:
    SkString fBaseURI;
    SkAnimator* fAnimator;

    typedef SkView INHERITED;
};

SkAnimatorView::SkAnimatorView() : fAnimator(nullptr) {}

SkAnimatorView::~SkAnimatorView() {
    delete fAnimator;
}

void SkAnimatorView::setURIBase(const char dir[]) {
    fBaseURI.set(dir);
}

bool SkAnimatorView::decodeFile(const char path[]) {
    SkAutoTDelete<SkStream> is(SkStream::NewFromFile(path));
    return is.get() != nullptr && this->decodeStream(is);
}

bool SkAnimatorView::decodeMemory(const void* buffer, size_t size) {
    SkMemoryStream is(buffer, size);
    return this->decodeStream(&is);
}

static const SkDOMNode* find_nodeID(const SkDOM& dom,
                        const SkDOMNode* node, const char name[]) {
    if (nullptr == node) {
        node = dom.getRootNode();
    }
    do {
        const char* idval = dom.findAttr(node, "id");
        if (idval && !strcmp(idval, name)) {
            return node;
        }
        const SkDOMNode* child = dom.getFirstChild(node);
        if (child) {
            const SkDOMNode* found = find_nodeID(dom, child, name);
            if (found) {
                return found;
            }
        }
    } while ((node = dom.getNextSibling(node)) != nullptr);
    return nullptr;
}

bool SkAnimatorView::decodeStream(SkStream* stream) {
    delete fAnimator;
    fAnimator = new SkAnimator;
    fAnimator->setURIBase(fBaseURI.c_str());
#if 0
    if (!fAnimator->decodeStream(stream)) {
        delete fAnimator;
        fAnimator = nullptr;
        return false;
    }
#else
    size_t len = stream->getLength();
    char* text = (char*)sk_malloc_throw(len);
    stream->read(text, len);
    SkDOM dom;
    const SkDOM::Node* root = dom.build(text, len);
    if (nullptr == root) {
        return false;
    }
    if (!fAnimator->decodeDOM(dom, root)) {
        delete fAnimator;
        fAnimator = nullptr;
        return false;
    }
    for (int i = 0; i <= 10; i++) {
        SkString name("glyph");
        name.appendS32(i);
        const SkDOM::Node* node = find_nodeID(dom, nullptr, name.c_str());
        SkASSERT(node);
        SkRect r;
        dom.findScalar(node, "left", &r.fLeft);
        dom.findScalar(node, "top", &r.fTop);
        dom.findScalar(node, "width", &r.fRight); r.fRight += r.fLeft;
        dom.findScalar(node, "height", &r.fBottom); r.fBottom += r.fTop;
        SkDebugf("--- %s [%g %g %g %g]\n", name.c_str(),
                 r.fLeft, r.fTop, r.fRight, r.fBottom);
    }
#endif
    return true;
}

#include "SkTime.h"

void SkAnimatorView::onDraw(SkCanvas* canvas) {
    canvas->drawColor(SK_ColorWHITE);
    if (fAnimator) {
        fAnimator->draw(canvas, 0);
#if 0
        canvas->save();
        canvas->translate(120, 30);
        canvas->scale(0.5, 0.5);
        fAnimator->draw(canvas, 0);
        canvas->restore();

        canvas->save();
        canvas->translate(190, 40);
        canvas->scale(0.25, 0.25);
        fAnimator->draw(canvas, 0);
        canvas->restore();

        this->inval(nullptr);
#endif
    }
}

bool SkAnimatorView::onQuery(SkEvent* evt) {
    if (SampleCode::TitleQ(*evt)) {
        SampleCode::TitleR(evt, "Animator");
        return true;
    }
    return this->INHERITED::onQuery(evt);
}

//////////////////////////////////////////////////////////////////////////////

static SkView* MyFactory() {
    SkAnimatorView* av = new SkAnimatorView;
//    av->decodeFile("/skimages/test.xml");
#if 0
    av->setURIBase("/skia/trunk/animations/");
    av->decodeFile("/skia/trunk/animations/checkbox.xml");
#else
    av->setURIBase("/");
    av->decodeFile("/testanim.txt");
#endif
    return av;
}

static SkViewRegister reg(MyFactory);
