/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <gtest/gtest.h>

#include <LayerUpdateQueue.h>
#include <RenderNode.h>

#include <tests/common/TestUtils.h>

namespace android {
namespace uirenderer {

TEST(LayerUpdateQueue, construct) {
    LayerUpdateQueue queue;
    EXPECT_TRUE(queue.entries().empty());
}

// sync node properties, so properties() reflects correct width and height
static sp<RenderNode> createSyncedNode(uint32_t width, uint32_t height) {
    sp<RenderNode> node = TestUtils::createNode(0, 0, width, height, nullptr);
    TestUtils::syncHierarchyPropertiesAndDisplayList(node);
    return node;
}

TEST(LayerUpdateQueue, enqueueSimple) {
    sp<RenderNode> a = createSyncedNode(100, 100);
    sp<RenderNode> b = createSyncedNode(200, 200);
    sp<RenderNode> c = createSyncedNode(200, 200);

    LayerUpdateQueue queue;
    queue.enqueueLayerWithDamage(a.get(), Rect(25, 25, 75, 75));
    queue.enqueueLayerWithDamage(b.get(), Rect(100, 100, 300, 300));
    queue.enqueueLayerWithDamage(c.get(), Rect(.5, .5, .5, .5));

    EXPECT_EQ(3u, queue.entries().size());

    EXPECT_EQ(a.get(), queue.entries()[0].renderNode.get());
    EXPECT_EQ(Rect(25, 25, 75, 75), queue.entries()[0].damage);
    EXPECT_EQ(b.get(), queue.entries()[1].renderNode.get());
    EXPECT_EQ(Rect(100, 100, 200, 200), queue.entries()[1].damage); // clipped to bounds
    EXPECT_EQ(c.get(), queue.entries()[2].renderNode.get());
    EXPECT_EQ(Rect(0, 0, 1, 1), queue.entries()[2].damage); // rounded out
}

TEST(LayerUpdateQueue, enqueueUnion) {
    sp<RenderNode> a = createSyncedNode(100, 100);

    LayerUpdateQueue queue;
    queue.enqueueLayerWithDamage(a.get(), Rect(10, 10, 20, 20));
    queue.enqueueLayerWithDamage(a.get(), Rect(30, 30, 40, 40));

    EXPECT_EQ(1u, queue.entries().size());

    EXPECT_EQ(a.get(), queue.entries()[0].renderNode.get());
    EXPECT_EQ(Rect(10, 10, 40, 40), queue.entries()[0].damage);
}

TEST(LayerUpdateQueue, clear) {
    sp<RenderNode> a = createSyncedNode(100, 100);

    LayerUpdateQueue queue;
    queue.enqueueLayerWithDamage(a.get(), Rect(100, 100));

    EXPECT_FALSE(queue.entries().empty());

    queue.clear();

    EXPECT_TRUE(queue.entries().empty());
}

};
};
