/*  Inti: Integrated Foundation Classes
 *  Copyright (C) 2002 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/colorselection.h
//! @brief A GtkColorSelection and GtkColorSelectionDialog C++ wrapper interface.
//!
//! Provides ColorSelection, a widget that is used to select a color,
//! and ColorSelectionDialog, a standard dialog that allows the user
//! to select a color much like the FileSelection provides a standard
//! dialog for file selection.

#ifndef INTI_GTK_COLOR_SELECTION_H
#define INTI_GTK_COLOR_SELECTION_H

#ifndef INTI_GTK_VBOX_H
#include <inti/gtk/box.h>
#endif

#ifndef INTI_GTK_DIALOG_H
#include <inti/gtk/dialog.h>
#endif

#ifndef __GTK_COLOR_SELECTION_H__
#include <gtk/gtkcolorsel.h>
#endif

#ifndef __GTK_COLOR_SELECTION_DIALOG_H__
#include <gtk/gtkcolorseldialog.h>
#endif

namespace Inti {

namespace Gdk { 
class Color; 
}

namespace Gtk {

class Button;
class ColorSelectionClass;
class ColorSelectionDialogClass;

//! @class ColorSelection colorselection.h inti/gtk/colorselection.h
//! @brief A GtkColorSelection C++ wrapper class.
//!
//! The ColorSelection is a widget that is used to select a color. It consists of a color wheel
//! and number of sliders and entry boxes for color parameters such as hue, saturation, value,
//! red, green, blue, and opacity. It is found in the standard color selection dialog box
//! ColorSelectionDialog.

class ColorSelection : public VBox
{
	friend class G::Object;
	friend class ColorSelectionClass;

	ColorSelection(const ColorSelection&);
	ColorSelection& operator=(const ColorSelection&);
	
protected:
//! @name Constructors
//! @{
	
	explicit ColorSelection(GtkColorSelection *color_selection, bool reference = false);
	//!< Construct a new ColorSelection from an existing GtkColorSelection.
	//!< @param color_selection A pointer to a GtkColorSelection.
	//!< @param reference Set false if the initial reference count is floating, set true if it's not.
	//!<
	//!< <BR>The <EM>color_selection</EM> can be a newly created GtkColorSelection or an existing
	//!< GtkColorSelection. (see G::Object::Object).

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

	virtual void on_color_changed();
	//!< Called when the color changes in the ColorSelection according to its update policy.

//! @}
//  Properties

	typedef G::Property<bool> HasOpacityControlPropertyType;
	typedef G::PropertyProxy<G::Object, HasOpacityControlPropertyType> HasOpacityControlPropertyProxy;
	static const HasOpacityControlPropertyType has_opacity_control_property;

	typedef G::Property<bool> HasPalettePropertyType;
	typedef G::PropertyProxy<G::Object, HasPalettePropertyType> HasPalettePropertyProxy;
	static const HasPalettePropertyType has_palette_property;

	typedef G::Property<Pointer<Gdk::Color> > CurrentColorPropertyType;
	typedef G::PropertyProxy<G::Object, CurrentColorPropertyType> CurrentColorPropertyProxy;
	static const CurrentColorPropertyType current_color_property;

	typedef G::Property<unsigned int> CurrentAlphaPropertyType;
	typedef G::PropertyProxy<G::Object, CurrentAlphaPropertyType> CurrentAlphaPropertyProxy;
	static const CurrentAlphaPropertyType current_alpha_property;

//  Signals

	typedef G::Signal0<void> ColorChangedSignalType;
	typedef G::SignalProxy<TypeInstance, ColorChangedSignalType> ColorChangedSignalProxy;
	static const ColorChangedSignalType color_changed_signal;

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

	ColorSelection();
	//!< Construct a new ColorSelection.

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

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

	GtkColorSelectionClass* gtk_color_selection_class() const;
	//!< Get a pointer to the GtkColorSelectionClass structure.

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

	bool get_has_opacity_control() const;
	//!< Returns true if the ColorSelection has an opacity control.

	bool get_has_palette() const;
	//!< Returns true if the ColorSelection has a color palette.

	Gdk::Color get_current_color() const;
	//!< Gets the currently selected color.

	unsigned short get_current_alpha() const;
	//!< Returns the maximum number of palette colors.

	Gdk::Color get_previous_color() const;
	//!< Retrieves the original color value.

	unsigned short get_previous_alpha() const;
	//!< Returns the previous alpha value.

	bool is_adjusting() const;
	//!< Returns true if the user is currently dragging a color around,
	//!< and false if the selection has stopped.

//! @}
	static bool palette_from_string(const String& str, std::vector<Pointer<Gdk::Color> >& colors);
	//!< Parses a color palette string; the string is a colon-separated list of color names
	//!< readable by Gdk::Color::parse().
	//!< @param str A String encoding a color palette.
	//!< @param colors A vector to fill with smart pointers to a newly allocated Gdk::Color.
	//!< @return <EM>true</EM> if a palette was successfully parsed.

	static String palette_to_string(const std::vector<Pointer<Gdk::Color> >& colors);
	//!< Encodes a palette as a string, useful for persistent storage.
	//!< @param colors A vector of colors.
	//!< @return A String encoding the palette.

//! @name Methods
//! @{

	void set_has_opacity_control(bool has_opacity);
	//!< Sets the ColorSelection to use or not use opacity.
	//!< @param has_opacity <EM>true</EM> if the ColorSelection can set the opacity,
	//!< <EM>false</EM> otherwise.
	
	void set_has_palette(bool has_palette);
	//!< Shows and hides the palette based upon the value of has_palette.
	//!< @param has_palette <EM>true</EM> if the palette is to be visible, <EM>false</EM> otherwise.

	void set_current_color(const Gdk::Color& color);
	//!< Sets the current color to be color. 
	//!< @param color A Gdk::Color to set the current color with.
	//!<
	//!< <BR>The first time this is called, it will also set the original color to be color too.

	void set_current_alpha(unsigned short alpha);
	//!< Sets the current opacity to be alpha.
	//!< @param alpha An integer between 0 and 65535.
	//!<
	//!< <BR>The first time this is called, it will also set the original opacity to be alpha too.

	void set_previous_color(const Gdk::Color& color);
	//!< Sets the 'previous' color to be color. 
	//!< @param color A Gdk::Color to set the previous color with.
	//!<
	//!< <BR>This method should be called with some hesitations, as it might seem confusing to 
	//!< have that color change. Calling set_current_color() will also set this color the first
	//!< time it is called.

	void set_previous_alpha(unsigned short alpha);
	//!< Sets the 'previous' alpha to be alpha. 
	//!< @param alpha An integer between 0 and 65535.
	//!<
	//!< <BR>This method should be called with some hesitations, as it might seem confusing to
	//!< have that alpha change.
	
//! @}
//! @name Property Proxies
//! @{

	const HasOpacityControlPropertyProxy prop_has_opacity_control()
	{
		return HasOpacityControlPropertyProxy(this, &has_opacity_control_property);
	}
	//!< Whether the color selector should allow setting opacity (bool : Read / Write).

	const HasPalettePropertyProxy prop_has_palette()
	{
		return HasPalettePropertyProxy(this, &has_palette_property);
	}
	//!< Whether a palette should be used (bool : Read / Write).

	const CurrentColorPropertyProxy prop_current_color()
	{
		return CurrentColorPropertyProxy(this, &current_color_property);
	}
	//!< The current color (Pointer<Gdk::Color> : Read / Write).

	const CurrentAlphaPropertyProxy prop_current_alpha()
	{
		return CurrentAlphaPropertyProxy(this, &current_alpha_property);
	}
	//!< The current opacity value; 0 fully transparent, 65535 fully opaque (unsigned int : Read / Write).

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

	const ColorChangedSignalProxy sig_color_changed()
	{
		return ColorChangedSignalProxy(this, &color_changed_signal);
	}
	//!< Connect to the color_changed_signal; emitted when the color changes in the
	//!< ColorSelection according to its update policy.

//! @}
};

//! @class ColorSelectionDialog colorselection.h inti/gtk/colorselection.h
//! @brief A GtkColorSelectionDialog C++ wrapper class.
//! 
//! The ColorSelectionDialog provides a standard dialog which allows the user to select a
//! color much like the FileSelection provides a standard dialog for file selection.

class ColorSelectionDialog : public Dialog
{
	friend class G::Object;
	friend class ColorSelectionDialogClass;

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

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

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

	ColorSelectionDialog();
	//!< Construct a new ColorSelectionDialog with the default title.

	explicit ColorSelectionDialog(const String& title);
	//!< Construct a new ColorSelectionDialog with the specified title.
	//!< @param title A String containing the title text for the dialog.

	virtual ~ColorSelectionDialog();
	//!< Destructor.

//! @}
//! @name Accessors
//! @{

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

	GtkColorSelectionDialogClass* gtk_color_selection_dialog_class() const;
	//!< Get a pointer to the GtkColorSelectionDialogClass structure.

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

	ColorSelection* colorsel() const;
	//!< Returns the ColorSelection widget contained within the dialog.
	//!< Use this widget and its get_current_color() method to gain access to the selected color.
	//!< Connect a slot to this widget's color_changed_signal, to be notify when the color changes.

	Button* ok_button() const;
	//!< Returns the OK button widget contained within the dialog. Connect a slot for the clicked_signal.

	Button* cancel_button() const;
	//!< Returns the cancel button widget contained within the dialog. Connect a slot for the clicked_signal.

	Button* help_button() const;
	//!< Returns the help button widget contained within the dialog. Connect a slot for the clicked_signal.

//! @}
};

} // namespace Gtk

} // namespace Inti

#endif // INTI_GTK_COLOR_SELECTION_DIALOG_H

