/*  Inti: Integrated Foundation Classes
 *  Copyright (C) 2002-2003 The Inti Development Team.
 *  Copyright (C) 2000 Red Hat, Inc.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 Library General Public License for more details.
 *
 *  You should have received a copy of the GNU Library General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
 
//! @file inti/gtk/plug.h
//! @brief A GtkPlug C++ wrapper interface.
//!
//! Provides Plug, which together with Socket, provides the ability to embed widgets
//! from one process into another process in a fashion that is transparent to the user.

#ifndef INTI_GTK_PLUG_H
#define INTI_GTK_PLUG_H

#ifndef INTI_GTK_WINDOW_H
#include <inti/gtk/window.h>
#endif

#ifndef __GTK_PLUG_H__
#include <gtk/gtkplug.h>
#endif

namespace Inti {

namespace Gdk {
class Display;
}

namespace Gtk {

class PlugClass;
class Socket;

//! @class Plug plug.h inti/gtk/plug.h
//! @brief A GtkPlug C++ wrapper class.
//!
//! Together with Socket, Plug provides the ability to embed widgets from one process
//! into another process in a fashion that is transparent to the user. One process
//! creates a Socket widget and, passes the ID of that widgets window to the other
//! process, which then creates a Plug with that window ID. Any widgets contained in
//! the Plug then will appear inside the first applications window.

class Plug : public Window
{
	friend class G::Object;
	friend class PlugClass;

	Plug(const Plug&);
	Plug& operator=(const Plug&);
	
protected:
//! @name Constructors
//! @{

	explicit Plug(GtkPlug *plug, bool reference = false);
	//!< Construct a new Plug from an existing GtkPlug.
	//!< @param plug A pointer to a GtkPlug.
	//!< @param reference Set false if the initial reference count is floating, set true if it's not.
	//!<
	//!< <BR>The <EM>plug</EM> can be a newly created GtkPlug or an existing
	//!< GtkPlug (see G::Object::Object).

//! @}
//! @name Signal Handlers
//! @{

	virtual void on_embedded();
	//!< Called when a plug is embedded into a socket.

//! @}
//  Signals

	typedef G::Signal0<void> EmbeddedSignalType;
	typedef G::SignalProxy<TypeInstance, EmbeddedSignalType> EmbeddedSignalProxy;
	static const EmbeddedSignalType embedded_signal;

public:
//! @name Constructors
//! @{

	Plug(GdkNativeWindow socket_id, const Gdk::Display *display = 0);
	//!< Constructs a new plug widget inside the Socket identified by socket_id.
	//!< @param socket_id The XID of the socket's window.
	//!< @param display The Gdk::Display on which socket_id is displayed, or null for the default display.
	//!<
	//!< <BR>If socket_id is 0, the plug is left "unplugged" and can later be plugged
	//!< into a Socket by Gtk::Socket::add_id().
	//!< 
	//!< <B>Note:</B> The default GDK display is the only display in the absence of MultiHead support.

	virtual ~Plug();
	//!< Destructor.
	
//! @}
//! @name Accessors
//! @{

	GtkPlug* gtk_plug() const { return (GtkPlug*)instance; }
	//!< Get a pointer to the GtkPlug structure.

	GtkPlugClass* gtk_plug_class() const;
	//!< Get a pointer to the GtkPlugClass structure.

	operator GtkPlug* () const;
	//!< Conversion operator; safely converts a Plug to a GtkPlug pointer.

	bool has_socket() const;
	//!< Returns true if this plug is embedded into a socket.

	Gdk::Window* socket_window() const;
	//!< Returns the socket window the plug is embedded into, or null if it is not embedded.

	bool same_app() const;
	//!< Return true if the plug is embedded into a socket in the same application.
	
	GdkNativeWindow get_id() const;
	//!< Gets the window ID of a Plug widget, which can then be used to embed this window
	//!< inside another window, for instance with Gtk::Socket::add_id().
	//!< @return The window ID for the plug.

//! @}
//! @name Methods
//! @{

	void add_to_socket(Socket& socket);
	//!< Adds a plug to a socket within the same application.
	//!< @param socket: A Socket.

	void remove_from_socket(Socket& socket);
	//!< Removes a plug from a socket within the same application.
	//!< @param socket: A Socket.

//! @}
//! @name Signal Proxies

	const EmbeddedSignalProxy sig_embedded()
	{
		return EmbeddedSignalProxy(this, &embedded_signal);
	}
	//!< Connect to the embedded_signal; emitted when a plug is embedded into a socket.
	
//! @}
};

} // namespace Gtk

} // namespace Inti

#endif // INTI_GTK_PLUG_H

