/*
 * Copyright (C) 2010 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 <GLES2/gl2.h>

#include <utils/LruCache.h>

#include <androidfw/ResourceTypes.h>

#include "Debug.h"
#include "utils/Pair.h"

namespace android {
namespace uirenderer {

class Patch;

///////////////////////////////////////////////////////////////////////////////
// Defines
///////////////////////////////////////////////////////////////////////////////

// Debug
#if DEBUG_PATCHES
    #define PATCH_LOGD(...) ALOGD(__VA_ARGS__)
#else
    #define PATCH_LOGD(...)
#endif

///////////////////////////////////////////////////////////////////////////////
// Cache
///////////////////////////////////////////////////////////////////////////////

class Caches;
class RenderState;

class PatchCache {
public:
    explicit PatchCache(RenderState& renderState);
    ~PatchCache();

    const Patch* get(const uint32_t bitmapWidth, const uint32_t bitmapHeight,
            const float pixelWidth, const float pixelHeight, const Res_png_9patch* patch);
    void clear();

    uint32_t getSize() const {
        return mSize;
    }

    uint32_t getMaxSize() const {
        return mMaxSize;
    }

    GLuint getMeshBuffer() const {
        return mMeshBuffer;
    }

    /**
     * Removes the entries associated with the specified 9-patch. This is meant
     * to be called from threads that are not the EGL context thread (GC thread
     * on the VM side for instance.)
     */
    void removeDeferred(Res_png_9patch* patch);

    /**
     * Process deferred removals.
     */
    void clearGarbage();


private:
    struct PatchDescription {
        PatchDescription(): mPatch(nullptr), mBitmapWidth(0), mBitmapHeight(0),
                mPixelWidth(0), mPixelHeight(0) {
        }

        PatchDescription(const uint32_t bitmapWidth, const uint32_t bitmapHeight,
                const float pixelWidth, const float pixelHeight, const Res_png_9patch* patch):
                mPatch(patch), mBitmapWidth(bitmapWidth), mBitmapHeight(bitmapHeight),
                mPixelWidth(pixelWidth), mPixelHeight(pixelHeight) {
        }

        hash_t hash() const;

        const Res_png_9patch* getPatch() const { return mPatch; }

        static int compare(const PatchDescription& lhs, const PatchDescription& rhs);

        bool operator==(const PatchDescription& other) const {
            return compare(*this, other) == 0;
        }

        bool operator!=(const PatchDescription& other) const {
            return compare(*this, other) != 0;
        }

        friend inline int strictly_order_type(const PatchDescription& lhs,
                const PatchDescription& rhs) {
            return PatchDescription::compare(lhs, rhs) < 0;
        }

        friend inline int compare_type(const PatchDescription& lhs,
                const PatchDescription& rhs) {
            return PatchDescription::compare(lhs, rhs);
        }

        friend inline hash_t hash_type(const PatchDescription& entry) {
            return entry.hash();
        }

    private:
        const Res_png_9patch* mPatch;
        uint32_t mBitmapWidth;
        uint32_t mBitmapHeight;
        float mPixelWidth;
        float mPixelHeight;

    }; // struct PatchDescription

    /**
     * A buffer block represents an empty range in the mesh buffer
     * that can be used to store vertices.
     *
     * The patch cache maintains a linked-list of buffer blocks
     * to track available regions of memory in the VBO.
     */
    struct BufferBlock {
        BufferBlock(uint32_t offset, uint32_t size): offset(offset), size(size), next(nullptr) {
        }

        uint32_t offset;
        uint32_t size;

        BufferBlock* next;
    }; // struct BufferBlock

    typedef Pair<const PatchDescription*, Patch*> patch_pair_t;

    void clearCache();
    void createVertexBuffer();

    void setupMesh(Patch* newMesh);

    void remove(Vector<patch_pair_t>& patchesToRemove, Res_png_9patch* patch);

#if DEBUG_PATCHES
    void dumpFreeBlocks(const char* prefix);
#endif

    RenderState& mRenderState;
    const uint32_t mMaxSize;
    uint32_t mSize;

    LruCache<PatchDescription, Patch*> mCache;

    GLuint mMeshBuffer;
    // First available free block inside the mesh buffer
    BufferBlock* mFreeBlocks;

    // Garbage tracking, required to handle GC events on the VM side
    Vector<Res_png_9patch*> mGarbage;
    mutable Mutex mLock;
}; // class PatchCache

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