/*
  Method:   Magick::fonts [ { |fontinfo| } ]
  Purpose:  If called with the optional block, iterates over the fonts,
            otherwise returns an array of Magick::Font objects
*/
VALUE
Magick_fonts(VALUE class)
{
#if defined(HAVE_GETTYPEINFOLIST)   // ImageMagick 6.0.0

    const TypeInfo **type_info;
    unsigned long number_types, x;
    volatile VALUE ary;

#if defined(HAVE_OLD_GETTYPEINFOLIST)
    type_info = GetTypeInfoList("*", &number_types);

#else
    // IM 6.1.3 added an exception argument to GetTypeInfoList
    ExceptionInfo exception;

    GetExceptionInfo(&exception);
    type_info = GetTypeInfoList("*", &number_types, &exception);
    HANDLE_ERROR
#endif

    if (rb_block_given_p())
    {
        for(x = 0; x < number_types; x++)
        {
            rb_yield(Font_from_TypeInfo((TypeInfo *)type_info[x]));
        }
        magick_free(type_info);
        return class;
    }
    else
    {
        ary = rb_ary_new2(number_types);
        for(x = 0; x < number_types; x++)
        {
            rb_ary_push(ary, Font_from_TypeInfo((TypeInfo *)type_info[x]));
        }
        magick_free(type_info);
        return ary;
    }

#else

    const TypeInfo *type_list;
    TypeInfo *type, *next;
    ExceptionInfo exception;
    volatile VALUE ary;

    GetExceptionInfo(&exception);

    type_list = GetTypeInfo("*", &exception);
    HANDLE_ERROR

    // If block, iterate over fonts
    if (rb_block_given_p())
    {
        for (type = (TypeInfo *)type_list; type; type = next)
        {
            next = type->next;  // Protect against recursive calls to GetTypeInfo
            if (! type->stealth)
            {
                rb_yield(Font_from_TypeInfo(type));
            }
        }

        return class;
    }
    else
    {
        ary = rb_ary_new();
        for (type = (TypeInfo *)type_list; type; type = type->next)
        {
            rb_ary_push(ary, Font_from_TypeInfo(type));
        }
        return ary;
    }

#endif
}