// -*- c++ -*-
// Generated by gtkmmproc -- DO NOT MODIFY!
#ifndef _CLUTTERMM_CONTAINER_H
#define _CLUTTERMM_CONTAINER_H


#include <glibmm.h>

/* Copyright (C) 2007 The cluttermm 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 <cluttermm/actor.h>
#include <cluttermm/childmeta.h>
#include <glibmm/interface.h>
#include <glibmm/ustring.h>


#ifndef DOXYGEN_SHOULD_SKIP_THIS
typedef struct _ClutterContainer ClutterContainer;
typedef struct _ClutterContainerClass ClutterContainerClass;
#endif /* DOXYGEN_SHOULD_SKIP_THIS */


namespace Clutter
{ class Container_Class; } // namespace Clutter
namespace Clutter
{


class Container : public Glib::Interface
{
  
#ifndef DOXYGEN_SHOULD_SKIP_THIS

public:
  typedef Container CppObjectType;
  typedef Container_Class CppClassType;
  typedef ClutterContainer BaseObjectType;
  typedef ClutterContainerIface BaseClassType;

private:
  friend class Container_Class;
  static CppClassType container_class_;

  // noncopyable
  Container(const Container&);
  Container& operator=(const Container&);

protected:
  Container(); // you must derive from this class

  /** Called by constructors of derived classes. Provide the result of 
   * the Class init() function to ensure that it is properly 
   * initialized.
   * 
   * @param interface_class The Class object for the derived type.
   */
  explicit Container(const Glib::Interface_Class& interface_class);

public:
  // This is public so that C++ wrapper instances can be
  // created for C instances of unwrapped types.
  // For instance, if an unexpected C type implements the C interface. 
  explicit Container(ClutterContainer* castitem);

protected:
#endif /* DOXYGEN_SHOULD_SKIP_THIS */

public:
  virtual ~Container();

  static void add_interface(GType gtype_implementer);

#ifndef DOXYGEN_SHOULD_SKIP_THIS
  static GType get_type()      G_GNUC_CONST;
  static GType get_base_type() G_GNUC_CONST;
#endif

  ///Provides access to the underlying C GObject.
  ClutterContainer*       gobj()       { return reinterpret_cast<ClutterContainer*>(gobject_); }

  ///Provides access to the underlying C GObject.  
  const ClutterContainer* gobj() const { return reinterpret_cast<ClutterContainer*>(gobject_); }

private:


public:
  
  /** Adds a Clutter::Actor to @a container. This function will emit the
   * "actor-added" signal. The actor should be parented to
   *  @a container. You cannot add a Clutter::Actor to more than one
   * Clutter::Container.
   * 
   * @newin{0,4}
   * @param actor The first Clutter::Actor to add.
   */
  void add_actor(const Glib::RefPtr<Actor>& actor);
  
  /** Removes @a actor from @a container. The actor should be unparented, so
   * if you want to keep it around you must hold a reference to it
   * yourself, using Glib::object_ref(). When the actor has been removed,
   * the "actor-removed" signal is emitted by @a container.
   * 
   * @newin{0,4}
   * @param actor A Clutter::Actor.
   */
  void remove_actor(const Glib::RefPtr<Actor>& actor);

  std::vector<Glib::RefPtr<Actor> >       get_children();
  std::vector<Glib::RefPtr<const Actor> > get_children() const;

  
  /** Lowers @a actor to @a sibling level, in the depth ordering.
   * 
   * @newin{0,6}
   * @param actor The actor to raise.
   * @param sibling The sibling to lower to, or <tt>0</tt> to lower to the bottom.
   */
  void lower_child(const Glib::RefPtr<Actor>& actor, const Glib::RefPtr<Actor>& sibling);
  void lower_child(const Glib::RefPtr<Actor>& actor);
  
  /** Raises @a actor to @a sibling level, in the depth ordering.
   * 
   * @newin{0,6}
   * @param actor The actor to raise.
   * @param sibling The sibling to raise to, or <tt>0</tt> to raise to the top.
   */
  void raise_child(const Glib::RefPtr<Actor>& actor, const Glib::RefPtr<Actor>& sibling);
  void raise_child(const Glib::RefPtr<Actor>& actor);

  
  /** Finds a child actor of a container by its name. Search recurses
   * into any child container.
   * 
   * @newin{0,6}
   * @param child_name The name of the requested child.
   * @return The child actor with the requested name,
   * or <tt>0</tt> if no actor with that name was found.
   */
  Glib::RefPtr<Actor> find_child(const Glib::ustring& child_name);
  
  /** Finds a child actor of a container by its name. Search recurses
   * into any child container.
   * 
   * @newin{0,6}
   * @param child_name The name of the requested child.
   * @return The child actor with the requested name,
   * or <tt>0</tt> if no actor with that name was found.
   */
  Glib::RefPtr<const Actor> find_child(const Glib::ustring& child_name) const;

  /** For instance,
   * void on_foreach(const Glib::RefPtr<Actor>& actor)
   */
  typedef sigc::slot<void, const Glib::RefPtr<Actor>&> SlotForEach;

  void foreach(const SlotForEach& slot);
  

  // not sure the valist stuff is good to wrap in C++
  

  template <class PropertyType> inline
  void set_child_property(const Glib::RefPtr<Actor>& child, const Glib::ustring& property_name, const PropertyType& value);

  
  /** Sets a container-specific property on a child of @a container.
   * 
   * @newin{0,8}
   * @param child A Clutter::Actor that is a child of @a container.
   * @param property The name of the property to set.
   * @param value The value.
   */
  void set_child_property_value(const Glib::RefPtr<Actor>& child, const Glib::ustring& property_name, const Glib::ValueBase& value);

  template <class PropertyType> inline
  void get_child_property(const Glib::RefPtr<const Actor>& child, const Glib::ustring& property_name, PropertyType& value) const;

  void get_child_property_value(const Glib::RefPtr<const Actor>& child, const Glib::ustring& property_name, Glib::ValueBase& value) const;
  

  /** Retrieves the Clutter::ChildMeta which contains the data about the
   *  @a container specific state for @a actor.
   * 
   * @newin{0,8}
   * @param actor A Clutter::Actor that is a child of @a container.
   * @return The Clutter::ChildMeta for the @a actor child
   * of @a container or <tt>0</tt> if the specifiec actor does not exist or the
   * container is not configured to provide Clutter::ChildMeta<!-- -->s.
   */
  Glib::RefPtr<ChildMeta> get_child_meta(const Glib::RefPtr<const Actor>& actor);
  
  /** Retrieves the Clutter::ChildMeta which contains the data about the
   *  @a container specific state for @a actor.
   * 
   * @newin{0,8}
   * @param actor A Clutter::Actor that is a child of @a container.
   * @return The Clutter::ChildMeta for the @a actor child
   * of @a container or <tt>0</tt> if the specifiec actor does not exist or the
   * container is not configured to provide Clutter::ChildMeta<!-- -->s.
   */
  Glib::RefPtr<const ChildMeta> get_child_meta(const Glib::RefPtr<const Actor>& actor) const;

 
  /**
   * @par Prototype:
   * <tt>void on_my_%actor_added(const Glib::RefPtr<Actor>& actor)</tt>
   */

  Glib::SignalProxy1< void,const Glib::RefPtr<Actor>& > signal_actor_added();

  
  /**
   * @par Prototype:
   * <tt>void on_my_%actor_removed(const Glib::RefPtr<Actor>& actor)</tt>
   */

  Glib::SignalProxy1< void,const Glib::RefPtr<Actor>& > signal_actor_removed();


  /**
   * @par Prototype:
   * <tt>void on_my_%child_notify(const Glib::RefPtr<Actor>& actor, GParamSpec* pspec)</tt>
   */

  Glib::SignalProxy2< void,const Glib::RefPtr<Actor>&,GParamSpec* > signal_child_notify();


protected:

  // Only useful as a protected method for derived implementations.
  
  /** Sorts a container's children using their depth. This function should not
   * be normally used by applications.
   * 
   * @newin{0,6}
   */
  void sort_depth_order();

    virtual void add_vfunc(const Glib::RefPtr<Actor>& actor);

    virtual void remove_vfunc(const Glib::RefPtr<Actor>& actor);

    virtual void raise_vfunc(const Glib::RefPtr<Actor>& actor, const Glib::RefPtr<Actor>& sibling);

    virtual void lower_vfunc(const Glib::RefPtr<Actor>& actor, const Glib::RefPtr<Actor>& sibling);

    virtual void sort_depth_order_vfunc();


  // TODO: C++ify?
    virtual void foreach_vfunc(ClutterCallback callback, gpointer user_data);


  /** Emit signal_actor_added().
   */
  void actor_added(const Glib::RefPtr<Actor>& actor);

  /** Emit signal_actor_removed().
   */
  void actor_removed(const Glib::RefPtr<Actor>& actor);

    virtual void create_child_meta_vfunc(const Glib::RefPtr<Actor>& actor);

    virtual void destroy_child_meta_vfunc(const Glib::RefPtr<Actor>& actor);

    virtual Glib::RefPtr<ChildMeta> get_child_meta_vfunc(const Glib::RefPtr<Actor>& actor);


public:

public:
  //C++ methods used to invoke GTK+ virtual functions:

protected:
  //GTK+ Virtual Functions (override these to change behaviour):

  //Default Signal Handlers::
  virtual void on_actor_added(const Glib::RefPtr<Actor>& actor);
  virtual void on_actor_removed(const Glib::RefPtr<Actor>& actor);
  virtual void on_child_notify(const Glib::RefPtr<Actor>& actor, GParamSpec* pspec);


};

#ifndef DOXYGEN_SHOULD_SKIP_THIS

template <class PropertyType> inline
void Container::set_child_property(const Glib::RefPtr<Actor>& child, const Glib::ustring& property_name, const PropertyType& value)
{
  Glib::Value<PropertyType> property_value;
  property_value.init(Glib::Value<PropertyType>::value_type());

  property_value.set(value);
  this->set_child_property_value(child, property_name, property_value);
}

template <class PropertyType> inline
void Container::get_child_property(const Glib::RefPtr<const Actor>& child, const Glib::ustring& property_name, PropertyType& value) const
{
  Glib::Value<PropertyType> property_value;
  property_value.init(Glib::Value<PropertyType>::value_type());

  this->get_child_property_value(child, property_name, property_value);

  value = property_value.get();
}

#endif /* DOXYGEN_SHOULD_SKIP_THIS */

} // namespace Clutter


namespace Glib
{
  /** A Glib::wrap() method for this object.
   * 
   * @param object The C instance.
   * @param take_copy False if the result should take ownership of the C instance. True if it should take a new copy or ref.
   * @result A C++ instance that wraps this C instance.
   *
   * @relates Clutter::Container
   */
  Glib::RefPtr<Clutter::Container> wrap(ClutterContainer* object, bool take_copy = false);

} // namespace Glib


#endif /* _CLUTTERMM_CONTAINER_H */

