/*
 * Copyright (C) 2013 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.
 */

#define LOG_TAG "Minikin"

#include <cutils/log.h>
#include <stdlib.h>
#include <stdint.h>

#include "MinikinInternal.h"
#include <minikin/MinikinFont.h>
#include <minikin/AnalyzeStyle.h>
#include <minikin/CmapCoverage.h>
#include <minikin/FontFamily.h>
#include <UniquePtr.h>

using std::vector;

namespace android {

// Parse bcp-47 language identifier into internal structure
FontLanguage::FontLanguage(const char* buf, size_t size) {
    uint32_t bits = 0;
    size_t i;
    for (i = 0; i < size; i++) {
        uint16_t c = buf[i];
        if (c == '-' || c == '_') break;
    }
    if (i == 2) {
        bits = (uint8_t(buf[0]) << 8) | uint8_t(buf[1]);
    }
    size_t next;
    for (i++; i < size; i = next + 1) {
        for (next = i; next < size; next++) {
            uint16_t c = buf[next];
            if (c == '-' || c == '_') break;
        }
        if (next - i == 4 && buf[i] == 'H' && buf[i+1] == 'a' && buf[i+2] == 'n') {
            if (buf[i+3] == 's') {
                bits |= kHansFlag;
            } else if (buf[i+3] == 't') {
                bits |= kHantFlag;
            }
        }
        // TODO: this might be a good place to infer script from country (zh_TW -> Hant),
        // but perhaps it's up to the client to do that, before passing a string.
    }
    mBits = bits;
}

std::string FontLanguage::getString() const {
  char buf[16];
  size_t i = 0;
  if (mBits & kBaseLangMask) {
    buf[i++] = (mBits >> 8) & 0xFFu;
    buf[i++] = mBits & 0xFFu;
  }
  if (mBits & kScriptMask) {
    if (!i)
      buf[i++] = 'x';
    buf[i++] = '-';
    buf[i++] = 'H';
    buf[i++] = 'a';
    buf[i++] = 'n';
    if (mBits & kHansFlag)
      buf[i++] = 's';
    else
      buf[i++] = 't';
  }
  return std::string(buf, i);
}

int FontLanguage::match(const FontLanguage other) const {
    int result = 0;
    if ((mBits & kBaseLangMask) == (other.mBits & kBaseLangMask)) {
        result++;
        if ((mBits & kScriptMask) != 0 && (mBits & kScriptMask) == (other.mBits & kScriptMask)) {
            result++;
        }
    }
    return result;
}

FontFamily::~FontFamily() {
    for (size_t i = 0; i < mFonts.size(); i++) {
        mFonts[i].typeface->UnrefLocked();
    }
}

bool FontFamily::addFont(MinikinFont* typeface) {
    AutoMutex _l(gMinikinLock);
    const uint32_t os2Tag = MinikinFont::MakeTag('O', 'S', '/', '2');
    size_t os2Size = 0;
    bool ok = typeface->GetTable(os2Tag, NULL, &os2Size);
    if (!ok) return false;
    UniquePtr<uint8_t[]> os2Data(new uint8_t[os2Size]);
    ok = typeface->GetTable(os2Tag, os2Data.get(), &os2Size);
    if (!ok) return false;
    int weight;
    bool italic;
    if (analyzeStyle(os2Data.get(), os2Size, &weight, &italic)) {
        //ALOGD("analyzed weight = %d, italic = %s", weight, italic ? "true" : "false");
        FontStyle style(weight, italic);
        addFontLocked(typeface, style);
        return true;
    } else {
        ALOGD("failed to analyze style");
    }
    return false;
}

void FontFamily::addFont(MinikinFont* typeface, FontStyle style) {
    AutoMutex _l(gMinikinLock);
    addFontLocked(typeface, style);
}

void FontFamily::addFontLocked(MinikinFont* typeface, FontStyle style) {    typeface->RefLocked();
    mFonts.push_back(Font(typeface, style));
    mCoverageValid = false;
}

// Compute a matching metric between two styles - 0 is an exact match
static int computeMatch(FontStyle style1, FontStyle style2) {
    if (style1 == style2) return 0;
    int score = abs(style1.getWeight() - style2.getWeight());
    if (style1.getItalic() != style2.getItalic()) {
        score += 2;
    }
    return score;
}

static FontFakery computeFakery(FontStyle wanted, FontStyle actual) {
    // If desired weight is semibold or darker, and 2 or more grades
    // higher than actual (for example, medium 500 -> bold 700), then
    // select fake bold.
    int wantedWeight = wanted.getWeight();
    bool isFakeBold = wantedWeight >= 6 && (wantedWeight - actual.getWeight()) >= 2;
    bool isFakeItalic = wanted.getItalic() && !actual.getItalic();
    return FontFakery(isFakeBold, isFakeItalic);
}

FakedFont FontFamily::getClosestMatch(FontStyle style) const {
    const Font* bestFont = NULL;
    int bestMatch = 0;
    for (size_t i = 0; i < mFonts.size(); i++) {
        const Font& font = mFonts[i];
        int match = computeMatch(font.style, style);
        if (i == 0 || match < bestMatch) {
            bestFont = &font;
            bestMatch = match;
        }
    }
    FakedFont result;
    if (bestFont == NULL) {
        result.font = NULL;
    } else {
        result.font = bestFont->typeface;
        result.fakery = computeFakery(style, bestFont->style);
    }
    return result;
}

size_t FontFamily::getNumFonts() const {
    return mFonts.size();
}

MinikinFont* FontFamily::getFont(size_t index) const {
    return mFonts[index].typeface;
}

FontStyle FontFamily::getStyle(size_t index) const {
    return mFonts[index].style;
}

const SparseBitSet* FontFamily::getCoverage() {
    if (!mCoverageValid) {
        const FontStyle defaultStyle;
        MinikinFont* typeface = getClosestMatch(defaultStyle).font;
        const uint32_t cmapTag = MinikinFont::MakeTag('c', 'm', 'a', 'p');
        size_t cmapSize = 0;
        bool ok = typeface->GetTable(cmapTag, NULL, &cmapSize);
        UniquePtr<uint8_t[]> cmapData(new uint8_t[cmapSize]);
        ok = typeface->GetTable(cmapTag, cmapData.get(), &cmapSize);
        CmapCoverage::getCoverage(mCoverage, cmapData.get(), cmapSize);
#ifdef VERBOSE_DEBUG
        ALOGD("font coverage length=%d, first ch=%x\n", mCoverage->length(),
                mCoverage->nextSetBit(0));
#endif
        mCoverageValid = true;
    }
    return &mCoverage;
}

}  // namespace android
