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

#include <string>
#include <vector>

#include <hb.h>

namespace minikin {

// Due to the limits in font fallback score calculation, we can't use anything more than 12
// languages.
const size_t FONT_LANGUAGES_LIMIT = 12;

// The language or region code is encoded to 15 bits.
const uint16_t INVALID_CODE = 0x7fff;

class FontLanguages;

// FontLanguage is a compact representation of a BCP 47 language tag. It
// does not capture all possible information, only what directly affects
// font rendering.
struct FontLanguage {
public:
    enum EmojiStyle : uint8_t {
        EMSTYLE_EMPTY = 0,
        EMSTYLE_DEFAULT = 1,
        EMSTYLE_EMOJI = 2,
        EMSTYLE_TEXT = 3,
    };
    // Default constructor creates the unsupported language.
    FontLanguage()
            : mScript(0ul),
            mLanguage(INVALID_CODE),
            mRegion(INVALID_CODE),
            mHbLanguage(HB_LANGUAGE_INVALID),
            mSubScriptBits(0ul),
            mEmojiStyle(EMSTYLE_EMPTY) {}

    // Parse from string
    FontLanguage(const char* buf, size_t length);

    bool operator==(const FontLanguage other) const {
        return !isUnsupported() && isEqualScript(other) && mLanguage == other.mLanguage &&
                mRegion == other.mRegion && mEmojiStyle == other.mEmojiStyle;
    }

    bool operator!=(const FontLanguage other) const {
        return !(*this == other);
    }

    bool isUnsupported() const { return mLanguage == INVALID_CODE; }
    EmojiStyle getEmojiStyle() const { return mEmojiStyle; }
    hb_language_t getHbLanguage() const { return mHbLanguage; }


    bool isEqualScript(const FontLanguage& other) const;

    // Returns true if this script supports the given script. For example, ja-Jpan supports Hira,
    // ja-Hira doesn't support Jpan.
    bool supportsHbScript(hb_script_t script) const;

    std::string getString() const;

    // Calculates a matching score. This score represents how well the input languages cover this
    // language. The maximum score in the language list is returned.
    // 0 = no match, 1 = script match, 2 = script and primary language match.
    int calcScoreFor(const FontLanguages& supported) const;

    uint64_t getIdentifier() const {
        return ((uint64_t)mLanguage << 49) | ((uint64_t)mScript << 17) | ((uint64_t)mRegion << 2) |
                mEmojiStyle;
    }

private:
    friend class FontLanguages;  // for FontLanguages constructor

    // ISO 15924 compliant script code. The 4 chars script code are packed into a 32 bit integer.
    uint32_t mScript;

    // ISO 639-1 or ISO 639-2 compliant language code.
    // The two- or three-letter language code is packed into a 15 bit integer.
    // mLanguage = 0 means the FontLanguage is unsupported.
    uint16_t mLanguage;

    // ISO 3166-1 or UN M.49 compliant region code. The two-letter or three-digit region code is
    // packed into a 15 bit integer.
    uint16_t mRegion;

    // The language to be passed HarfBuzz shaper.
    hb_language_t mHbLanguage;

    // For faster comparing, use 7 bits for specific scripts.
    static const uint8_t kBopomofoFlag = 1u;
    static const uint8_t kHanFlag = 1u << 1;
    static const uint8_t kHangulFlag = 1u << 2;
    static const uint8_t kHiraganaFlag = 1u << 3;
    static const uint8_t kKatakanaFlag = 1u << 4;
    static const uint8_t kSimplifiedChineseFlag = 1u << 5;
    static const uint8_t kTraditionalChineseFlag = 1u << 6;
    uint8_t mSubScriptBits;

    EmojiStyle mEmojiStyle;

    static uint8_t scriptToSubScriptBits(uint32_t script);

    static EmojiStyle resolveEmojiStyle(const char* buf, size_t length, uint32_t script);

    // Returns true if the provide subscript bits has the requested subscript bits.
    // Note that this function returns false if the requested subscript bits are empty.
    static bool supportsScript(uint8_t providedBits, uint8_t requestedBits);
};

// An immutable list of languages.
class FontLanguages {
public:
    explicit FontLanguages(std::vector<FontLanguage>&& languages);
    FontLanguages() : mUnionOfSubScriptBits(0), mIsAllTheSameLanguage(false) {}
    FontLanguages(FontLanguages&&) = default;

    size_t size() const { return mLanguages.size(); }
    bool empty() const { return mLanguages.empty(); }
    const FontLanguage& operator[] (size_t n) const { return mLanguages[n]; }

private:
    friend struct FontLanguage;  // for calcScoreFor

    std::vector<FontLanguage> mLanguages;
    uint8_t mUnionOfSubScriptBits;
    bool mIsAllTheSameLanguage;

    uint8_t getUnionOfSubScriptBits() const { return mUnionOfSubScriptBits; }
    bool isAllTheSameLanguage() const { return mIsAllTheSameLanguage; }

    // Do not copy and assign.
    FontLanguages(const FontLanguages&) = delete;
    void operator=(const FontLanguages&) = delete;
};

}  // namespace minikin

#endif  // MINIKIN_FONT_LANGUAGE_H
