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

#include "Debug.h"
#include "Matrix.h"
#include "Rect.h"
#include "Vector.h"
#include "VertexBuffer.h"
#include "thread/TaskProcessor.h"
#include "utils/Macros.h"
#include "utils/Pair.h"

#include <SkPaint.h>
#include <SkPath.h>

#include <utils/LruCache.h>
#include <utils/Mutex.h>
#include <utils/StrongPointer.h>

class SkBitmap;
class SkCanvas;
struct SkRect;

namespace android {
namespace uirenderer {

class Caches;
class VertexBuffer;

///////////////////////////////////////////////////////////////////////////////
// Classes
///////////////////////////////////////////////////////////////////////////////

class TessellationCache {
public:
    typedef Pair<VertexBuffer*, VertexBuffer*> vertexBuffer_pair_t;

    struct Description {
        HASHABLE_TYPE(Description);
        enum class Type {
            None,
            RoundRect,
        };

        Type type;
        float scaleX;
        float scaleY;
        bool aa;
        SkPaint::Cap cap;
        SkPaint::Style style;
        float strokeWidth;
        union Shape {
            struct RoundRect {
                float width;
                float height;
                float rx;
                float ry;
            } roundRect;
        } shape;

        Description();
        Description(Type type, const Matrix4& transform, const SkPaint& paint);
        void setupMatrixAndPaint(Matrix4* matrix, SkPaint* paint) const;
    };

    struct ShadowDescription {
        HASHABLE_TYPE(ShadowDescription);
        const SkPath* nodeKey;
        float matrixData[16];

        ShadowDescription();
        ShadowDescription(const SkPath* nodeKey, const Matrix4* drawTransform);
    };

    class ShadowTask : public Task<vertexBuffer_pair_t> {
    public:
        ShadowTask(const Matrix4* drawTransform, const Rect& localClip, bool opaque,
                   const SkPath* casterPerimeter, const Matrix4* transformXY,
                   const Matrix4* transformZ, const Vector3& lightCenter, float lightRadius)
                : drawTransform(*drawTransform)
                , localClip(localClip)
                , opaque(opaque)
                , casterPerimeter(*casterPerimeter)
                , transformXY(*transformXY)
                , transformZ(*transformZ)
                , lightCenter(lightCenter)
                , lightRadius(lightRadius) {}

        /* Note - we deep copy all task parameters, because *even though* pointers into Allocator
         * controlled objects (like the SkPath and Matrix4s) should be safe for the entire frame,
         * certain Allocators are destroyed before trim() is called to flush incomplete tasks.
         *
         * These deep copies could be avoided, long term, by canceling or flushing outstanding
         * tasks before tearing down single-frame LinearAllocators.
         */
        const Matrix4 drawTransform;
        const Rect localClip;
        bool opaque;
        const SkPath casterPerimeter;
        const Matrix4 transformXY;
        const Matrix4 transformZ;
        const Vector3 lightCenter;
        const float lightRadius;
        VertexBuffer ambientBuffer;
        VertexBuffer spotBuffer;
    };

    TessellationCache();
    ~TessellationCache();

    /**
     * Clears the cache. This causes all TessellationBuffers to be deleted.
     */
    void clear();
    /**
     * Returns the maximum size of the cache in bytes.
     */
    uint32_t getMaxSize();
    /**
     * Returns the current size of the cache in bytes.
     */
    uint32_t getSize();

    /**
     * Trims the contents of the cache, removing items until it's under its
     * specified limit.
     *
     * Trimming is used for caches that support pre-caching from a worker
     * thread. During pre-caching the maximum limit of the cache can be
     * exceeded for the duration of the frame. It is therefore required to
     * trim the cache at the end of the frame to keep the total amount of
     * memory used under control.
     *
     * Also removes transient Shadow VertexBuffers, which aren't cached between frames.
     */
    void trim();

    // TODO: precache/get for Oval, Lines, Points, etc.

    void precacheRoundRect(const Matrix4& transform, const SkPaint& paint, float width,
                           float height, float rx, float ry) {
        getRoundRectBuffer(transform, paint, width, height, rx, ry);
    }
    const VertexBuffer* getRoundRect(const Matrix4& transform, const SkPaint& paint, float width,
                                     float height, float rx, float ry);

    sp<ShadowTask> getShadowTask(const Matrix4* drawTransform, const Rect& localClip, bool opaque,
                                 const SkPath* casterPerimeter, const Matrix4* transformXY,
                                 const Matrix4* transformZ, const Vector3& lightCenter,
                                 float lightRadius);

private:
    class Buffer;
    class TessellationTask;
    class TessellationProcessor;

    typedef VertexBuffer* (*Tessellator)(const Description&);

    void precacheShadows(const Matrix4* drawTransform, const Rect& localClip, bool opaque,
                         const SkPath* casterPerimeter, const Matrix4* transformXY,
                         const Matrix4* transformZ, const Vector3& lightCenter, float lightRadius);

    Buffer* getRectBuffer(const Matrix4& transform, const SkPaint& paint, float width,
                          float height);
    Buffer* getRoundRectBuffer(const Matrix4& transform, const SkPaint& paint, float width,
                               float height, float rx, float ry);

    Buffer* getOrCreateBuffer(const Description& entry, Tessellator tessellator);

    const uint32_t mMaxSize;

    bool mDebugEnabled;

    mutable Mutex mLock;

    ///////////////////////////////////////////////////////////////////////////////
    // General tessellation caching
    ///////////////////////////////////////////////////////////////////////////////
    sp<TaskProcessor<VertexBuffer*> > mProcessor;
    LruCache<Description, Buffer*> mCache;
    class BufferRemovedListener : public OnEntryRemoved<Description, Buffer*> {
        void operator()(Description& description, Buffer*& buffer) override;
    };
    BufferRemovedListener mBufferRemovedListener;

    ///////////////////////////////////////////////////////////////////////////////
    // Shadow tessellation caching
    ///////////////////////////////////////////////////////////////////////////////
    sp<TaskProcessor<vertexBuffer_pair_t> > mShadowProcessor;

    // holds a pointer, and implicit strong ref to each shadow task of the frame
    LruCache<ShadowDescription, Task<vertexBuffer_pair_t>*> mShadowCache;
    class BufferPairRemovedListener
            : public OnEntryRemoved<ShadowDescription, Task<vertexBuffer_pair_t>*> {
        void operator()(ShadowDescription& description,
                        Task<vertexBuffer_pair_t>*& bufferPairTask) override {
            bufferPairTask->decStrong(nullptr);
        }
    };
    BufferPairRemovedListener mBufferPairRemovedListener;

};  // class TessellationCache

void tessellateShadows(const Matrix4* drawTransform, const Rect* localClip, bool isCasterOpaque,
                       const SkPath* casterPerimeter, const Matrix4* casterTransformXY,
                       const Matrix4* casterTransformZ, const Vector3& lightCenter,
                       float lightRadius, VertexBuffer& ambientBuffer, VertexBuffer& spotBuffer);

};  // namespace uirenderer
};  // namespace android
