/*
 * 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 "CanvasState.h"

#include "Matrix.h"
#include "Rect.h"
#include "hwui/Canvas.h"
#include "utils/LinearAllocator.h"

#include <gtest/gtest.h>
#include <SkPath.h>
#include <SkClipOp.h>

namespace android {
namespace uirenderer {

class NullClient: public CanvasStateClient {
    void onViewportInitialized() override {}
    void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) {}
    GLuint getTargetFbo() const override { return 0; }
};

static NullClient sNullClient;

static bool approxEqual(const Matrix4& a, const Matrix4& b) {
    for (int i = 0; i < 16; i++) {
        if (!MathUtils::areEqual(a[i], b[i])) {
            return false;
        }
    }
    return true;
}

TEST(CanvasState, gettersAndSetters) {
    CanvasState state(sNullClient);
    state.initializeSaveStack(200, 200,
            0, 0, 200, 200, Vector3());

    ASSERT_EQ(state.getWidth(), 200);
    ASSERT_EQ(state.getHeight(), 200);

    Matrix4 simpleTranslate;
    simpleTranslate.loadTranslate(10, 20, 0);
    state.setMatrix(simpleTranslate);

    ASSERT_EQ(state.getRenderTargetClipBounds(), Rect(200, 200));
    ASSERT_EQ(state.getLocalClipBounds(), Rect(-10, -20, 190, 180));
    EXPECT_TRUE(approxEqual(*state.currentTransform(), simpleTranslate));
    EXPECT_TRUE(state.clipIsSimple());
}

TEST(CanvasState, simpleClipping) {
    CanvasState state(sNullClient);
    state.initializeSaveStack(200, 200,
            0, 0, 200, 200, Vector3());

    state.clipRect(0, 0, 100, 100, SkClipOp::kIntersect);
    ASSERT_EQ(state.getRenderTargetClipBounds(), Rect(100, 100));

    state.clipRect(10, 10, 200, 200, SkClipOp::kIntersect);
    ASSERT_EQ(state.getRenderTargetClipBounds(), Rect(10, 10, 100, 100));

    state.clipRect(50, 50, 150, 150, SkClipOp::kReplace_deprecated);
    ASSERT_EQ(state.getRenderTargetClipBounds(), Rect(50, 50, 150, 150));
}

TEST(CanvasState, complexClipping) {
    CanvasState state(sNullClient);
    state.initializeSaveStack(200, 200,
            0, 0, 200, 200, Vector3());

    state.save(SaveFlags::MatrixClip);
    {
        // rotated clip causes complex clip
        state.rotate(10);
        EXPECT_TRUE(state.clipIsSimple());
        state.clipRect(0, 0, 200, 200, SkClipOp::kIntersect);
        EXPECT_FALSE(state.clipIsSimple());
    }
    state.restore();

    state.save(SaveFlags::MatrixClip);
    {
        // subtracted clip causes complex clip
        EXPECT_TRUE(state.clipIsSimple());
        state.clipRect(50, 50, 150, 150, SkClipOp::kDifference);
        EXPECT_FALSE(state.clipIsSimple());
    }
    state.restore();

    state.save(SaveFlags::MatrixClip);
    {
        // complex path causes complex clip
        SkPath path;
        path.addOval(SkRect::MakeWH(200, 200));
        EXPECT_TRUE(state.clipIsSimple());
        state.clipPath(&path, SkClipOp::kDifference);
        EXPECT_FALSE(state.clipIsSimple());
    }
    state.restore();
}

TEST(CanvasState, saveAndRestore) {
    CanvasState state(sNullClient);
    state.initializeSaveStack(200, 200,
            0, 0, 200, 200, Vector3());

    state.save(SaveFlags::Clip);
    {
        state.clipRect(0, 0, 10, 10, SkClipOp::kIntersect);
        ASSERT_EQ(state.getRenderTargetClipBounds(), Rect(10, 10));
    }
    state.restore();
    ASSERT_EQ(state.getRenderTargetClipBounds(), Rect(200, 200)); // verify restore

    Matrix4 simpleTranslate;
    simpleTranslate.loadTranslate(10, 10, 0);
    state.save(SaveFlags::Matrix);
    {
        state.translate(10, 10, 0);
        EXPECT_TRUE(approxEqual(*state.currentTransform(), simpleTranslate));
    }
    state.restore();
    EXPECT_FALSE(approxEqual(*state.currentTransform(), simpleTranslate));
}

TEST(CanvasState, saveAndRestoreButNotTooMuch) {
    CanvasState state(sNullClient);
    state.initializeSaveStack(200, 200,
            0, 0, 200, 200, Vector3());

    state.save(SaveFlags::Matrix); // NOTE: clip not saved
    {
        state.clipRect(0, 0, 10, 10, SkClipOp::kIntersect);
        ASSERT_EQ(state.getRenderTargetClipBounds(), Rect(10, 10));
    }
    state.restore();
    ASSERT_EQ(state.getRenderTargetClipBounds(), Rect(10, 10)); // verify not restored

    Matrix4 simpleTranslate;
    simpleTranslate.loadTranslate(10, 10, 0);
    state.save(SaveFlags::Clip); // NOTE: matrix not saved
    {
        state.translate(10, 10, 0);
        EXPECT_TRUE(approxEqual(*state.currentTransform(), simpleTranslate));
    }
    state.restore();
    EXPECT_TRUE(approxEqual(*state.currentTransform(), simpleTranslate)); // verify not restored
}

}
}
