/** Pau Freixes pfreixes@milnou.net
 * Example how fonts can be manage in Linux evorniment with most useful tools
 *
 *  - fontconfig for search and matching fonts files
 *      http://www.fontconfig.org/fontconfig-devel/
 *  - freetype2 for load fonts files
 *      http://www.freetype.org/freetype2/documentation.html
 *
 *  Compile form:
 *
 *  gcc -g -I /usr/include/fontconfig -I /usr/include/freetype2/ -o font_demo  main.c -lfontconfig -lfreetype
 *
 */


#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fontconfig.h>
#include <ft2build.h>
#include FT_FREETYPE_H


/** Return Font face object
 * \params font_path char pointer to font path
 * \params font_fache object pointer allocated
 *
 * \returns 0 without error, but -1 with any error
 */
int getFontFace(char * font_path, FT_Face * font_face)
{
    FT_Error error;
    FT_Library library;

    error = FT_Init_FreeType( &library );
    if ( error )
    {
        printf("FreeType library can't initilitzed\n");
        return -1;
    }

    error = FT_New_Face( library, font_path, 0, font_face );
    if ( error == FT_Err_Unknown_File_Format ) 
    { 
        printf ("This font can't be load\n");
        return -1;
    } 
    else if ( error ) 
    { 
        printf ("Some error when loading this font %d\n", error);
        return -1;
    }

    return 0;
}

/** Return Font path with fontconfig lib tool
 * \params font_name char pointer to font name search "Times", "Arial" ...
 * \params font_style char pointer to font style search "Italic", "Bold Italic" ....
 *
 * \returns pointer to font path or NULL if this will be don't found
 */
char * getFontPath(char * font_name, char * font_style)
{
    char * fpath = NULL;
    FcPattern* pattern;
    FcPattern* matched;
    FcResult result = FcResultMatch;
    FcValue v;

    FcConfig * pConfig = FcInitLoadConfigAndFonts();

    if ( ! font_style )
    {
        // make search without font_style
        pattern = FcPatternBuild (0, FC_FAMILY, FcTypeString, font_name, (char *) 0);  
    }
    else
    {
        // make search with font_style
        pattern = FcPatternBuild (0, FC_FAMILY, FcTypeString, font_name, 
                                FC_STYLE, FcTypeString, font_style,
                                (char *) 0);  
    }

    // make a default parameters hat they have not been indicated     
    FcDefaultSubstitute( pattern );

    // Binding pattern with fact configuration
    if( !FcConfigSubstitute( pConfig, pattern, FcMatchFont ) )
    {
        FcPatternDestroy( pattern );
        return NULL;
    }

    // matching font in fontconfig file databases
    matched = FcFontMatch( pConfig, pattern, &result );
    if( result != FcResultNoMatch )
    {
        result = FcPatternGet( matched, FC_FILE, 0, &v );
        fpath = (char *) malloc (strlen((const char *)v.u.s));
        strcpy(fpath, (const char*) v.u.s);
    }
    else
    {
        FcPatternDestroy( pattern );
        FcPatternDestroy( matched );
        return NULL;
    }

    FcPatternDestroy( pattern );
    FcPatternDestroy( matched );
    return fpath;
}


void usage()
{
    printf("fontdemo <font name> [<style name>]\n");
}

int main ( int argc, char ** argv )
{
    char * font_path = NULL;
    char * name_font;
    char * style_font;
    FT_Face font_face;


    if ( ( argc < 2 ) || ( argc > 3 ) )
    {
        usage();
        exit(1);
    }

    // recollecting params

    name_font = argv[1];
    style_font = ( argc == 3 ? argv[2] : NULL); 

    // return font path with fontconfig lib tools
    font_path = getFontPath(name_font, style_font);
    if ( ! font_path )
    {
        printf("This font can not be localitzed\n");
        exit(1);
    }

    printf("Matched pattern font in file %s\n", font_path);

    // load new font with freetype lib tools
    if ( getFontFace(font_path, &font_face) != 0)
    {
        printf("Error when load font\n");
        exit(1);
    }

    printf("Loaded Font with Faimily Name = %s and Style Name = %s, with %d faces\n", font_face->family_name, font_face->style_name,font_face->num_faces);
   

    // testing code
    printf("Name file : %s\n", (const char *) font_face->stream->pathname.pointer);


    // deallocating memory space
    FT_Done_Face(font_face);
    free(font_path);
    

}