/*  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/treesortable.h
//! @brief A GtkTreeSortable C++ wrapper interface.
//! 
//! Provides TreeSortable, an object that defines a generic interface for sorting a model.

#ifndef INTI_GTK_TREE_SORTABLE_H
#define INTI_GTK_TREE_SORTABLE_H

#ifndef INTI_G_TYPE_H
#include <inti/glib/type.h>
#endif

#ifndef INTI_GTK_ENUMS_H
#include <inti/gtk/enums.h>
#endif

#ifndef __GTK_TREE_SORTABLE_H__
#include <gtk/gtktreesortable.h>
#endif

#ifndef INTI_SLOT_H
#include <inti/slot.h>
#endif

namespace Inti {

namespace Gtk {

class TreeIter;
class TreeModel;
class TreeSortableIface;

//! @class TreeSortable treesortable.h inti/gtk/treesortable.h
//! @brief A GtkTreeSortable C++ wrapper class.
//!
//! The TreeSortable interface defines a generic interface for sorting a model.
//! It is an abstract interface, and is designed to be usable with any derived 
//! class. The programmer just has to multiplely inherit this interface on their
//! own model for it to be sortable. To make life easier two generic sortable 
//! models are already provided, ListStore and TreeStore.

class TreeSortable : public virtual G::TypeInterface
{
	friend class TreeSortableIface;

protected:
//! @name Constructors
//! @{

	virtual ~TreeSortable() = 0;
	//!< Destructor.

//! @}
//  Override these do_ methods when you want to change the default behaviour of the GtkTreeSortable.

	virtual bool do_get_sort_column_id(int *sort_column_id, GtkSortType *order);

	virtual void do_set_sort_column_id(int sort_column_id, GtkSortType order);

	virtual void do_set_sort_func(int sort_column_id, GtkTreeIterCompareFunc func, void *data, GtkDestroyNotify destroy);

	virtual void do_set_default_sort_func(GtkTreeIterCompareFunc func, void *data, GtkDestroyNotify destroy);

	virtual bool do_has_default_sort_func();

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

	virtual void on_sort_column_changed();
	//!< Called whenever the current sort column is changed.
	
//! @}
//  Signals

	typedef G::Signal0<void> SortColumnChangedSignalType;
	typedef G::SignalProxy<TypeInstance, SortColumnChangedSignalType> SortColumnChangedSignalProxy;
	static const SortColumnChangedSignalType sort_column_changed_signal;

public:
	typedef Slot3<int, const TreeModel&, const TreeIter*, const TreeIter*> TreeIterCompareSlot;
	//!< Signature of the callback slot to be used for comparison when sorting.
	//!< <B>Example:</B> Method signature for TreeIterCompareSlot.
	//!< @code
	//!< int method(const TreeModel& model, const TreeIter *a, const TreeIter *b);
	//!<
	//!< // model: The TreeModel being sorted.
	//!< // a: A TreeIter.
	//!< // b: Another TreeIter.
	//!< // return: -1 if "a" comes before "b" in the tree, 1 if "a" comes after "b" in
	//!< //         the tree and 0 if a and b point to the same location in the tree.
	//!< @endcode

//! @name Accessors
//! @{

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

	GtkTreeSortableIface* gtk_tree_sortable_iface() const;
	//!< Get a pointer to the GtkTreeSortableIface structure.

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

	bool get_sort_column_id(int *sort_column_id, SortType *order) const;
	//!< Fills in <EM>sort_column_id</EM> and <EM>order</EM> with the current sort column
	//!< and the order, if applicable. 
	//!< @param sort_column_id The sort column id to be filled in.
	//!< @param order The SortType to be filled in. 
	//!< @return <EM>true</EM> if the sort column has been set.
	//!<	
	//!< <BR>If the sort column is not set, then false is returned, and the values in 
	//!< sort_column_id and order are unchanged.
	 
	bool has_default_sort_func() const;
	//!< Returns true if the model has a default sort function. 
	//!< @return <EM>true</EM> if the model has a default sort function.
	//!< 
	//!< <BR>This is used primarily by TreeViewColumns in order to determine if a model
	//!< can go back to its default state, or not.

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

	void sort_column_changed();
	//!< Emits a "sort_column_changed" signal on the sortable.
	
	void set_sort_column_id(int sort_column_id, SortType order);
	//!< Sets the current sort column to be <EM>sort_column_id</EM>. 
	//!< @param sort_column_id The sort column id to set. 
	//!< @param order The sort order of the column.
	//!<	
	//!< <BR>The sortable will resort itself to reflect this change, after emitting a
	//!< <EM>sort_column_changed</EM> signal. If <EM>sort_column_id</EM> is 
	//!< GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, then the default sort function will
	//!< be used, if it is set.
	 
	void set_sort_func(int sort_column_id, const TreeIterCompareSlot *compare);
	//!< Sets the comparison callback slot used when sorting to be <EM>compare</EM>.
	//!< @param sort_column_id The sort column id to set the callback slot for. 
	//!< @param compare The sorting slot to call. 
	//!<	 
	//!< <BR>If the current sort column id of sortable is the same as <EM>sort_column_id</EM>,
	//!< then the model will sort using this function.
	
	void set_default_sort_func(const TreeIterCompareSlot *compare);
	//!< Sets the default comparison callback slot used when sorting to be <EM>compare</EM>.
	//!< @param compare The sorting slot. 
	//!< 	 
	//!< <BR>If the current sort_column_id of sortable is GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
	//!< then the model will sort using this function. If <EM>compare</EM> is null, then there will
	//!< be no default comparison callback slot. This means that once the model has been sorted, it
	//!< can't go back to its default state. In this case, when the current sort column id of
	//!< sortable is GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, the model will be unsorted.

//! @}
//! @name Signal Proxies
//! @{
	
	const SortColumnChangedSignalProxy sig_sort_column_changed()
	{
		return SortColumnChangedSignalProxy(this, &sort_column_changed_signal);
	}
	//!< Connect to the sort_column_changed_signal; emitted whenever the current sort column is changed.
	
//! @}
};

} // namespace Gtk

} // namespace Inti

#endif // INTI_GTK_TREE_SORTABLE_H

