#include "fontcache.h"

/**
 * Linux/Mac:
 *   The strings listed below will be submitted to fontconfig, in this priority,
 *   with point size specified, and it will try to find something that matches. If it doesn't
 *   find anything, it will try the next font.
 *
 *   If fontconfig can't find any that look like any of the fonts you specify, (unlikely with the defaults)
 *   you must find one that it will. Run `fc-match <test_font_name>` to test you font name, and then modify
 *   this array with that name string. If you'd like, run `fc-list` to list available fonts.
 *   Note:
 *     - The fc-* commands are a CLI frontend for fontconfig,
 *       so anything that works there will work in this graphics library.
 *     - The font returned by fontconfig may not be the same, but will look similar.
 *
 * Windows:
 *   Something with similar effect will be done, but it is harder to tell what will happen.
 *   Check your installed fonts if the program exits immediately or while changing font size.
 *
 */
const char* const fontname_config[]{
    "helvetica",
    "lucida sans",
    "schumacher"
};

/******************************************
 * begin FontCache function definitions *
 ******************************************/

#ifdef X11
#include "graphics_state.h"
void FontCache::close_font(font_ptr font) {
    XftFontClose(t_x11_state::getInstance()->display, font);
}
#elif defined WIN32
void FontCache::close_font(font_ptr font) {
    free(font);
}
void WIN32_DELETE_ERROR(); //Forward declaration
#else
void FontCache::close_font(font_ptr /*font*/) {
}
#endif

/**
 * Loads the font with given attributes, and puts the pointer to in in put_font_ptr_here
 */
font_ptr FontCache::do_font_loading(
        
#if defined X11 || defined WIN32
        int pointsize, int degrees
#else
        int /*pointsize*/, int /*degrees*/
#endif
        ) {

#if defined X11 || defined WIN32
    bool success = false;
#endif
    font_ptr retval = nullptr;

#ifdef X11
    for (int ifont = 0; ifont < NUM_FONT_TYPES; ifont++) {

#ifdef VERBOSE
        printf("Loading font: %s-%d\n", fontname_config[ifont], pointsize);
#endif

        XftMatrix font_matrix;
        XftMatrixInit(&font_matrix);
        if (degrees != 0) {
            XftMatrixRotate(&font_matrix, cos(PI * (degrees) / 180), sin(PI * degrees / 180));
        }

        /* Load font and get font information structure. */
        retval = XftFontOpen(
            t_x11_state::getInstance()->display, t_x11_state::getInstance()->screen_num,
            XFT_FAMILY, XftTypeString, fontname_config[ifont],
            XFT_SIZE, XftTypeDouble, static_cast<double>(pointsize),
            XFT_MATRIX, XftTypeMatrix, &font_matrix,
            NULL // (sentinel)
            );

        if (retval == nullptr) {
#ifdef VERBOSE
            fprintf(stderr, "Cannot open font %s", fontname_config[ifont]);
            if (degrees != 0) {
                fprintf(stderr, "with rotation %f deg", degrees);
            }
            printf("\n");
#endif
        } else {
            success = true;
            break;
        }
    }
    if (success == false) {
        printf("Error in load_font: fontconfig couldn't find any font of pointsize %d.\n", pointsize);
        if (degrees != 0) {
            printf("and rotation %d deg", degrees);
        }
        printf("Use `fc-list` to list available fonts, `fc-match` to test, and then modify\n");
        printf("the font config array in easygl_constants.h .\n");
        exit(1);
    }
#elif defined WIN32
    LOGFONT *lf = retval = (LOGFONT*) malloc(sizeof (LOGFONT));
    ZeroMemory(lf, sizeof (LOGFONT));
    // lfHeight specifies the desired height of characters in logical units.
    // A positive value of lfHeight will request a font that is appropriate
    // for a line spacing of lfHeight. On the other hand, setting lfHeight
    // to a negative value will obtain a font height that is compatible with
    // the desired pointsize.
    lf->lfHeight = -pointsize;
    lf->lfWeight = FW_NORMAL;
    lf->lfCharSet = ANSI_CHARSET;
    lf->lfOutPrecision = OUT_DEFAULT_PRECIS;
    lf->lfClipPrecision = CLIP_DEFAULT_PRECIS;
    lf->lfQuality = PROOF_QUALITY;
    lf->lfPitchAndFamily = VARIABLE_PITCH | FF_SWISS;
    lf->lfEscapement = (LONG) degrees * 10;
    lf->lfOrientation = (LONG) degrees * 10;
    HFONT testfont;

	// Convert lf->lfFaceName from a char_t* to a wc_chart*
	// "The length of this string must not exceed 32 TCHAR values" 
	// Source: https://msdn.microsoft.com/en-us/library/windows/desktop/dd145037(v=vs.85).aspx
	wchar_t wcFaceName[32];
	std::mbstowcs(wcFaceName, lf->lfFaceName, 32);

    for (int ifont = 0; ifont < NUM_FONT_TYPES; ++ifont) {
        MultiByteToWideChar(CP_UTF8, 0, fontname_config[ifont], -1,
            wcFaceName, sizeof (lf->lfFaceName) / sizeof (wchar_t));

        testfont = CreateFontIndirect(lf);
        if (testfont == NULL) {
#ifdef VERBOSE
            fprintf(stderr, "Couldn't open font %s in pointsize %d.\n",
                fontname_config[ifont], pointsize);
#endif
            continue;
        }

        if (DeleteObject(testfont) == 0) {
            WIN32_DELETE_ERROR();
        } else {
            success = true;
            break;
        }
    }
    if (success == false) {
        printf("Error in load_font: Windows couldn't find any font of pointsize %d.\n", pointsize);
        printf("check installed fonts, and then modify\n");
        printf("the font config array in easygl_constants.h .\n");
        exit(1);
    }
#endif
    return retval;
}

void FontCache::clear() {
    for (
        auto iter = descriptor2font_zeros.begin();
        iter != descriptor2font_zeros.end();
        ++iter
        ) {
        close_font(iter->second);
    }
    order_zeros.clear();
    descriptor2font_zeros.clear();

    for (
        auto iter = descriptor2font_rotated.begin();
        iter != descriptor2font_rotated.end();
        ++iter
        ) {
        close_font(iter->second);
    }
    order_rotated.clear();
    descriptor2font_rotated.clear();
}

font_ptr FontCache::get_font_info(size_t pointsize, int degrees) {
    if (degrees == 0) {
        return get_font_info(
            pointsize, degrees,
            order_zeros, descriptor2font_zeros, FONT_CACHE_SIZE_FOR_ZEROS
            );
    } else {
        return get_font_info(
            pointsize, degrees,
            order_rotated, descriptor2font_rotated, FONT_CACHE_SIZE_FOR_ROTATED
            );
    }
}

template<class queue_type, class map_type>
font_ptr FontCache::get_font_info(
    size_t pointsize, int degrees,
    queue_type& orderqueue, map_type& descr2font_map, size_t max_size) {

    auto search_result = descr2font_map.find(std::make_pair(pointsize, degrees));
    if (search_result == descr2font_map.end()) {

        if (orderqueue.size() + 1 > max_size) {
            // if too many fonts, remove the oldest font from the cache.
            font_descriptor fontdesc_to_remove = orderqueue.back();
            auto font_to_remove = descr2font_map.find(fontdesc_to_remove);

            if (font_to_remove != descr2font_map.end()) {
                close_font(font_to_remove->second);
            }

            descr2font_map.erase(font_to_remove);
            orderqueue.pop_back();
            puts("font cache overflow");
        }

        font_ptr new_font = do_font_loading(pointsize, degrees);
        font_descriptor new_font_desc = std::make_pair(pointsize, degrees);
        orderqueue.push_front(new_font_desc);
        descr2font_map.insert(std::make_pair(new_font_desc, new_font));
        return new_font;
    } else {
        return search_result->second;
    }
}


