/*
 * 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.
 */
#ifndef CLIPAREA_H
#define CLIPAREA_H

#include "Matrix.h"
#include "Rect.h"
#include "utils/Pair.h"

#include <SkRegion.h>

namespace android {
namespace uirenderer {

class LinearAllocator;

Rect transformAndCalculateBounds(const Rect& r, const Matrix4& transform);

class TransformedRectangle {
public:
    TransformedRectangle();
    TransformedRectangle(const Rect& bounds, const Matrix4& transform);

    bool canSimplyIntersectWith(const TransformedRectangle& other) const;
    void intersectWith(const TransformedRectangle& other);

    bool isEmpty() const;

    const Rect& getBounds() const {
        return mBounds;
    }

    Rect transformedBounds() const {
        Rect transformedBounds(transformAndCalculateBounds(mBounds, mTransform));
        return transformedBounds;
    }

    const Matrix4& getTransform() const {
        return mTransform;
    }

    void transform(const Matrix4& transform) {
        Matrix4 t;
        t.loadMultiply(transform, mTransform);
        mTransform = t;
    }

private:
    Rect mBounds;
    Matrix4 mTransform;
};

class RectangleList {
public:
    RectangleList();

    bool isEmpty() const;
    int getTransformedRectanglesCount() const;
    const TransformedRectangle& getTransformedRectangle(int i) const;

    void setEmpty();
    void set(const Rect& bounds, const Matrix4& transform);
    bool intersectWith(const Rect& bounds, const Matrix4& transform);
    void transform(const Matrix4& transform);

    SkRegion convertToRegion(const SkRegion& clip) const;
    Rect calculateBounds() const;

    enum {
        kMaxTransformedRectangles = 5
    };

private:
    int mTransformedRectanglesCount;
    TransformedRectangle mTransformedRectangles[kMaxTransformedRectangles];
};

enum class ClipMode {
    Rectangle,
    RectangleList,

    // region and path - intersected. if either is empty, don't use
    Region
};

struct ClipBase {
    ClipBase(ClipMode mode)
            : mode(mode) {}
    ClipBase(const Rect& rect)
            : mode(ClipMode::Rectangle)
            , rect(rect) {}
    const ClipMode mode;
    bool intersectWithRoot = false;
    // Bounds of the clipping area, used to define the scissor, and define which
    // portion of the stencil is updated/used
    Rect rect;

    void dump() const;
};

struct ClipRect : ClipBase {
    ClipRect(const Rect& rect)
            : ClipBase(rect) {}
};

struct ClipRectList : ClipBase {
    ClipRectList(const RectangleList& rectList)
            : ClipBase(ClipMode::RectangleList)
            , rectList(rectList) {}
    RectangleList rectList;
};

struct ClipRegion : ClipBase {
    ClipRegion(const SkRegion& region)
            : ClipBase(ClipMode::Region)
            , region(region) {}
    ClipRegion()
            : ClipBase(ClipMode::Region) {}
    SkRegion region;
};

class ClipArea {
public:
    ClipArea();

    void setViewportDimensions(int width, int height);

    bool isEmpty() const {
        return mClipRect.isEmpty();
    }

    void setEmpty();
    void setClip(float left, float top, float right, float bottom);
    void clipRectWithTransform(const Rect& r, const mat4* transform,
            SkRegion::Op op);
    void clipRegion(const SkRegion& region, SkRegion::Op op);
    void clipPathWithTransform(const SkPath& path, const mat4* transform,
            SkRegion::Op op);

    const Rect& getClipRect() const {
        return mClipRect;
    }

    const SkRegion& getClipRegion() const {
        return mClipRegion;
    }

    const RectangleList& getRectangleList() const {
        return mRectangleList;
    }

    bool isRegion() const {
        return ClipMode::Region == mMode;
    }

    bool isSimple() const {
        return mMode == ClipMode::Rectangle;
    }

    bool isRectangleList() const {
        return mMode == ClipMode::RectangleList;
    }

    WARN_UNUSED_RESULT const ClipBase* serializeClip(LinearAllocator& allocator);
    WARN_UNUSED_RESULT const ClipBase* serializeIntersectedClip(LinearAllocator& allocator,
            const ClipBase* recordedClip, const Matrix4& recordedClipTransform);
    void applyClip(const ClipBase* recordedClip, const Matrix4& recordedClipTransform);

    static void applyTransformToRegion(const Matrix4& transform, SkRegion* region);

private:
    void enterRectangleMode();
    void rectangleModeClipRectWithTransform(const Rect& r, const mat4* transform, SkRegion::Op op);

    void enterRectangleListMode();
    void rectangleListModeClipRectWithTransform(const Rect& r,
            const mat4* transform, SkRegion::Op op);

    void enterRegionModeFromRectangleMode();
    void enterRegionModeFromRectangleListMode();
    void enterRegionMode();
    void regionModeClipRectWithTransform(const Rect& r, const mat4* transform,
            SkRegion::Op op);

    void ensureClipRegion();
    void onClipRegionUpdated();

    // Called by every state modifying public method.
    void onClipUpdated() {
        mPostViewportClipObserved = true;
        mLastSerialization = nullptr;
        mLastResolutionResult = nullptr;
    }

    SkRegion createViewportRegion() {
        return SkRegion(mViewportBounds.toSkIRect());
    }

    void regionFromPath(const SkPath& path, SkRegion& pathAsRegion) {
        // TODO: this should not mask every path to the viewport - this makes it impossible to use
        // paths to clip to larger areas (which is valid e.g. with SkRegion::kReplace_Op)
        pathAsRegion.setPath(path, createViewportRegion());
    }

    ClipMode mMode;
    bool mPostViewportClipObserved = false;
    bool mReplaceOpObserved = false;

    /**
     * If mLastSerialization is non-null, it represents an already serialized copy
     * of the current clip state. If null, it has not been computed.
     */
    const ClipBase* mLastSerialization = nullptr;

    /**
     * This pair of pointers is a single entry cache of most recently seen
     */
    const ClipBase* mLastResolutionResult = nullptr;
    const ClipBase* mLastResolutionClip = nullptr;
    Matrix4 mLastResolutionTransform;

    Rect mViewportBounds;
    Rect mClipRect;
    SkRegion mClipRegion;
    RectangleList mRectangleList;
};

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

#endif /* CLIPAREA_H_ */
