/*
 * 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 "SkRectPriv.h"
#include "SkSGNode.h"
#include "SkSGInvalidationController.h"

#include <algorithm>

namespace sksg {

class Node::ScopedFlag {
public:
    ScopedFlag(Node* node, uint32_t flag)
        : fNode(node)
        , fFlag(flag)
        , fWasSet(node->fFlags & flag) {
        node->fFlags |= flag;
    }
    ~ScopedFlag() {
        if (!fWasSet) {
            fNode->fFlags &= ~fFlag;
        }
    }

    bool wasSet() const { return fWasSet; }

private:
    Node*    fNode;
    uint32_t fFlag;
    bool     fWasSet;
};

#define TRAVERSAL_GUARD                                  \
    ScopedFlag traversal_guard(this, kInTraversal_Flag); \
    if (traversal_guard.wasSet())                        \
        return

Node::Node(uint32_t invalTraits)
    : fInvalObserver(nullptr)
    , fBounds(SkRectPriv::MakeLargeS32())
    , fInvalTraits(invalTraits)
    , fFlags(kInvalidated_Flag) {}

Node::~Node() {
    if (fFlags & kObserverArray_Flag) {
        SkASSERT(fInvalObserverArray->empty());
        delete fInvalObserverArray;
    } else {
        SkASSERT(!fInvalObserver);
    }
}

void Node::observeInval(const sk_sp<Node>& node) {
    SkASSERT(node);
    if (!(node->fFlags & kObserverArray_Flag)) {
        if (!node->fInvalObserver) {
            node->fInvalObserver = this;
            return;
        }

        auto observers = new std::vector<Node*>();
        observers->reserve(2);
        observers->push_back(node->fInvalObserver);

        node->fInvalObserverArray = observers;
        node->fFlags |= kObserverArray_Flag;
    }

    // No duplicate observers.
    SkASSERT(std::find(node->fInvalObserverArray->begin(),
                       node->fInvalObserverArray->end(), this) == node->fInvalObserverArray->end());

    node->fInvalObserverArray->push_back(this);
}

void Node::unobserveInval(const sk_sp<Node>& node) {
    SkASSERT(node);
    if (!(node->fFlags & kObserverArray_Flag)) {
        SkASSERT(node->fInvalObserver == this);
        node->fInvalObserver = nullptr;
        return;
    }

    SkDEBUGCODE(const auto origSize = node->fInvalObserverArray->size());
    node->fInvalObserverArray->erase(std::remove(node->fInvalObserverArray->begin(),
                                                 node->fInvalObserverArray->end(), this),
                                     node->fInvalObserverArray->end());
    SkASSERT(node->fInvalObserverArray->size() == origSize - 1);
}

template <typename Func>
void Node::forEachInvalObserver(Func&& func) const {
    if (fFlags & kObserverArray_Flag) {
        for (const auto& parent : *fInvalObserverArray) {
            func(parent);
        }
        return;
    }

    if (fInvalObserver) {
        func(fInvalObserver);
    }
}

void Node::invalidate(bool damageBubbling) {
    TRAVERSAL_GUARD;

    if (this->hasInval() && (!damageBubbling || (fFlags & kDamage_Flag))) {
        // All done.
        return;
    }

    if (damageBubbling && !(fInvalTraits & kBubbleDamage_Trait)) {
        // Found a damage observer.
        fFlags |= kDamage_Flag;
        damageBubbling = false;
    }

    fFlags |= kInvalidated_Flag;

    forEachInvalObserver([&](Node* observer) {
        observer->invalidate(damageBubbling);
    });
}

const SkRect& Node::revalidate(InvalidationController* ic, const SkMatrix& ctm) {
    TRAVERSAL_GUARD fBounds;

    if (!this->hasInval()) {
        return fBounds;
    }

    SkRect prevBounds;
    if (fFlags & kDamage_Flag) {
        prevBounds = fBounds;
    }

    fBounds = this->onRevalidate(ic, ctm);

    if (fFlags & kDamage_Flag) {
        ic->inval(prevBounds, ctm);
        if (fBounds != prevBounds) {
            ic->inval(fBounds, ctm);
        }
    }

    fFlags &= ~(kInvalidated_Flag | kDamage_Flag);

    return fBounds;
}

} // namespace sksg
