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

#include "utils/LinearAllocator.h"

#include <SkPath.h>
#include <limits>
#include <type_traits>

namespace android {
namespace uirenderer {

static void handlePoint(Rect& transformedBounds, const Matrix4& transform, float x, float y) {
    Vertex v = {x, y};
    transform.mapPoint(v.x, v.y);
    transformedBounds.expandToCover(v.x, v.y);
}

Rect transformAndCalculateBounds(const Rect& r, const Matrix4& transform) {
    const float kMinFloat = std::numeric_limits<float>::lowest();
    const float kMaxFloat = std::numeric_limits<float>::max();
    Rect transformedBounds = { kMaxFloat, kMaxFloat, kMinFloat, kMinFloat };
    handlePoint(transformedBounds, transform, r.left, r.top);
    handlePoint(transformedBounds, transform, r.right, r.top);
    handlePoint(transformedBounds, transform, r.left, r.bottom);
    handlePoint(transformedBounds, transform, r.right, r.bottom);
    return transformedBounds;
}

/*
 * TransformedRectangle
 */

TransformedRectangle::TransformedRectangle() {
}

TransformedRectangle::TransformedRectangle(const Rect& bounds,
        const Matrix4& transform)
        : mBounds(bounds)
        , mTransform(transform) {
}

bool TransformedRectangle::canSimplyIntersectWith(
        const TransformedRectangle& other) const {

    return mTransform == other.mTransform;
}

void TransformedRectangle::intersectWith(const TransformedRectangle& other) {
    mBounds.doIntersect(other.mBounds);
}

bool TransformedRectangle::isEmpty() const {
    return mBounds.isEmpty();
}

/*
 * RectangleList
 */

RectangleList::RectangleList()
        : mTransformedRectanglesCount(0) {
}

bool RectangleList::isEmpty() const {
    if (mTransformedRectanglesCount < 1) {
        return true;
    }

    for (int i = 0; i < mTransformedRectanglesCount; i++) {
        if (mTransformedRectangles[i].isEmpty()) {
            return true;
        }
    }
    return false;
}

int RectangleList::getTransformedRectanglesCount() const {
    return mTransformedRectanglesCount;
}

const TransformedRectangle& RectangleList::getTransformedRectangle(int i) const {
    return mTransformedRectangles[i];
}

void RectangleList::setEmpty() {
    mTransformedRectanglesCount = 0;
}

void RectangleList::set(const Rect& bounds, const Matrix4& transform) {
    mTransformedRectanglesCount = 1;
    mTransformedRectangles[0] = TransformedRectangle(bounds, transform);
}

bool RectangleList::intersectWith(const Rect& bounds,
        const Matrix4& transform) {
    TransformedRectangle newRectangle(bounds, transform);

    // Try to find a rectangle with a compatible transformation
    int index = 0;
    for (; index < mTransformedRectanglesCount; index++) {
        TransformedRectangle& tr(mTransformedRectangles[index]);
        if (tr.canSimplyIntersectWith(newRectangle)) {
            tr.intersectWith(newRectangle);
            return true;
        }
    }

    // Add it to the list if there is room
    if (index < kMaxTransformedRectangles) {
        mTransformedRectangles[index] = newRectangle;
        mTransformedRectanglesCount += 1;
        return true;
    }

    // This rectangle list is full
    return false;
}

Rect RectangleList::calculateBounds() const {
    Rect bounds;
    for (int index = 0; index < mTransformedRectanglesCount; index++) {
        const TransformedRectangle& tr(mTransformedRectangles[index]);
        if (index == 0) {
            bounds = tr.transformedBounds();
        } else {
            bounds.doIntersect(tr.transformedBounds());
        }
    }
    return bounds;
}

static SkPath pathFromTransformedRectangle(const Rect& bounds,
        const Matrix4& transform) {
    SkPath rectPath;
    SkPath rectPathTransformed;
    rectPath.addRect(bounds.left, bounds.top, bounds.right, bounds.bottom);
    SkMatrix skTransform;
    transform.copyTo(skTransform);
    rectPath.transform(skTransform, &rectPathTransformed);
    return rectPathTransformed;
}

SkRegion RectangleList::convertToRegion(const SkRegion& clip) const {
    SkRegion rectangleListAsRegion;
    for (int index = 0; index < mTransformedRectanglesCount; index++) {
        const TransformedRectangle& tr(mTransformedRectangles[index]);
        SkPath rectPathTransformed = pathFromTransformedRectangle(
                tr.getBounds(), tr.getTransform());
        if (index == 0) {
            rectangleListAsRegion.setPath(rectPathTransformed, clip);
        } else {
            SkRegion rectRegion;
            rectRegion.setPath(rectPathTransformed, clip);
            rectangleListAsRegion.op(rectRegion, SkRegion::kIntersect_Op);
        }
    }
    return rectangleListAsRegion;
}

void RectangleList::transform(const Matrix4& transform) {
    for (int index = 0; index < mTransformedRectanglesCount; index++) {
        mTransformedRectangles[index].transform(transform);
    }
}

/*
 * ClipArea
 */

ClipArea::ClipArea()
        : mMode(ClipMode::Rectangle) {
}

/*
 * Interface
 */

void ClipArea::setViewportDimensions(int width, int height) {
    mPostViewportClipObserved = false;
    mViewportBounds.set(0, 0, width, height);
    mClipRect = mViewportBounds;
}

void ClipArea::setEmpty() {
    onClipUpdated();
    mMode = ClipMode::Rectangle;
    mClipRect.setEmpty();
    mClipRegion.setEmpty();
    mRectangleList.setEmpty();
}

void ClipArea::setClip(float left, float top, float right, float bottom) {
    onClipUpdated();
    mMode = ClipMode::Rectangle;
    mClipRect.set(left, top, right, bottom);
    mClipRegion.setEmpty();
}

void ClipArea::clipRectWithTransform(const Rect& r, const mat4* transform,
        SkRegion::Op op) {
    if (!mPostViewportClipObserved && op == SkRegion::kIntersect_Op) op = SkRegion::kReplace_Op;
    onClipUpdated();
    switch (mMode) {
    case ClipMode::Rectangle:
        rectangleModeClipRectWithTransform(r, transform, op);
        break;
    case ClipMode::RectangleList:
        rectangleListModeClipRectWithTransform(r, transform, op);
        break;
    case ClipMode::Region:
        regionModeClipRectWithTransform(r, transform, op);
        break;
    }
}

void ClipArea::clipRegion(const SkRegion& region, SkRegion::Op op) {
    if (!mPostViewportClipObserved && op == SkRegion::kIntersect_Op) op = SkRegion::kReplace_Op;
    onClipUpdated();
    enterRegionMode();
    mClipRegion.op(region, op);
    onClipRegionUpdated();
}

void ClipArea::clipPathWithTransform(const SkPath& path, const mat4* transform,
        SkRegion::Op op) {
    if (!mPostViewportClipObserved && op == SkRegion::kIntersect_Op) op = SkRegion::kReplace_Op;
    onClipUpdated();
    SkMatrix skTransform;
    transform->copyTo(skTransform);
    SkPath transformed;
    path.transform(skTransform, &transformed);
    SkRegion region;
    regionFromPath(transformed, region);
    clipRegion(region, op);
}

/*
 * Rectangle mode
 */

void ClipArea::enterRectangleMode() {
    // Entering rectangle mode discards any
    // existing clipping information from the other modes.
    // The only way this occurs is by a clip setting operation.
    mMode = ClipMode::Rectangle;
}

void ClipArea::rectangleModeClipRectWithTransform(const Rect& r,
        const mat4* transform, SkRegion::Op op) {

    if (op == SkRegion::kReplace_Op && transform->rectToRect()) {
        mClipRect = r;
        transform->mapRect(mClipRect);
        return;
    } else if (op != SkRegion::kIntersect_Op) {
        enterRegionMode();
        regionModeClipRectWithTransform(r, transform, op);
        return;
    }

    if (transform->rectToRect()) {
        Rect transformed(r);
        transform->mapRect(transformed);
        mClipRect.doIntersect(transformed);
        return;
    }

    enterRectangleListMode();
    rectangleListModeClipRectWithTransform(r, transform, op);
}

/*
 * RectangleList mode implementation
 */

void ClipArea::enterRectangleListMode() {
    // Is is only legal to enter rectangle list mode from
    // rectangle mode, since rectangle list mode cannot represent
    // all clip areas that can be represented by a region.
    ALOG_ASSERT(mMode == ClipMode::Rectangle);
    mMode = ClipMode::RectangleList;
    mRectangleList.set(mClipRect, Matrix4::identity());
}

void ClipArea::rectangleListModeClipRectWithTransform(const Rect& r,
        const mat4* transform, SkRegion::Op op) {
    if (op != SkRegion::kIntersect_Op
            || !mRectangleList.intersectWith(r, *transform)) {
        enterRegionMode();
        regionModeClipRectWithTransform(r, transform, op);
    }
}

/*
 * Region mode implementation
 */

void ClipArea::enterRegionMode() {
    ClipMode oldMode = mMode;
    mMode = ClipMode::Region;
    if (oldMode != ClipMode::Region) {
        if (oldMode == ClipMode::Rectangle) {
            mClipRegion.setRect(mClipRect.toSkIRect());
        } else {
            mClipRegion = mRectangleList.convertToRegion(createViewportRegion());
            onClipRegionUpdated();
        }
    }
}

void ClipArea::regionModeClipRectWithTransform(const Rect& r,
        const mat4* transform, SkRegion::Op op) {
    SkPath transformedRect = pathFromTransformedRectangle(r, *transform);
    SkRegion transformedRectRegion;
    regionFromPath(transformedRect, transformedRectRegion);
    mClipRegion.op(transformedRectRegion, op);
    onClipRegionUpdated();
}

void ClipArea::onClipRegionUpdated() {
    if (!mClipRegion.isEmpty()) {
        mClipRect.set(mClipRegion.getBounds());

        if (mClipRegion.isRect()) {
            mClipRegion.setEmpty();
            enterRectangleMode();
        }
    } else {
        mClipRect.setEmpty();
    }
}

/**
 * Clip serialization
 */

const ClipBase* ClipArea::serializeClip(LinearAllocator& allocator) {
    if (!mPostViewportClipObserved) {
        // Only initial clip-to-viewport observed, so no serialization of clip necessary
        return nullptr;
    }

    static_assert(std::is_trivially_destructible<Rect>::value,
            "expect Rect to be trivially destructible");
    static_assert(std::is_trivially_destructible<RectangleList>::value,
            "expect RectangleList to be trivially destructible");

    if (mLastSerialization == nullptr) {
        ClipBase* serialization = nullptr;
        switch (mMode) {
        case ClipMode::Rectangle:
            serialization = allocator.create<ClipRect>(mClipRect);
            break;
        case ClipMode::RectangleList:
            serialization = allocator.create<ClipRectList>(mRectangleList);
            serialization->rect = mRectangleList.calculateBounds();
            break;
        case ClipMode::Region:
            serialization = allocator.create<ClipRegion>(mClipRegion);
            serialization->rect.set(mClipRegion.getBounds());
            break;
        }
        mLastSerialization = serialization;
    }
    return mLastSerialization;
}

inline static const Rect& getRect(const ClipBase* scb) {
    return reinterpret_cast<const ClipRect*>(scb)->rect;
}

inline static const RectangleList& getRectList(const ClipBase* scb) {
    return reinterpret_cast<const ClipRectList*>(scb)->rectList;
}

inline static const SkRegion& getRegion(const ClipBase* scb) {
    return reinterpret_cast<const ClipRegion*>(scb)->region;
}

// Conservative check for too many rectangles to fit in rectangle list.
// For simplicity, doesn't account for rect merging
static bool cannotFitInRectangleList(const ClipArea& clipArea, const ClipBase* scb) {
    int currentRectCount = clipArea.isRectangleList()
            ? clipArea.getRectangleList().getTransformedRectanglesCount()
            : 1;
    int recordedRectCount = (scb->mode == ClipMode::RectangleList)
            ? getRectList(scb).getTransformedRectanglesCount()
            : 1;
    return currentRectCount + recordedRectCount > RectangleList::kMaxTransformedRectangles;
}

static const ClipRect sEmptyClipRect(Rect(0, 0));

const ClipBase* ClipArea::serializeIntersectedClip(LinearAllocator& allocator,
        const ClipBase* recordedClip, const Matrix4& recordedClipTransform) {

    // if no recordedClip passed, just serialize current state
    if (!recordedClip) return serializeClip(allocator);

    // if either is empty, clip is empty
    if (CC_UNLIKELY(recordedClip->rect.isEmpty())|| mClipRect.isEmpty()) return &sEmptyClipRect;

    if (!mLastResolutionResult
            || recordedClip != mLastResolutionClip
            || recordedClipTransform != mLastResolutionTransform) {
        mLastResolutionClip = recordedClip;
        mLastResolutionTransform = recordedClipTransform;

        if (CC_LIKELY(mMode == ClipMode::Rectangle
                && recordedClip->mode == ClipMode::Rectangle
                && recordedClipTransform.rectToRect())) {
            // common case - result is a single rectangle
            auto rectClip = allocator.create<ClipRect>(getRect(recordedClip));
            recordedClipTransform.mapRect(rectClip->rect);
            rectClip->rect.doIntersect(mClipRect);
            mLastResolutionResult = rectClip;
        } else if (CC_UNLIKELY(mMode == ClipMode::Region
                || recordedClip->mode == ClipMode::Region
                || cannotFitInRectangleList(*this, recordedClip))) {
            // region case
            SkRegion other;
            switch (recordedClip->mode) {
            case ClipMode::Rectangle:
                if (CC_LIKELY(recordedClipTransform.rectToRect())) {
                    // simple transform, skip creating SkPath
                    Rect resultClip(getRect(recordedClip));
                    recordedClipTransform.mapRect(resultClip);
                    other.setRect(resultClip.toSkIRect());
                } else {
                    SkPath transformedRect = pathFromTransformedRectangle(getRect(recordedClip),
                            recordedClipTransform);
                    other.setPath(transformedRect, createViewportRegion());
                }
                break;
            case ClipMode::RectangleList: {
                RectangleList transformedList(getRectList(recordedClip));
                transformedList.transform(recordedClipTransform);
                other = transformedList.convertToRegion(createViewportRegion());
                break;
            }
            case ClipMode::Region:
                other = getRegion(recordedClip);

                // TODO: handle non-translate transforms properly!
                other.translate(recordedClipTransform.getTranslateX(),
                        recordedClipTransform.getTranslateY());
            }

            ClipRegion* regionClip = allocator.create<ClipRegion>();
            switch (mMode) {
            case ClipMode::Rectangle:
                regionClip->region.op(mClipRect.toSkIRect(), other, SkRegion::kIntersect_Op);
                break;
            case ClipMode::RectangleList:
                regionClip->region.op(mRectangleList.convertToRegion(createViewportRegion()),
                        other, SkRegion::kIntersect_Op);
                break;
            case ClipMode::Region:
                regionClip->region.op(mClipRegion, other, SkRegion::kIntersect_Op);
                break;
            }
            regionClip->rect.set(regionClip->region.getBounds());
            mLastResolutionResult = regionClip;
        } else {
            auto rectListClip = allocator.create<ClipRectList>(mRectangleList);
            auto&& rectList = rectListClip->rectList;
            if (mMode == ClipMode::Rectangle) {
                rectList.set(mClipRect, Matrix4::identity());
            }

            if (recordedClip->mode == ClipMode::Rectangle) {
                rectList.intersectWith(getRect(recordedClip), recordedClipTransform);
            } else {
                const RectangleList& other = getRectList(recordedClip);
                for (int i = 0; i < other.getTransformedRectanglesCount(); i++) {
                    auto&& tr = other.getTransformedRectangle(i);
                    Matrix4 totalTransform(recordedClipTransform);
                    totalTransform.multiply(tr.getTransform());
                    rectList.intersectWith(tr.getBounds(), totalTransform);
                }
            }
            rectListClip->rect = rectList.calculateBounds();
            mLastResolutionResult = rectListClip;
        }
    }
    return mLastResolutionResult;
}

void ClipArea::applyClip(const ClipBase* clip, const Matrix4& transform) {
    if (!clip) return; // nothing to do

    if (CC_LIKELY(clip->mode == ClipMode::Rectangle)) {
        clipRectWithTransform(getRect(clip), &transform, SkRegion::kIntersect_Op);
    } else if (CC_LIKELY(clip->mode == ClipMode::RectangleList)) {
        auto&& rectList = getRectList(clip);
        for (int i = 0; i < rectList.getTransformedRectanglesCount(); i++) {
            auto&& tr = rectList.getTransformedRectangle(i);
            Matrix4 totalTransform(transform);
            totalTransform.multiply(tr.getTransform());
            clipRectWithTransform(tr.getBounds(), &totalTransform, SkRegion::kIntersect_Op);
        }
    } else {
        SkRegion region(getRegion(clip));
        // TODO: handle non-translate transforms properly!
        region.translate(transform.getTranslateX(), transform.getTranslateY());
        clipRegion(region, SkRegion::kIntersect_Op);
    }
}

} /* namespace uirenderer */
} /* namespace android */
