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

#include "Resources.h"
#include "SkFontMgr.h"
#include "SkMutex.h"
#include "SkOSFile.h"
#include "SkTestScalerContext.h"
#include "SkUtils.h"
#include "sk_tool_utils.h"

namespace sk_tool_utils {

#include "test_font_monospace.cpp"
#include "test_font_sans_serif.cpp"
#include "test_font_serif.cpp"
#include "test_font_index.cpp"

void release_portable_typefaces() {
    for (int index = 0; index < gTestFontsCount; ++index) {
        SkTestFontData& fontData = gTestFonts[index];
        SkSafeUnref(fontData.fFontCache);
    }
}

SK_DECLARE_STATIC_MUTEX(gTestFontMutex);

SkTypeface* create_font(const char* name, SkTypeface::Style style) {
    SkTestFontData* fontData = NULL;
    const SubFont* sub;
    if (name) {
        for (int index = 0; index < gSubFontsCount; ++index) {
            sub = &gSubFonts[index];
            if (!strcmp(name, sub->fName) && sub->fStyle == style) {
                fontData = &sub->fFont;
                break;
            }
        }
        if (!fontData) {
            // Once all legacy callers to portable fonts are converted, replace this with
            // SK_CRASH();
            SkDebugf("missing %s %d\n", name, style);
            // If we called SkTypeface::CreateFromName() here we'd recurse infinitely,
            // so we reimplement its core logic here inline without the recursive aspect.
            SkAutoTUnref<SkFontMgr> fm(SkFontMgr::RefDefault());
            return fm->legacyCreateTypeface(name, style);
        }
    } else {
        sub = &gSubFonts[gDefaultFontIndex];
        fontData = &sub->fFont;
    }
    SkTestFont* font;
    {
        SkAutoMutexAcquire ac(gTestFontMutex);
        if (fontData->fFontCache) {
            font = SkSafeRef(fontData->fFontCache);
        } else {
            font = SkNEW_ARGS(SkTestFont, (*fontData));
            SkDEBUGCODE(font->fDebugName = sub->fName);
            SkDEBUGCODE(font->fDebugStyle = sub->fStyle);
            fontData->fFontCache = SkSafeRef(font);
        }
    }
    return SkNEW_ARGS(SkTestTypeface, (font, SkFontStyle(style)));
}


SkTypeface* resource_font(const char* name, SkTypeface::Style style) {
    const char* file = NULL;
    if (name) {
        for (int index = 0; index < gSubFontsCount; ++index) {
            const SubFont& sub = gSubFonts[index];
            if (!strcmp(name, sub.fName) && sub.fStyle == style) {
                file = sub.fFile;
                break;
            }
        }
        if (!file) {
            return SkTypeface::CreateFromName(name, style);
        }
    } else {
        file = gSubFonts[gDefaultFontIndex].fFile;
    }
    SkString filepath(GetResourcePath(file));
    if (sk_exists(filepath.c_str())) {
        return SkTypeface::CreateFromFile(filepath.c_str());
    }
    return SkTypeface::CreateFromName(name, style);
}

#ifdef SK_DEBUG
#include <stdio.h>

char const * const gStyleName[] = {
    "",
    "_Bold",
    "_Italic",
    "_BoldItalic",
};

static SkString strip_spaces(const char* str) {
    SkString result;
    int count = (int) strlen(str);
    for (int index = 0; index < count; ++index) {
        char c = str[index];
        if (c != ' ' && c != '-') {
            result += c;
        }
    }
    return result;
}

const char gHeader[] =
"/*\n"
" * Copyright 2014 Google Inc.\n"
" *\n"
" * Use of this source code is governed by a BSD-style license that can be\n"
" * found in the LICENSE file.\n"
" */\n"
"\n"
"// Auto-generated by ";

static FILE* font_header() {
    SkString pathStr(GetResourcePath());
    pathStr = SkOSPath::Join(pathStr.c_str(), "..");
    pathStr = SkOSPath::Join(pathStr.c_str(), "tools");
    pathStr = SkOSPath::Join(pathStr.c_str(), "test_font_data_chars.cpp");
    FILE* out = fopen(pathStr.c_str(), "w");
    fprintf(out, "%s%s\n\n", gHeader, SkOSPath::Basename(__FILE__).c_str());
    return out;
}

void report_used_chars() {
    FILE* out = font_header();
    for (int index = 0; index < gTestFontsCount; ++index) {
        SkTestFontData& fontData = gTestFonts[index];
        SkTestFont* font = fontData.fFontCache;
        if (!font) {
            continue;
        }
        SkString name(strip_spaces(font->debugFontName()));
        fprintf(out, "const char g%s%s[] =\n", name.c_str(), gStyleName[font->fDebugStyle]);
        SkString used("    \"");
        for (int c = ' '; c <= '~'; ++c) {
            int bitOffset = c - ' ';
            if (font->fDebugBits[bitOffset >> 3] & (1 << (bitOffset & 7))) {
                if (c == '"' || c == '\\') {
                    used += '\\';
                }
                used += c;
            }
        }
        if (used.size() > 1) {
            fprintf(out, "%s\"", used.c_str());
        }
        int oIndex = 0;
        while (font->fDebugOverage[oIndex]) {
            uint16_t uni = font->fDebugOverage[oIndex];
            size_t byteCount = SkUTF16_ToUTF8(&uni, 1, NULL);
            SkAutoSTMalloc<10, char> utf8(byteCount);
            SkUTF16_ToUTF8(&uni, 1, utf8);
            for (unsigned byteIndex = 0; byteIndex < byteCount; ++byteIndex) {
                char unibyte = utf8[byteIndex];
                fprintf(out, " \"\\x%02X\"", (unsigned char) unibyte);
            }
            if (++oIndex >= (int) sizeof(font->fDebugOverage)) {
                break;
            }
        }
       fprintf(out, ";\n");
    }
    fclose(out);
}
#endif

}
