/* gstreamermm - a C++ wrapper for gstreamer
 *
 * Copyright 2008 The gstreamermm Development Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <gst/gstregistry.h>
#include <gstreamermm/pluginfeature.h>
#include <gstreamermm/plugin.h>
_PINCLUDE(gstreamermm/private/object_p.h)

static gboolean Registry_Plugin_Filter_gstreamermm_callback(GstPlugin* plugin, void* data)
{
  Gst::Plugin::SlotFilter* the_slot = static_cast<Gst::Plugin::SlotFilter*>(data);

  #ifdef GLIBMM_EXCEPTIONS_ENABLED
  try
  {
  #endif //GLIBMM_EXCEPTIONS_ENABLED
    bool result = (*the_slot)(Glib::wrap(plugin, true));

    //Delete the once executing slot before returning result
    delete the_slot;

    return result;
  #ifdef GLIBMM_EXCEPTIONS_ENABLED
  }
  catch(...)
  {
    Glib::exception_handlers_invoke();
  }
  #endif //GLIBMM_EXCEPTIONS_ENABLED
}

static gboolean Registry_PluginFeature_Filter_gstreamermm_callback(GstPluginFeature* feature, void* data)
{
  Gst::PluginFeature::SlotFilter* the_slot = static_cast<Gst::PluginFeature::SlotFilter*>(data);

  #ifdef GLIBMM_EXCEPTIONS_ENABLED
  try
  {
  #endif //GLIBMM_EXCEPTIONS_ENABLED
    bool result = (*the_slot)(Glib::wrap(feature, true));

    //Delete the once executing slot before returning result
    delete the_slot;

    return result;
  #ifdef GLIBMM_EXCEPTIONS_ENABLED
  }
  catch(...)
  {
    Glib::exception_handlers_invoke();
  }
  #endif //GLIBMM_EXCEPTIONS_ENABLED
}

namespace Gst
{

Glib::ListHandle< Glib::RefPtr<Gst::Plugin> >
Registry::get_plugin_list(const Plugin::SlotFilter& filter, bool first)
{
  Plugin::SlotFilter* slot_copy = new Plugin::SlotFilter(filter);
  GList* list = gst_registry_plugin_filter(gobj(), &Registry_Plugin_Filter_gstreamermm_callback, first, slot_copy);
  return Glib::ListHandle< Glib::RefPtr<Gst::Plugin> >(list,
    Glib::OWNERSHIP_DEEP);
}

Glib::ListHandle< Glib::RefPtr<const Gst::Plugin> >
Registry::get_plugin_list(const Plugin::SlotFilter& filter, bool first) const
{
  Plugin::SlotFilter* slot_copy = new Plugin::SlotFilter(filter);
  GList* list = gst_registry_plugin_filter(const_cast<GstRegistry*>(gobj()),
    &Registry_Plugin_Filter_gstreamermm_callback, first, slot_copy);
  return Glib::ListHandle< Glib::RefPtr<const Gst::Plugin> >(list,
    Glib::OWNERSHIP_DEEP);
}

Glib::ListHandle< Glib::RefPtr<Gst::PluginFeature> >
Registry::get_feature_list(const PluginFeature::SlotFilter& filter, bool first)
{
  PluginFeature::SlotFilter* slot_copy = new PluginFeature::SlotFilter(filter);
  GList* list = gst_registry_feature_filter(gobj(), &Registry_PluginFeature_Filter_gstreamermm_callback, first, slot_copy);
  return Glib::ListHandle< Glib::RefPtr<Gst::PluginFeature> >(list,
    Glib::OWNERSHIP_DEEP);
}

Glib::ListHandle< Glib::RefPtr<const Gst::PluginFeature> >
Registry::get_feature_list(const PluginFeature::SlotFilter& filter,
  bool first) const
{
  PluginFeature::SlotFilter* slot_copy = new PluginFeature::SlotFilter(filter);
  GList* list = gst_registry_feature_filter(const_cast<GstRegistry*>(gobj()),
    &Registry_PluginFeature_Filter_gstreamermm_callback, first, slot_copy);
  return Glib::ListHandle< Glib::RefPtr<const Gst::PluginFeature> >(list,
    Glib::OWNERSHIP_DEEP);
}

#ifdef USE_BINARY_REGISTRY

bool Registry::binary_read_cache(const Glib::ustring& location)
{
  return gst_registry_binary_read_cache(gobj(), location.c_str());
}

bool Registry::binary_write_cache(const Glib::ustring& location) const
{
  return gst_registry_binary_write_cache(const_cast<GstRegistry*>(gobj()),
    location.c_str());
}

#else

bool Registry::xml_read_cache(const Glib::ustring& location)
{
  return gst_registry_xml_read_cache(gobj(), location.c_str());
}

bool Registry::xml_write_cache(const Glib::ustring& location) const
{
  return gst_registry_xml_write_cache(const_cast<GstRegistry*>(gobj()),
    location.c_str());
}

#endif

} //namespace Gst
