/*
 * 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 "modules/sksg/include/SkSGGroup.h"

#include "include/core/SkCanvas.h"

#include <algorithm>

namespace sksg {

Group::Group() = default;

Group::Group(std::vector<sk_sp<RenderNode>> children)
    : fChildren(std::move(children)) {
    for (const auto& child : fChildren) {
        this->observeInval(child);
    }
}

Group::~Group() {
    for (const auto& child : fChildren) {
        this->unobserveInval(child);
    }
}

void Group::clear() {
    for (const auto& child : fChildren) {
        this->unobserveInval(child);
    }
    fChildren.clear();
}

void Group::addChild(sk_sp<RenderNode> node) {
    // should we allow duplicates?
    for (const auto& child : fChildren) {
        if (child == node) {
            return;
        }
    }

    this->observeInval(node);
    fChildren.push_back(std::move(node));

    this->invalidate();
}

void Group::removeChild(const sk_sp<RenderNode>& node) {
    SkDEBUGCODE(const auto origSize = fChildren.size());
    fChildren.erase(std::remove(fChildren.begin(), fChildren.end(), node), fChildren.end());
    SkASSERT(fChildren.size() == origSize - 1);

    this->unobserveInval(node);
    this->invalidate();
}

void Group::onRender(SkCanvas* canvas, const RenderContext* ctx) const {
    const auto local_ctx = ScopedRenderContext(canvas, ctx).setIsolation(this->bounds(),
                                                                         canvas->getTotalMatrix(),
                                                                         fRequiresIsolation);

    for (const auto& child : fChildren) {
        child->render(canvas, local_ctx);
    }
}

const RenderNode* Group::onNodeAt(const SkPoint& p) const {
    for (auto it = fChildren.crbegin(); it != fChildren.crend(); ++it) {
        if (const auto* node = (*it)->nodeAt(p)) {
            return node;
        }
    }

    return nullptr;
}

SkRect Group::onRevalidate(InvalidationController* ic, const SkMatrix& ctm) {
    SkASSERT(this->hasInval());

    SkRect bounds = SkRect::MakeEmpty();
    fRequiresIsolation = false;

    for (size_t i = 0; i < fChildren.size(); ++i) {
        const auto child_bounds = fChildren[i]->revalidate(ic, ctm);

        // If any of the child nodes overlap, group effects require layer isolation.
        if (!fRequiresIsolation && i > 0 && child_bounds.intersects(bounds)) {
#if 1
            // Testing conservatively against the union of prev bounds is cheap and good enough.
            fRequiresIsolation = true;
#else
            // Testing exhaustively doesn't seem to increase the layer elision rate in practice.
            for (size_t j = 0; j < i; ++ j) {
                if (child_bounds.intersects(fChildren[i]->bounds())) {
                    fRequiresIsolation = true;
                    break;
                }
            }
#endif
        }

        bounds.join(child_bounds);
    }

    return bounds;
}

} // namespace sksg
