/*
 * Copyright 2021 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/utils/SkOrderedFontMgr.h"

#include "include/core/SkData.h" // IWYU pragma: keep
#include "include/core/SkFontStyle.h"
#include "include/core/SkStream.h" // IWYU pragma: keep
#include "include/core/SkTypeface.h" // IWYU pragma: keep

#include <utility>

class SkString;
struct SkFontArguments;

SkOrderedFontMgr::SkOrderedFontMgr() {}
SkOrderedFontMgr::~SkOrderedFontMgr() {}

void SkOrderedFontMgr::append(sk_sp<SkFontMgr> fm) {
    fList.push_back(std::move(fm));
}

int SkOrderedFontMgr::onCountFamilies() const {
    int count = 0;
    for (const auto& fm : fList) {
        count += fm->countFamilies();
    }
    return count;
}

void SkOrderedFontMgr::onGetFamilyName(int index, SkString* familyName) const {
    for (const auto& fm : fList) {
        const int count = fm->countFamilies();
        if (index < count) {
            return fm->getFamilyName(index, familyName);
        }
        index -= count;
    }
}

sk_sp<SkFontStyleSet> SkOrderedFontMgr::onCreateStyleSet(int index) const {
    for (const auto& fm : fList) {
        const int count = fm->countFamilies();
        if (index < count) {
            return fm->createStyleSet(index);
        }
        index -= count;
    }
    return nullptr;
}

sk_sp<SkFontStyleSet> SkOrderedFontMgr::onMatchFamily(const char familyName[]) const {
    for (const auto& fm : fList) {
        if (auto fs = fm->matchFamily(familyName)) {
            return fs;
        }
    }
    return nullptr;
}

sk_sp<SkTypeface> SkOrderedFontMgr::onMatchFamilyStyle(const char family[],
                                                       const SkFontStyle& style) const {
    for (const auto& fm : fList) {
        if (auto tf = fm->matchFamilyStyle(family, style)) {
            return tf;
        }
    }
    return nullptr;
}

sk_sp<SkTypeface> SkOrderedFontMgr::onMatchFamilyStyleCharacter(
    const char familyName[], const SkFontStyle& style,
    const char* bcp47[], int bcp47Count,
    SkUnichar uni) const
{
    for (const auto& fm : fList) {
        if (auto tf = fm->matchFamilyStyleCharacter(familyName, style, bcp47, bcp47Count, uni)) {
            return tf;
        }
    }
    return nullptr;
}

// All of these are defined to fail by returning null

sk_sp<SkTypeface> SkOrderedFontMgr::onMakeFromData(sk_sp<SkData>, int ttcIndex) const {
    return nullptr;
}

sk_sp<SkTypeface> SkOrderedFontMgr::onMakeFromStreamIndex(std::unique_ptr<SkStreamAsset>,
                                                          int ttcIndex) const {
    return nullptr;
}

sk_sp<SkTypeface> SkOrderedFontMgr::onMakeFromStreamArgs(std::unique_ptr<SkStreamAsset>,
                                                         const SkFontArguments&) const {
    return nullptr;
}

sk_sp<SkTypeface> SkOrderedFontMgr::onMakeFromFile(const char path[], int ttcIndex) const {
    return nullptr;
}

sk_sp<SkTypeface> SkOrderedFontMgr::onLegacyMakeTypeface(const char family[], SkFontStyle) const {
    return nullptr;
}
