/*
 * Copyright (C) 2011 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_TEXT_LAYOUT_CACHE_H
#define ANDROID_TEXT_LAYOUT_CACHE_H

#include "RtlProperties.h"

#include <stddef.h>
#include <utils/threads.h>
#include <utils/String16.h>
#include <utils/LruCache.h>
#include <utils/KeyedVector.h>
#include <utils/RefBase.h>
#include <utils/Singleton.h>

#include <SkAutoKern.h>
#include <SkLanguage.h>
#include <SkPaint.h>
#include <SkTemplates.h>
#include <SkTypeface.h>
#include <SkUtils.h>

#include <unicode/ubidi.h>
#include <unicode/unistr.h>

#include <hb.h>

#include <android_runtime/AndroidRuntime.h>

#define UNICODE_NOT_A_CHAR              0xffff
#define UNICODE_ZWSP                    0x200b
#define UNICODE_FIRST_LOW_SURROGATE     0xdc00
#define UNICODE_FIRST_HIGH_SURROGATE    0xd800
#define UNICODE_FIRST_PRIVATE_USE       0xe000
#define UNICODE_FIRST_RTL_CHAR          0x0590

// Temporary buffer size
#define CHAR_BUFFER_SIZE 80

// Converts a number of mega-bytes into bytes
#define MB(s) s * 1024 * 1024

// Define the default cache size in Mb
#define DEFAULT_TEXT_LAYOUT_CACHE_SIZE_IN_MB 0.500f

// Define the interval in number of cache hits between two statistics dump
#define DEFAULT_DUMP_STATS_CACHE_HIT_INTERVAL 100

namespace android {

/**
 * TextLayoutCacheKey is the Cache key
 */
class TextLayoutCacheKey {
public:
    TextLayoutCacheKey();

    TextLayoutCacheKey(const SkPaint* paint, const UChar* text, size_t start, size_t count,
            size_t contextCount, int dirFlags);

    TextLayoutCacheKey(const TextLayoutCacheKey& other);

    /**
     * Get the size of the Cache key.
     */
    size_t getSize() const;

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

    inline const UChar* getText() const { return textCopy.string(); }

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

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

    hash_t hash() const;
private:
    String16 textCopy;
    size_t start;
    size_t count;
    size_t contextCount;
    int dirFlags;
    SkTypeface* typeface;
    SkScalar textSize;
    SkScalar textSkewX;
    SkScalar textScaleX;
    uint32_t flags;
    SkPaint::Hinting hinting;
    SkPaint::FontVariant variant;
    SkLanguage language;

}; // TextLayoutCacheKey

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

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

inline hash_t hash_type(const TextLayoutCacheKey& key) {
    return key.hash();
}

/*
 * TextLayoutValue is the Cache value
 */
class TextLayoutValue : public RefBase {
public:
    TextLayoutValue(size_t contextCount);

    void setElapsedTime(uint32_t time);
    uint32_t getElapsedTime();

    inline const jfloat* getAdvances() const { return mAdvances.array(); }
    inline size_t getAdvancesCount() const { return mAdvances.size(); }
    inline jfloat getTotalAdvance() const { return mTotalAdvance; }
    inline const jchar* getGlyphs() const { return mGlyphs.array(); }
    inline size_t getGlyphsCount() const { return mGlyphs.size(); }
    inline const jfloat* getPos() const { return mPos.array(); }
    inline size_t getPosCount() const { return mPos.size(); }

    /**
     * Advances vector
     */
    Vector<jfloat> mAdvances;

    /**
     * Total number of advances
     */
    jfloat mTotalAdvance;

    /**
     * Glyphs vector
     */
    Vector<jchar> mGlyphs;

    /**
     * Pos vector (2 * i is x pos, 2 * i + 1 is y pos, same as drawPosText)
     */
    Vector<jfloat> mPos;

    /**
     * Get the size of the Cache entry
     */
    size_t getSize() const;

private:
    /**
     * Time for computing the values (in milliseconds)
     */
    uint32_t mElapsedTime;

}; // TextLayoutCacheValue

/**
 * The TextLayoutShaper is responsible for shaping (with the Harfbuzz library)
 */
class TextLayoutShaper {
public:
    TextLayoutShaper();
    virtual ~TextLayoutShaper();

    void computeValues(TextLayoutValue* value, const SkPaint* paint, const UChar* chars,
            size_t start, size_t count, size_t contextCount, int dirFlags);

    void purgeCaches();

private:
    /**
     * Harfbuzz buffer for shaping
     */
    hb_buffer_t* mBuffer;

    /**
     * Skia Paint used for shaping
     */
    SkPaint mShapingPaint;

    /**
     * Cache of Harfbuzz faces
     */
    KeyedVector<SkFontID, hb_face_t*> mCachedHBFaces;

    SkTypeface* typefaceForScript(const SkPaint* paint, SkTypeface* typeface,
        hb_script_t script);

    size_t shapeFontRun(const SkPaint* paint);

    void computeValues(const SkPaint* paint, const UChar* chars,
            size_t start, size_t count, size_t contextCount, int dirFlags,
            Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
            Vector<jchar>* const outGlyphs, Vector<jfloat>* const outPos);

    void computeRunValues(const SkPaint* paint, const UChar* chars,
            size_t start, size_t count, size_t contextCount, bool isRTL,
            Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance,
            Vector<jchar>* const outGlyphs, Vector<jfloat>* const outPos);

    SkTypeface* setCachedTypeface(SkTypeface** typeface, hb_script_t script, SkTypeface::Style style);
    hb_face_t* referenceCachedHBFace(SkTypeface* typeface);

    bool isComplexScript(hb_script_t script);
}; // TextLayoutShaper

/**
 * Cache of text layout information.
 */
class TextLayoutCache : private OnEntryRemoved<TextLayoutCacheKey, sp<TextLayoutValue> >
{
public:
    TextLayoutCache(TextLayoutShaper* shaper);

    ~TextLayoutCache();

    bool isInitialized() {
        return mInitialized;
    }

    /**
     * Used as a callback when an entry is removed from the cache
     * Do not invoke directly
     */
    void operator()(TextLayoutCacheKey& text, sp<TextLayoutValue>& desc);

    sp<TextLayoutValue> getValue(const SkPaint* paint, const jchar* text, jint start,
            jint count, jint contextCount, jint dirFlags);

    /**
     * Clear the cache
     */
    void purgeCaches();

private:
    TextLayoutShaper* mShaper;
    Mutex mLock;
    bool mInitialized;

    LruCache<TextLayoutCacheKey, sp<TextLayoutValue> > mCache;

    uint32_t mSize;
    uint32_t mMaxSize;

    uint32_t mCacheHitCount;
    uint64_t mNanosecondsSaved;

    uint64_t mCacheStartTime;

    RtlDebugLevel mDebugLevel;
    bool mDebugEnabled;

    /*
     * Class initialization
     */
    void init();

    /**
     * Dump Cache statistics
     */
    void dumpCacheStats();

}; // TextLayoutCache

/**
 * The TextLayoutEngine is reponsible for computing TextLayoutValues
 */
class TextLayoutEngine : public Singleton<TextLayoutEngine> {
public:
    TextLayoutEngine();
    virtual ~TextLayoutEngine();

    /**
     * Note: this method currently does a defensive copy of the text argument, in case
     * there is concurrent mutation of it. The contract may change, and may in the
     * future require the caller to guarantee that the contents will not change during
     * the call. Be careful of this when doing optimization.
     **/
    sp<TextLayoutValue> getValue(const SkPaint* paint, const jchar* text, jint start,
            jint count, jint contextCount, jint dirFlags);

    void purgeCaches();

private:
    TextLayoutCache* mTextLayoutCache;
    TextLayoutShaper* mShaper;
}; // TextLayoutEngine

} // namespace android
#endif /* ANDROID_TEXT_LAYOUT_CACHE_H */

