#include <gnome.h>
#include <gst/gst.h>
#include <gst/gstregistry.h>

GList *
get_plugins_list_from_class (const gchar *classname)
{
  GList *found_plugins_list = NULL;
  GList *found_plugins_list1 = NULL;
  GList *plugins = NULL, *features = NULL;

  GstRegistry *registry = gst_registry_get_default ();

  plugins = gst_default_registry_get_plugin_list ();

  while (plugins) {
    GstPlugin *plugin = plugins->data;

    features = gst_registry_get_feature_list_by_plugin (registry, gst_plugin_get_name (plugin));

    while (features) {
      GstPluginFeature *feature = GST_PLUGIN_FEATURE(features->data);

      if (GST_IS_ELEMENT_FACTORY (feature)) {
        GstElementFactory *factory = GST_ELEMENT_FACTORY (feature);
        const gchar *name = gst_plugin_feature_get_name (feature);
//        g_printf("%s: %s\n",name,factory->details.klass);

        if (g_strrstr (factory->details.klass, classname)) {
/*          found_plugins_list =
              g_list_append (found_plugins_list,
              (char *) g_strdup (GST_OBJECT_NAME (factory)));*/
//          g_printf("%s: %s\n",name,factory->details.klass);
          GstElement *element;
          element = gst_element_factory_create (factory, NULL);
          if (!element) {
            g_print ("couldn't construct element for some reason\n");
            return NULL;
          }
          const GList *pads;
          GstStaticPadTemplate *padtemplate;
          pads = factory->staticpadtemplates;
          while (pads) {
            padtemplate = (GstStaticPadTemplate *) (pads->data);
            pads= g_list_next (pads);
            if ((padtemplate->direction == GST_PAD_SINK) & (padtemplate->presence == GST_PAD_ALWAYS)) {
              const GstCaps * caps =gst_static_caps_get (&padtemplate->static_caps);
              if ((!gst_caps_is_any (caps)) & (!gst_caps_is_empty (caps))) {
                guint i;
                for (i = 0; i < gst_caps_get_size (caps); i++) {
                  GstStructure *structure = gst_caps_get_structure (caps, i);
                  found_plugins_list =
                      g_list_append (found_plugins_list,
                      (char *) g_strdup (gst_structure_get_name (structure)));
//                  g_printf ("lala: %s\n",gst_structure_get_name (structure));
                }
              }
            }
          }
        }
      }
      features = g_list_next (features);
    }

    gst_plugin_list_free(features);
    plugins = g_list_next (plugins);
  }

  gst_plugin_list_free(plugins);
  if (found_plugins_list) {
    found_plugins_list = g_list_sort(found_plugins_list,(GCompareFunc) g_ascii_strcasecmp);
    char *prev;
    prev=(char *) g_strdup (found_plugins_list->data);
    found_plugins_list = g_list_next(found_plugins_list);
    while(found_plugins_list){
      if(g_ascii_strcasecmp(found_plugins_list->data,prev)) {
//        g_printf ("nono: %s\n",found_plugins_list->data);
        found_plugins_list1 =
            g_list_append (found_plugins_list1,
            (char *) g_strdup (found_plugins_list->data));
      } else {
//        g_printf ("duped: %s\n",found_plugins_list->data);
      }
      prev=(char *) g_strdup (found_plugins_list->data);
      found_plugins_list = g_list_next(found_plugins_list);
    }
  }
  g_list_free(found_plugins_list);
  return found_plugins_list1;
}

int
main (int argc, char **argv)
{
  GList *plugins;
  gst_init(&argc, (char ***) &argv);
  plugins = get_plugins_list_from_class("Codec/Decoder/Audio");
  while (plugins) {
    const char *name = plugins->data;
    g_printf("%s\n",name);
    plugins=g_list_next (plugins);
  }
  return 0;
}
