/*
 * Copyright (C) 2009 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 ANDROID_RS_FONT_H
#define ANDROID_RS_FONT_H

#include "RenderScript.h"
#include "rsStream.h"
#include <utils/String8.h>
#include <utils/Vector.h>
#include <utils/KeyedVector.h>

#include <ft2build.h>
#include FT_FREETYPE_H

// ---------------------------------------------------------------------------
namespace android {

namespace renderscript {

// Gamma (>= 1.0, <= 10.0)
#define PROPERTY_TEXT_GAMMA "ro.text_gamma"
#define PROPERTY_TEXT_BLACK_GAMMA_THRESHOLD "ro.text_gamma.black_threshold"
#define PROPERTY_TEXT_WHITE_GAMMA_THRESHOLD "ro.text_gamma.white_threshold"

#define DEFAULT_TEXT_GAMMA 1.4f
#define DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD 64
#define DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD 192

class FontState;

class Font : public ObjectBase {
public:
    enum RenderMode {
        FRAMEBUFFER,
        BITMAP,
        MEASURE,
    };

    struct Rect {
        int32_t left;
        int32_t top;
        int32_t right;
        int32_t bottom;
        void set(int32_t l, int32_t r, int32_t t, int32_t b) {
            left = l;
            right = r;
            top = t;
            bottom = b;
        }
    };

    ~Font();

    // Currently files do not get serialized,
    // but we need to inherit from ObjectBase for ref tracking
    virtual void serialize(OStream *stream) const {
    }
    virtual RsA3DClassID getClassId() const {
        return RS_A3D_CLASS_ID_UNKNOWN;
    }

    static Font * create(Context *rsc, const char *name, float fontSize, uint32_t dpi,
                         const void *data = NULL, uint32_t dataLen = 0);

protected:

    friend class FontState;

    // Pointer to the utf data, length of data, where to start, number of glyphs ot read
    // (each glyph may be longer than a char because we are dealing with utf data)
    // Last two variables are the initial pen position
    void renderUTF(const char *text, uint32_t len, int32_t x, int32_t y,
                   uint32_t start, int32_t numGlyphs,
                   RenderMode mode = FRAMEBUFFER, Rect *bounds = NULL,
                   uint8_t *bitmap = NULL, uint32_t bitmapW = 0, uint32_t bitmapH = 0);

    void invalidateTextureCache();
    struct CachedGlyphInfo
    {
        // Has the cache been invalidated?
        bool mIsValid;
        // Location of the cached glyph in the bitmap
        // in case we need to resize the texture
        uint32_t mBitmapMinX;
        uint32_t mBitmapMinY;
        uint32_t mBitmapWidth;
        uint32_t mBitmapHeight;
        // Also cache texture coords for the quad
        float mBitmapMinU;
        float mBitmapMinV;
        float mBitmapMaxU;
        float mBitmapMaxV;
        // Minimize how much we call freetype
        FT_UInt mGlyphIndex;
        FT_Vector mAdvance;
        // Values below contain a glyph's origin in the bitmap
        FT_Int mBitmapLeft;
        FT_Int mBitmapTop;
    };

    String8 mFontName;
    float mFontSize;
    uint32_t mDpi;

    Font(Context *rsc);
    bool init(const char *name, float fontSize, uint32_t dpi, const void *data = NULL, uint32_t dataLen = 0);

    virtual void preDestroy() const;
    FT_Face mFace;
    bool mInitialized;
    bool mHasKerning;

    DefaultKeyedVector<uint32_t, CachedGlyphInfo* > mCachedGlyphs;
    CachedGlyphInfo* getCachedUTFChar(int32_t utfChar);

    CachedGlyphInfo *cacheGlyph(uint32_t glyph);
    void updateGlyphCache(CachedGlyphInfo *glyph);
    void measureCachedGlyph(CachedGlyphInfo *glyph, int32_t x, int32_t y, Rect *bounds);
    void drawCachedGlyph(CachedGlyphInfo *glyph, int32_t x, int32_t y);
    void drawCachedGlyph(CachedGlyphInfo *glyph, int32_t x, int32_t y,
                         uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH);
};

class FontState {
public:
    FontState();
    ~FontState();

    void init(Context *rsc);
    void deinit(Context *rsc);

    ObjectBaseRef<Font> mDefault;
    ObjectBaseRef<Font> mLast;

    void renderText(const char *text, uint32_t len, int32_t x, int32_t y,
                    uint32_t startIndex = 0, int numGlyphs = -1,
                    Font::RenderMode mode = Font::FRAMEBUFFER,
                    Font::Rect *bounds = NULL,
                    uint8_t *bitmap = NULL, uint32_t bitmapW = 0, uint32_t bitmapH = 0);

    void measureText(const char *text, uint32_t len, Font::Rect *bounds);

    void setFontColor(float r, float g, float b, float a);
    void getFontColor(float *r, float *g, float *b, float *a) const;

protected:

    friend class Font;

    struct CacheTextureLine {
        uint32_t mMaxHeight;
        uint32_t mMaxWidth;
        uint32_t mCurrentRow;
        uint32_t mCurrentCol;
        bool mDirty;

        CacheTextureLine(uint32_t maxHeight, uint32_t maxWidth, uint32_t currentRow, uint32_t currentCol)
            : mMaxHeight(maxHeight), mMaxWidth(maxWidth), mCurrentRow(currentRow),
              mCurrentCol(currentCol), mDirty(false)  {
        }

        bool fitBitmap(FT_Bitmap *bitmap, uint32_t *retOriginX, uint32_t *retOriginY) {
            if ((uint32_t)bitmap->rows > mMaxHeight) {
                return false;
            }

            if (mCurrentCol + (uint32_t)bitmap->width < mMaxWidth) {
                *retOriginX = mCurrentCol;
                *retOriginY = mCurrentRow;
                mCurrentCol += bitmap->width;
                mDirty = true;
               return true;
            }

            return false;
        }
    };

    Vector<CacheTextureLine*> mCacheLines;
    uint32_t getRemainingCacheCapacity();

    void precacheLatin(Font *font);
    String8 mLatinPrecache;

    Context *mRSC;

    struct {
        float mFontColor[4];
        float mGamma;
    } mConstants;
    bool mConstantsDirty;

    float mBlackGamma;
    float mWhiteGamma;

    float mBlackThreshold;
    float mWhiteThreshold;

    // Free type library, we only need one copy
    FT_Library mLibrary;
    FT_Library getLib();
    Vector<Font*> mActiveFonts;

    // Render state for the font
    ObjectBaseRef<Allocation> mFontShaderFConstant;
    ObjectBaseRef<ProgramFragment> mFontShaderF;
    ObjectBaseRef<Sampler> mFontSampler;
    ObjectBaseRef<ProgramStore> mFontProgramStore;
    void initRenderState();

    // Texture to cache glyph bitmaps
    ObjectBaseRef<Allocation> mTextTexture;
    void initTextTexture();
    const uint8_t* getTextTextureData() const {
        return (uint8_t*)mTextTexture->getPtr();
    }

    bool cacheBitmap(FT_Bitmap *bitmap, uint32_t *retOriginX, uint32_t *retOriginY);
    const Type* getCacheTextureType() {
        return mTextTexture->getType();
    }

    void flushAllAndInvalidate();

    // Pointer to vertex data to speed up frame to frame work
    float *mTextMeshPtr;
    uint32_t mCurrentQuadIndex;
    uint32_t mMaxNumberOfQuads;

    void initVertexArrayBuffers();
    ObjectBaseRef<Allocation> mIndexBuffer;
    ObjectBaseRef<Allocation> mVertexArray;


    bool mInitialized;

    void checkInit();

    void issueDrawCommand();

    void appendMeshQuad(float x1, float y1, float z1,
                        float u1, float v1,
                        float x2, float y2, float z2,
                        float u2, float v2,
                        float x3, float y3, float z3,
                        float u3, float v3,
                        float x4, float y4, float z4,
                        float u4, float v4);
};

}
}

#endif
