/*
 * 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 "font/CacheTexture.h"
#include "font/CachedGlyphInfo.h"
#include "font/Font.h"
#include "font/FontUtil.h"
#ifdef BUGREPORT_FONT_CACHE_USAGE
#include "font/FontCacheHistoryTracker.h"
#endif

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

#include <SkPaint.h>

#include <GLES2/gl2.h>

#include <vector>

#include "RenderScript.h"
namespace RSC {
class Element;
class RS;
class ScriptIntrinsicBlur;
class sp;
}

namespace android {
namespace uirenderer {

class BakedOpState;
class BakedOpRenderer;
struct ClipBase;

class TextDrawFunctor {
public:
    TextDrawFunctor(BakedOpRenderer* renderer, const BakedOpState* bakedState, const ClipBase* clip,
                    float x, float y, bool pureTranslate, int alpha, SkBlendMode mode,
                    const SkPaint* paint)
            : renderer(renderer)
            , bakedState(bakedState)
            , clip(clip)
            , x(x)
            , y(y)
            , pureTranslate(pureTranslate)
            , alpha(alpha)
            , mode(mode)
            , paint(paint) {}

    void draw(CacheTexture& texture, bool linearFiltering);

    BakedOpRenderer* renderer;
    const BakedOpState* bakedState;
    const ClipBase* clip;
    float x;
    float y;
    bool pureTranslate;
    int alpha;
    SkBlendMode mode;
    const SkPaint* paint;
};

class FontRenderer {
public:
    explicit FontRenderer(const uint8_t* gammaTable);
    ~FontRenderer();

    void flushLargeCaches(std::vector<CacheTexture*>& cacheTextures);
    void flushLargeCaches();

    void setFont(const SkPaint* paint, const SkMatrix& matrix);

    void precache(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs,
                  const SkMatrix& matrix);
    void endPrecaching();

    bool renderPosText(const SkPaint* paint, const Rect* clip, const glyph_t* glyphs, int numGlyphs,
                       int x, int y, const float* positions, Rect* outBounds,
                       TextDrawFunctor* functor, bool forceFinish = true);

    bool renderTextOnPath(const SkPaint* paint, const Rect* clip, const glyph_t* glyphs,
                          int numGlyphs, const SkPath* path, float hOffset, float vOffset,
                          Rect* outBounds, TextDrawFunctor* functor);

    struct DropShadow {
        uint32_t width;
        uint32_t height;
        uint8_t* image;
        int32_t penX;
        int32_t penY;
    };

    // After renderDropShadow returns, the called owns the memory in DropShadow.image
    // and is responsible for releasing it when it's done with it
    DropShadow renderDropShadow(const SkPaint* paint, const glyph_t* glyphs, int numGlyphs,
                                float radius, const float* positions);

    void setTextureFiltering(bool linearFiltering) { mLinearFiltering = linearFiltering; }

    uint32_t getSize() const;
    void dumpMemoryUsage(String8& log) const;

#ifdef BUGREPORT_FONT_CACHE_USAGE
    FontCacheHistoryTracker& historyTracker() { return mHistoryTracker; }
#endif

private:
    friend class Font;

    const uint8_t* mGammaTable;

    void allocateTextureMemory(CacheTexture* cacheTexture);
    void deallocateTextureMemory(CacheTexture* cacheTexture);
    void initTextTexture();
    CacheTexture* createCacheTexture(int width, int height, GLenum format, bool allocate);
    void cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyph, uint32_t* retOriginX,
                     uint32_t* retOriginY, bool precaching);
    CacheTexture* cacheBitmapInTexture(std::vector<CacheTexture*>& cacheTextures,
                                       const SkGlyph& glyph, uint32_t* startX, uint32_t* startY);

    void flushAllAndInvalidate();

    void checkInit();
    void initRender(const Rect* clip, Rect* bounds, TextDrawFunctor* functor);
    void finishRender();

    void issueDrawCommand(std::vector<CacheTexture*>& cacheTextures);
    void issueDrawCommand();
    void appendMeshQuadNoClip(float x1, float y1, float u1, float v1, float x2, float y2, float u2,
                              float v2, float x3, float y3, float u3, float v3, float x4, float y4,
                              float u4, float v4, CacheTexture* texture);
    void appendMeshQuad(float x1, float y1, float u1, float v1, float x2, float y2, float u2,
                        float v2, float x3, float y3, float u3, float v3, float x4, float y4,
                        float u4, float v4, CacheTexture* texture);
    void appendRotatedMeshQuad(float x1, float y1, float u1, float v1, float x2, float y2, float u2,
                               float v2, float x3, float y3, float u3, float v3, float x4, float y4,
                               float u4, float v4, CacheTexture* texture);

    void checkTextureUpdate();

    void setTextureDirty() { mUploadTexture = true; }

    const std::vector<CacheTexture*>& cacheTexturesForFormat(GLenum format) const;
    uint32_t getCacheSize(GLenum format) const;
    uint32_t getFreeCacheSize(GLenum format) const;

    uint32_t mSmallCacheWidth;
    uint32_t mSmallCacheHeight;
    uint32_t mLargeCacheWidth;
    uint32_t mLargeCacheHeight;

    std::vector<CacheTexture*> mACacheTextures;
    std::vector<CacheTexture*> mRGBACacheTextures;

    Font* mCurrentFont;
    LruCache<Font::FontDescription, Font*> mActiveFonts;

    CacheTexture* mCurrentCacheTexture;

    bool mUploadTexture;

    TextDrawFunctor* mFunctor;
    const Rect* mClip;
    Rect* mBounds;
    bool mDrawn;

    bool mInitialized;

    bool mLinearFiltering;

#ifdef BUGREPORT_FONT_CACHE_USAGE
    FontCacheHistoryTracker mHistoryTracker;
#endif

    // RS constructs
    RSC::sp<RSC::RS> mRs;
    RSC::sp<const RSC::Element> mRsElement;
    RSC::sp<RSC::ScriptIntrinsicBlur> mRsScript;

    static void computeGaussianWeights(float* weights, int32_t radius);
    static void horizontalBlur(float* weights, int32_t radius, const uint8_t* source, uint8_t* dest,
                               int32_t width, int32_t height);
    static void verticalBlur(float* weights, int32_t radius, const uint8_t* source, uint8_t* dest,
                             int32_t width, int32_t height);

    // the input image handle may have its pointer replaced (to avoid copies)
    void blurImage(uint8_t** image, int32_t width, int32_t height, float radius);
};

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