/*
 * Copyright (C) 2014 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.
 */

#pragma once

#ifdef __ANDROID__ // Layoutlib does not support device info
#include "DeviceInfo.h"
#endif // __ANDROID__

#include "Outline.h"
#include "Rect.h"
#include "RevealClip.h"
#include "effects/StretchEffect.h"
#include "utils/MathUtils.h"
#include "utils/PaintUtils.h"

#include <SkBlendMode.h>
#include <SkImageFilter.h>
#include <SkCamera.h>
#include <SkColor.h>
#include <SkMatrix.h>
#include <SkRegion.h>

#include <androidfw/ResourceTypes.h>
#include <cutils/compiler.h>
#include <stddef.h>
#include <utils/Log.h>
#include <algorithm>
#include <ostream>
#include <vector>

class SkBitmap;
class SkColorFilter;
class SkPaint;

namespace android {
namespace uirenderer {

class Matrix4;
class RenderNode;
class RenderProperties;

// The __VA_ARGS__ will be executed if a & b are not equal
#define RP_SET(a, b, ...) ((a) != (b) ? ((a) = (b), ##__VA_ARGS__, true) : false)
#define RP_SET_AND_DIRTY(a, b) RP_SET(a, b, mPrimitiveFields.mMatrixOrPivotDirty = true)

// Keep in sync with View.java:LAYER_TYPE_*
enum class LayerType {
    None = 0,
    // We cannot build the software layer directly (must be done at record time) and all management
    // of software layers is handled in Java.
    Software = 1,
    RenderLayer = 2,
};

enum ClippingFlags {
    CLIP_TO_BOUNDS = 0x1 << 0,
    CLIP_TO_CLIP_BOUNDS = 0x1 << 1,
};

class LayerProperties {
public:
    bool setType(LayerType type) {
        if (RP_SET(mType, type)) {
            reset();
            return true;
        }
        return false;
    }

    bool setOpaque(bool opaque) { return RP_SET(mOpaque, opaque); }

    bool opaque() const { return mOpaque; }

    bool setAlpha(uint8_t alpha) { return RP_SET(mAlpha, alpha); }

    uint8_t alpha() const { return mAlpha; }

    bool setXferMode(SkBlendMode mode) { return RP_SET(mMode, mode); }

    SkBlendMode xferMode() const { return mMode; }

    SkColorFilter* getColorFilter() const { return mColorFilter.get(); }

    bool setImageFilter(SkImageFilter* imageFilter);

    SkImageFilter* getImageFilter() const { return mImageFilter.get(); }

    const StretchEffect& getStretchEffect() const { return mStretchEffect; }

    StretchEffect& mutableStretchEffect() { return mStretchEffect; }

    // Sets alpha, xfermode, and colorfilter from an SkPaint
    // paint may be NULL, in which case defaults will be set
    bool setFromPaint(const SkPaint* paint);

    bool needsBlending() const { return !opaque() || alpha() < 255; }

    LayerProperties& operator=(const LayerProperties& other);

    // Strongly recommend using effectiveLayerType instead
    LayerType type() const { return mType; }

private:
    LayerProperties();
    ~LayerProperties();
    void reset();
    bool setColorFilter(SkColorFilter* filter);

    friend class RenderProperties;

    LayerType mType = LayerType::None;
    // Whether or not that Layer's content is opaque, doesn't include alpha
    bool mOpaque;
    uint8_t mAlpha;
    SkBlendMode mMode;
    sk_sp<SkColorFilter> mColorFilter;
    sk_sp<SkImageFilter> mImageFilter;
    StretchEffect mStretchEffect;
};

/*
 * Data structure that holds the properties for a RenderNode
 */
class RenderProperties {
public:
    RenderProperties();
    virtual ~RenderProperties();

    static bool setFlag(int flag, bool newValue, int* outFlags) {
        if (newValue) {
            if (!(flag & *outFlags)) {
                *outFlags |= flag;
                return true;
            }
            return false;
        } else {
            if (flag & *outFlags) {
                *outFlags &= ~flag;
                return true;
            }
            return false;
        }
    }

    /**
     * Set internal layer state based on whether this layer
     *
     * Additionally, returns true if child RenderNodes with functors will need to use a layer
     * to support clipping.
     */
    bool prepareForFunctorPresence(bool willHaveFunctor, bool ancestorDictatesFunctorsNeedLayer) {
        // parent may have already dictated that a descendant layer is needed
        bool functorsNeedLayer =
                ancestorDictatesFunctorsNeedLayer ||
                CC_UNLIKELY(isClipMayBeComplex())

                // Round rect clipping forces layer for functors
                || CC_UNLIKELY(getOutline().willComplexClip()) ||
                CC_UNLIKELY(getRevealClip().willClip())

                // Complex matrices forces layer, due to stencil clipping
                || CC_UNLIKELY(getTransformMatrix() && !getTransformMatrix()->isScaleTranslate()) ||
                CC_UNLIKELY(getAnimationMatrix() && !getAnimationMatrix()->isScaleTranslate()) ||
                CC_UNLIKELY(getStaticMatrix() && !getStaticMatrix()->isScaleTranslate());

        mComputedFields.mNeedLayerForFunctors = (willHaveFunctor && functorsNeedLayer);

        // If on a layer, will have consumed the need for isolating functors from stencil.
        // Thus, it's safe to reset the flag until some descendent sets it.
        return CC_LIKELY(effectiveLayerType() == LayerType::None) && functorsNeedLayer;
    }

    RenderProperties& operator=(const RenderProperties& other);

    bool setClipToBounds(bool clipToBounds) {
        return setFlag(CLIP_TO_BOUNDS, clipToBounds, &mPrimitiveFields.mClippingFlags);
    }

    bool setClipBounds(const Rect& clipBounds) {
        bool ret = setFlag(CLIP_TO_CLIP_BOUNDS, true, &mPrimitiveFields.mClippingFlags);
        return RP_SET(mPrimitiveFields.mClipBounds, clipBounds) || ret;
    }

    bool setClipBoundsEmpty() {
        return setFlag(CLIP_TO_CLIP_BOUNDS, false, &mPrimitiveFields.mClippingFlags);
    }

    bool setProjectBackwards(bool shouldProject) {
        return RP_SET(mPrimitiveFields.mProjectBackwards, shouldProject);
    }

    bool setProjectionReceiver(bool shouldReceive) {
        return RP_SET(mPrimitiveFields.mProjectionReceiver, shouldReceive);
    }

    bool isProjectionReceiver() const { return mPrimitiveFields.mProjectionReceiver; }

    bool setClipMayBeComplex(bool isClipMayBeComplex) {
        return RP_SET(mPrimitiveFields.mClipMayBeComplex, isClipMayBeComplex);
    }

    bool isClipMayBeComplex() const { return mPrimitiveFields.mClipMayBeComplex; }

    bool setStaticMatrix(const SkMatrix* matrix) {
        delete mStaticMatrix;
        if (matrix) {
            mStaticMatrix = new SkMatrix(*matrix);
        } else {
            mStaticMatrix = nullptr;
        }
        return true;
    }

    // Can return NULL
    const SkMatrix* getStaticMatrix() const { return mStaticMatrix; }

    bool setAnimationMatrix(const SkMatrix* matrix) {
        delete mAnimationMatrix;
        if (matrix) {
            mAnimationMatrix = new SkMatrix(*matrix);
        } else {
            mAnimationMatrix = nullptr;
        }
        return true;
    }

    bool setAlpha(float alpha) {
        alpha = MathUtils::clampAlpha(alpha);
        return RP_SET(mPrimitiveFields.mAlpha, alpha);
    }

    float getAlpha() const { return mPrimitiveFields.mAlpha; }

    bool setHasOverlappingRendering(bool hasOverlappingRendering) {
        return RP_SET(mPrimitiveFields.mHasOverlappingRendering, hasOverlappingRendering);
    }

    bool hasOverlappingRendering() const { return mPrimitiveFields.mHasOverlappingRendering; }

    bool setElevation(float elevation) {
        return RP_SET(mPrimitiveFields.mElevation, elevation);
        // Don't dirty matrix/pivot, since they don't respect Z
    }

    float getElevation() const { return mPrimitiveFields.mElevation; }

    bool setTranslationX(float translationX) {
        return RP_SET_AND_DIRTY(mPrimitiveFields.mTranslationX, translationX);
    }

    float getTranslationX() const { return mPrimitiveFields.mTranslationX; }

    bool setTranslationY(float translationY) {
        return RP_SET_AND_DIRTY(mPrimitiveFields.mTranslationY, translationY);
    }

    float getTranslationY() const { return mPrimitiveFields.mTranslationY; }

    bool setTranslationZ(float translationZ) {
        return RP_SET(mPrimitiveFields.mTranslationZ, translationZ);
        // mMatrixOrPivotDirty not set, since matrix doesn't respect Z
    }

    float getTranslationZ() const { return mPrimitiveFields.mTranslationZ; }

    // Animation helper
    bool setX(float value) { return setTranslationX(value - getLeft()); }

    // Animation helper
    float getX() const { return getLeft() + getTranslationX(); }

    // Animation helper
    bool setY(float value) { return setTranslationY(value - getTop()); }

    // Animation helper
    float getY() const { return getTop() + getTranslationY(); }

    // Animation helper
    bool setZ(float value) { return setTranslationZ(value - getElevation()); }

    float getZ() const { return getElevation() + getTranslationZ(); }

    bool setRotation(float rotation) {
        return RP_SET_AND_DIRTY(mPrimitiveFields.mRotation, rotation);
    }

    float getRotation() const { return mPrimitiveFields.mRotation; }

    bool setRotationX(float rotationX) {
        return RP_SET_AND_DIRTY(mPrimitiveFields.mRotationX, rotationX);
    }

    float getRotationX() const { return mPrimitiveFields.mRotationX; }

    bool setRotationY(float rotationY) {
        return RP_SET_AND_DIRTY(mPrimitiveFields.mRotationY, rotationY);
    }

    float getRotationY() const { return mPrimitiveFields.mRotationY; }

    bool setScaleX(float scaleX) { return RP_SET_AND_DIRTY(mPrimitiveFields.mScaleX, scaleX); }

    float getScaleX() const { return mPrimitiveFields.mScaleX; }

    bool setScaleY(float scaleY) { return RP_SET_AND_DIRTY(mPrimitiveFields.mScaleY, scaleY); }

    float getScaleY() const { return mPrimitiveFields.mScaleY; }

    bool setPivotX(float pivotX) {
        if (RP_SET(mPrimitiveFields.mPivotX, pivotX) || !mPrimitiveFields.mPivotExplicitlySet) {
            mPrimitiveFields.mMatrixOrPivotDirty = true;
            mPrimitiveFields.mPivotExplicitlySet = true;
            return true;
        }
        return false;
    }

    /* Note that getPivotX and getPivotY are adjusted by updateMatrix(),
     * so the value returned may be stale if the RenderProperties has been
     * modified since the last call to updateMatrix()
     */
    float getPivotX() const { return mPrimitiveFields.mPivotX; }

    bool setPivotY(float pivotY) {
        if (RP_SET(mPrimitiveFields.mPivotY, pivotY) || !mPrimitiveFields.mPivotExplicitlySet) {
            mPrimitiveFields.mMatrixOrPivotDirty = true;
            mPrimitiveFields.mPivotExplicitlySet = true;
            return true;
        }
        return false;
    }

    float getPivotY() const { return mPrimitiveFields.mPivotY; }

    bool isPivotExplicitlySet() const { return mPrimitiveFields.mPivotExplicitlySet; }

    bool resetPivot() { return RP_SET_AND_DIRTY(mPrimitiveFields.mPivotExplicitlySet, false); }

    bool setCameraDistance(float distance) {
        if (distance != getCameraDistance()) {
            mPrimitiveFields.mMatrixOrPivotDirty = true;
            mComputedFields.mTransformCamera.setCameraLocation(0, 0, distance);
            return true;
        }
        return false;
    }

    float getCameraDistance() const {
        // TODO: update getCameraLocationZ() to be const
        return const_cast<Sk3DView*>(&mComputedFields.mTransformCamera)->getCameraLocationZ();
    }

    bool setLeft(int left) {
        if (RP_SET(mPrimitiveFields.mLeft, left)) {
            mPrimitiveFields.mWidth = mPrimitiveFields.mRight - mPrimitiveFields.mLeft;
            if (!mPrimitiveFields.mPivotExplicitlySet) {
                mPrimitiveFields.mMatrixOrPivotDirty = true;
            }
            return true;
        }
        return false;
    }

    int getLeft() const { return mPrimitiveFields.mLeft; }

    bool setTop(int top) {
        if (RP_SET(mPrimitiveFields.mTop, top)) {
            mPrimitiveFields.mHeight = mPrimitiveFields.mBottom - mPrimitiveFields.mTop;
            if (!mPrimitiveFields.mPivotExplicitlySet) {
                mPrimitiveFields.mMatrixOrPivotDirty = true;
            }
            return true;
        }
        return false;
    }

    int getTop() const { return mPrimitiveFields.mTop; }

    bool setRight(int right) {
        if (RP_SET(mPrimitiveFields.mRight, right)) {
            mPrimitiveFields.mWidth = mPrimitiveFields.mRight - mPrimitiveFields.mLeft;
            if (!mPrimitiveFields.mPivotExplicitlySet) {
                mPrimitiveFields.mMatrixOrPivotDirty = true;
            }
            return true;
        }
        return false;
    }

    int getRight() const { return mPrimitiveFields.mRight; }

    bool setBottom(int bottom) {
        if (RP_SET(mPrimitiveFields.mBottom, bottom)) {
            mPrimitiveFields.mHeight = mPrimitiveFields.mBottom - mPrimitiveFields.mTop;
            if (!mPrimitiveFields.mPivotExplicitlySet) {
                mPrimitiveFields.mMatrixOrPivotDirty = true;
            }
            return true;
        }
        return false;
    }

    int getBottom() const { return mPrimitiveFields.mBottom; }

    bool setLeftTop(int left, int top) {
        bool leftResult = setLeft(left);
        bool topResult = setTop(top);
        return leftResult || topResult;
    }

    bool setLeftTopRightBottom(int left, int top, int right, int bottom) {
        if (left != mPrimitiveFields.mLeft || top != mPrimitiveFields.mTop ||
            right != mPrimitiveFields.mRight || bottom != mPrimitiveFields.mBottom) {
            mPrimitiveFields.mLeft = left;
            mPrimitiveFields.mTop = top;
            mPrimitiveFields.mRight = right;
            mPrimitiveFields.mBottom = bottom;
            mPrimitiveFields.mWidth = mPrimitiveFields.mRight - mPrimitiveFields.mLeft;
            mPrimitiveFields.mHeight = mPrimitiveFields.mBottom - mPrimitiveFields.mTop;
            if (!mPrimitiveFields.mPivotExplicitlySet) {
                mPrimitiveFields.mMatrixOrPivotDirty = true;
            }
            return true;
        }
        return false;
    }

    bool offsetLeftRight(int offset) {
        if (offset != 0) {
            mPrimitiveFields.mLeft += offset;
            mPrimitiveFields.mRight += offset;
            return true;
        }
        return false;
    }

    bool offsetTopBottom(int offset) {
        if (offset != 0) {
            mPrimitiveFields.mTop += offset;
            mPrimitiveFields.mBottom += offset;
            return true;
        }
        return false;
    }

    int getWidth() const { return mPrimitiveFields.mWidth; }

    int getHeight() const { return mPrimitiveFields.mHeight; }

    const SkMatrix* getAnimationMatrix() const { return mAnimationMatrix; }

    bool hasTransformMatrix() const {
        return getTransformMatrix() && !getTransformMatrix()->isIdentity();
    }

    // May only call this if hasTransformMatrix() is true
    bool isTransformTranslateOnly() const {
        return getTransformMatrix()->getType() == SkMatrix::kTranslate_Mask;
    }

    const SkMatrix* getTransformMatrix() const {
        LOG_ALWAYS_FATAL_IF(mPrimitiveFields.mMatrixOrPivotDirty, "Cannot get a dirty matrix!");
        return mComputedFields.mTransformMatrix;
    }

    int getClippingFlags() const { return mPrimitiveFields.mClippingFlags; }

    bool getClipToBounds() const { return mPrimitiveFields.mClippingFlags & CLIP_TO_BOUNDS; }

    const Rect& getClipBounds() const { return mPrimitiveFields.mClipBounds; }

    void getClippingRectForFlags(uint32_t flags, Rect* outRect) const {
        if (flags & CLIP_TO_BOUNDS) {
            outRect->set(0, 0, getWidth(), getHeight());
            if (flags & CLIP_TO_CLIP_BOUNDS) {
                outRect->doIntersect(mPrimitiveFields.mClipBounds);
            }
        } else {
            outRect->set(mPrimitiveFields.mClipBounds);
        }
    }

    bool getHasOverlappingRendering() const { return mPrimitiveFields.mHasOverlappingRendering; }

    const Outline& getOutline() const { return mPrimitiveFields.mOutline; }

    const RevealClip& getRevealClip() const { return mPrimitiveFields.mRevealClip; }

    bool getProjectBackwards() const { return mPrimitiveFields.mProjectBackwards; }

    void debugOutputProperties(std::ostream& output, const int level) const;

    void updateMatrix();

    Outline& mutableOutline() { return mPrimitiveFields.mOutline; }

    RevealClip& mutableRevealClip() { return mPrimitiveFields.mRevealClip; }

    const LayerProperties& layerProperties() const { return mLayerProperties; }

    LayerProperties& mutateLayerProperties() { return mLayerProperties; }

    // Returns true if damage calculations should be clipped to bounds
    // TODO: Figure out something better for getZ(), as children should still be
    // clipped to this RP's bounds. But as we will damage -INT_MAX to INT_MAX
    // for this RP's getZ() anyway, this can be optimized when we have a
    // Z damage estimate instead of INT_MAX
    bool getClipDamageToBounds() const {
        return getClipToBounds() && (getZ() <= 0 || getOutline().isEmpty());
    }

    bool hasShadow() const {
        return getZ() > 0.0f && getOutline().getPath() != nullptr &&
               getOutline().getAlpha() != 0.0f;
    }

    SkColor getSpotShadowColor() const { return mPrimitiveFields.mSpotShadowColor; }

    bool setSpotShadowColor(SkColor shadowColor) {
        return RP_SET(mPrimitiveFields.mSpotShadowColor, shadowColor);
    }

    SkColor getAmbientShadowColor() const { return mPrimitiveFields.mAmbientShadowColor; }

    bool setAmbientShadowColor(SkColor shadowColor) {
        return RP_SET(mPrimitiveFields.mAmbientShadowColor, shadowColor);
    }

    bool fitsOnLayer() const {
#ifdef __ANDROID__ // Layoutlib does not support device info
        const DeviceInfo* deviceInfo = DeviceInfo::get();
        return mPrimitiveFields.mWidth <= deviceInfo->maxTextureSize() &&
               mPrimitiveFields.mHeight <= deviceInfo->maxTextureSize();
#else
        return mPrimitiveFields.mWidth <= 4096 && mPrimitiveFields.mHeight <= 4096;
#endif
    }

    bool promotedToLayer() const {
        return mLayerProperties.mType == LayerType::None && fitsOnLayer() &&
               (mComputedFields.mNeedLayerForFunctors || mLayerProperties.mImageFilter != nullptr ||
                mLayerProperties.getStretchEffect().requiresLayer() ||
                (!MathUtils::isZero(mPrimitiveFields.mAlpha) && mPrimitiveFields.mAlpha < 1 &&
                 mPrimitiveFields.mHasOverlappingRendering));
    }

    LayerType effectiveLayerType() const {
        return CC_UNLIKELY(promotedToLayer()) ? LayerType::RenderLayer : mLayerProperties.mType;
    }

    bool setAllowForceDark(bool allow) {
        return RP_SET(mPrimitiveFields.mAllowForceDark, allow);
    }

    bool getAllowForceDark() const {
        return mPrimitiveFields.mAllowForceDark;
    }

private:
    // Rendering properties
    struct PrimitiveFields {
        int mLeft = 0, mTop = 0, mRight = 0, mBottom = 0;
        int mWidth = 0, mHeight = 0;
        int mClippingFlags = CLIP_TO_BOUNDS;
        SkColor mSpotShadowColor = SK_ColorBLACK;
        SkColor mAmbientShadowColor = SK_ColorBLACK;
        float mAlpha = 1;
        float mTranslationX = 0, mTranslationY = 0, mTranslationZ = 0;
        float mElevation = 0;
        float mRotation = 0, mRotationX = 0, mRotationY = 0;
        float mScaleX = 1, mScaleY = 1;
        float mPivotX = 0, mPivotY = 0;
        bool mHasOverlappingRendering = false;
        bool mPivotExplicitlySet = false;
        bool mMatrixOrPivotDirty = false;
        bool mProjectBackwards = false;
        bool mProjectionReceiver = false;
        bool mAllowForceDark = true;
        bool mClipMayBeComplex = false;
        Rect mClipBounds;
        Outline mOutline;
        RevealClip mRevealClip;
    } mPrimitiveFields;

    SkMatrix* mStaticMatrix;
    SkMatrix* mAnimationMatrix;
    LayerProperties mLayerProperties;

    /**
     * These fields are all generated from other properties and are not set directly.
     */
    struct ComputedFields {
        ComputedFields();
        ~ComputedFields();

        /**
         * Stores the total transformation of the DisplayList based upon its scalar
         * translate/rotate/scale properties.
         *
         * In the common translation-only case, the matrix isn't necessarily allocated,
         * and the mTranslation properties are used directly.
         */
        SkMatrix* mTransformMatrix;

        Sk3DView mTransformCamera;

        // Force layer on for functors to enable render features they don't yet support (clipping)
        bool mNeedLayerForFunctors = false;
    } mComputedFields;
};

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