/*  Inti: Integrated Foundation Classes
 *  Copyright (C) 2002 The Inti Development Team.
 *
 *  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/atk/table.h
//! @brief An AtkTable C++ wrapper interface.
//!
//! Provides Table, an interface implemented for UI components which contain tabular or row/column information.

#ifndef INTI_ATK_TABLE_H
#define INTI_ATK_TABLE_H

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

#ifndef __ATK_TABLE_H__
#include <atk/atktable.h>
#endif

#ifndef _CPP_VECTOR
#include <vector>
#endif

namespace Inti {

namespace Atk {

class Object;

class TableIface;

//! @class Table table.h inti/atk/table.h
//! @brief An AtkTable C++ wrapper class.
//!
//! Table should be implemented by components which present elements ordered via rows and columns.
//! It may also be used to present tree-structured information if the nodes of the trees can be 
//! said to contain multiple "columns". Individual elements of an Table are typically referred 
//! to as "cells", and these cells are exposed by Table as child Atk::Objects of the Table. Both
//! row/column and child-index-based access to these children is provided.
//!
//! Children of Table are frequently "lightweight" objects, that is, they may not have backing
//! widgets in the host UI toolkit. They are therefore often transient.
//! 
//! Since tables are often very complex, Table includes provision for offering simplified summary
//! information, as well as row and column headers and captions. Headers and captions are Atk::Objects
//! which may implement other interfaces (Text, Image, etc.) as appropriate. Table summaries may 
//! themselves be (simplified) Tables, etc.

class Table : public virtual G::TypeInterface
{
	friend class TableIface;

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

	virtual ~Table() = 0;
	//!< Destructor.
	
//! @}
//  Override these do_ methods when you want to change the default behaviour of the AtkTable.
	
	virtual AtkObject* do_ref_at(int row, int column);

	virtual int do_get_index_at(int row, int column);

	virtual int do_get_column_at_index(int index);

	virtual int do_get_row_at_index(int index);

	virtual int do_get_n_columns();

	virtual int do_get_n_rows();

	virtual int do_get_column_extent_at(int row, int column);

	virtual int do_get_row_extent_at(int row, int column);

	virtual AtkObject* do_get_caption();

	virtual const char* do_get_column_description(int column);

	virtual AtkObject* do_get_column_header(int column);

	virtual const char* do_get_row_description(int row);

	virtual AtkObject* do_get_row_header(int row);

	virtual AtkObject* do_get_summary();

	virtual void do_set_caption(AtkObject *caption);

	virtual void do_set_column_description(int column, const char *description);

	virtual void do_set_column_header(int column, AtkObject *header);

	virtual void do_set_row_description(int row, const char *description);

	virtual void do_set_row_header(int row, AtkObject *header);

	virtual void do_set_summary(AtkObject *accessible);

	virtual int do_get_selected_columns(int **selected);

	virtual int do_get_selected_rows(int **selected);

	virtual bool do_is_column_selected(int column);

	virtual bool do_is_row_selected(int row);

	virtual bool do_is_selected(int row, int column);

	virtual bool do_add_row_selection(int row);

	virtual bool do_remove_row_selection(int row);

	virtual bool do_add_column_selection(int column);

	virtual bool do_remove_column_selection(int column);

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

	virtual void on_row_inserted(int row, int num_inserted);
	//!< Called when one or more rows are inserted into the table.
	//!< @param row The index of the first row inserted.
	//!< @param num_inserted The number of rows inserted.

	virtual void on_column_inserted(int column, int num_inserted);
	//!< Called when one or more columns are inserted into the table.
	//!< @param column The index of the first column inserted.
	//!< @param num_inserted The number of columns inserted.

	virtual void on_row_deleted(int row, int num_deleted);
	//!< Called when one or more rows in the table are deleted.
	//!< @param row The index of the first row deleted.
	//!< @param num_deleted The number of rows deleted.

	virtual void on_column_deleted(int column, int num_deleted);
	//!< Called when one or more columns in the table are deleted.
	//!< @param column The index of the first column deleted.
	//!< @param num_deleted The number of columns deleted.

	virtual void on_row_reordered();
	//!< Called when the rows in the table are reordered.

	virtual void on_column_reordered();
	//!< Called when the columns in the table are reordered.

	virtual void on_model_changed();
	//!< Called when a model_changed signal is received.

//! @}
//  Signals

	typedef G::Signal2<void, int, int> RowInsertedSignalType;
	typedef G::SignalProxy<TypeInstance, RowInsertedSignalType> RowInsertedSignalProxy;
	static const RowInsertedSignalType row_inserted_signal;

	typedef G::Signal2<void, int, int> ColumnInsertedSignalType;
	typedef G::SignalProxy<TypeInstance, ColumnInsertedSignalType> ColumnInsertedSignalProxy;
	static const ColumnInsertedSignalType column_inserted_signal;

	typedef G::Signal2<void, int, int> RowDeletedSignalType;
	typedef G::SignalProxy<TypeInstance, RowDeletedSignalType> RowDeletedSignalProxy;
	static const RowDeletedSignalType row_deleted_signal;

	typedef G::Signal2<void, int, int> ColumnDeletedSignalType;
	typedef G::SignalProxy<TypeInstance, ColumnDeletedSignalType> ColumnDeletedSignalProxy;
	static const ColumnDeletedSignalType column_deleted_signal;

	typedef G::Signal0<void> RowReorderedSignalType;
	typedef G::SignalProxy<TypeInstance, RowReorderedSignalType> RowReorderedSignalProxy;
	static const RowReorderedSignalType row_reordered_signal;

	typedef G::Signal0<void> ColumnReorderedSignalType;
	typedef G::SignalProxy<TypeInstance, ColumnReorderedSignalType> ColumnReorderedSignalProxy;
	static const ColumnReorderedSignalType column_reordered_signal;

	typedef G::Signal0<void> ModelChangedSignalType;
	typedef G::SignalProxy<TypeInstance, ModelChangedSignalType> ModelChangedSignalProxy;
	static const ModelChangedSignalType model_changed_signal;

public:
//! @name Accessors
//! @{

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

	AtkTableIface* atk_table_iface() const;
	//!< Get a pointer to the AtkTableIface structure.

	operator AtkTable* () const;
	//!< Conversion operator; safely converts a Table to an AtkTable pointer.

	Object* ref_at(int row, int column) const;
	//!< Get a reference to the table cell at row, column.
	//!< @param row An integer representing a row in table.
	//!< @param column an integer representing a column in the table.
	//!< @return A pointer to Atk::Object representing the referred to accessible.

	int get_index_at(int row, int column) const;
	//!< Gets a integer representing the index at the specified row and column. 
	//!< @param row An integer representing a row in the table.
	//!< @param column An integer representing a column in the table.
	//!< @return An integer representing the index at specified position.
	//!<
	//!< <BR>The value -1 is returned if the object at <EM>row, column</EM> is not
	//!< a child of the table or the table does not implement this interface.

	int get_column_at_index(int index) const;
	//!< Gets an integer representing the column at the specified <EM>index</EM>.
	//!< @param index An integer representing an index in the table.
	//!< @return An integer representing the column at the specified index, or or -1
	//!< if the table does not implement this interface.

	int get_row_at_index(int index) const;
	//!< Gets an integer representing the row at the specified <EM>index</EM>.
	//!< @param index An integer representing an index in the table.
	//!< @return An integer representing the row at the specified index, or or -1
	//!< if the table does not implement this interface.

	int get_n_columns() const;
	//!< Gets the number of columns in the table.
	//!< @return An integer representing the number of columns, or 0 if the table
	//!< does not implement this interface.

	int get_n_rows() const;
	//!< Gets the number of rows in the table.
	//!< @return An integer representing the number of rows, or 0 if the table
	//!< does not implement this interface.

	int get_column_extent_at(int row, int column) const;
	//!< Gets the number of columns occupied by the accessible object at the
	//!< specified row and column in the table.
	//!< @param row An integer representing a row in the table.
	//!< @param column An integer representing a column in the table.
	//!< @return An integer representing the column extent at specified position, or 0
	//!< if the table does not implement this interface.

	int get_row_extent_at(int row, int column) const;
	//!< Gets the number of rows occupied by the accessible object at the
	//!< specified row and column in the table.
	//!< @param row An integer representing a row in the table.
	//!< @param column An integer representing a column in the table.
	//!< @return An integer representing the row extent at specified position, or 0
	//!< if the table does not implement this interface.

	Object* get_caption() const;
	//!< Gets the caption for the table.
	//!< @return A pointer to an Atk::Object representing the table caption, or null
	//!< if table does not implement this interface.

	String get_column_description(int column) const;
	//!< Gets the description text of the specified column in the table.
	//!< @param column An integer representing a column in the table.
	//!< @return A string representing the column description, or a null String if
	//!< the table does not implement this interface.

	Object* get_column_header(int column) const;
	//!< Gets the column header of a specified column in an accessible table.
	//!< @param column An integer representing a column in the table.
	//!< @return A pointer to an Atk::Object representing the specified column header,
	//!< or null if table does not implement this interface.

	String get_row_description(int row) const;
	//!< Gets the description text of the specified row in the table.
	//!< @param row An integer representing a row in the table.
	//!< @return A string representing the row description, or null if the table
	//!< does not implement this interface.

	Object* get_row_header(int row) const;
	//!< Gets the row header of a specified row in an accessible table.
	//!< @param row An integer representing a row in the table.
	//!< @return A pointer to an Atk::Object representing the specified row header,
	//!< or null if table does not implement this interface.

	Object* get_summary() const;
	//!< Gets the summary description of the table.
	//!< @return A pointer to an Atk::Object representing a summary description of the table,
	//!< or null if table does not implement this interface.

	bool get_selected_columns(std::vector<int>& selected) const;
	//!< Gets the selected columns of the table.
	//!< @param selected A vector of int that is to hold the selected columns numbers.
	//!< @return <EM>true</EM> if the vector is not empty.

	bool get_selected_rows(std::vector<int>& selected) const;
	//!< Gets the selected rows of the table.
	//!< @param selected A vector of int that is to hold the selected rows numbers.
	//!< @return <EM>true</EM> if the vector is not empty.

	bool is_column_selected(int column) const;
	//!< Gets whether the specified column is selected.
	//!< @param column An integer representing a column in the table.
	//!< @return <EM>true</EM> if the column is selected, or <EM>false</EM> if the table
	//!< does not implement this interface.	bool is_row_selected(int row);

	bool is_row_selected(int row) const;
	//!< Gets whether the specified row is selected.
	//!< @param row An integer representing a row in the table.
	//!< @return <EM>true</EM> if the row is selected, or <EM>false</EM> if the table
	//!< does not implement this interface.
		
	bool is_selected(int row, int column) const;
	//!< Gets a bool value indicating whether the accessible object at the specified
	//!< <EM>row</EM> and <EM>column</EM> is selected.
	//!< @param row An integer representing a row in the table.
	//!< @param column An integer representing a column in the table.
	//!< @return <EM>true</EM> if the cell is selected, or <EM>false</EM> if the table
	//!< does not implement this interface.

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

	void set_caption(const Object *caption);
	//!< Sets the caption for the table.
	//!< @param caption An Atk::Object representing the caption to set for the table.

	void set_column_description(int column, const String& description);
	//!< Sets the description text for the specified <EM>column</EM> of the table.
	//!< @param column An integer representing a column in the table.
	//!< @param description A string representing the description text to
	//!< set for the specified <EM>column</EM> of the table.

	void set_column_header(int column, const Object *header);
	//!< Sets the specified column header to header.
	//!< @param column An integer representing a column in the table.
	//!< @param header An Atk::Object representing the specified column header.

	void set_row_description(int row, const String& description);
	//!< Sets the description text for the specified <EM>row</EM> of the table.
	//!< @param row An integer representing a row in the table.
	//!< @param description A string representing the description text to
	//!< set for the specified <EM>row</EM> of the table.

	void set_row_header(int row, const Object *header);
	//!< Sets the specified row header to header.
	//!< @param row An integer representing a row in the table.
	//!< @param header An Atk::Object representing the specified row header.

	void set_summary(const Object *accessible);
	//!< Sets the summary description of the table.
	//!< @param accessible An Atk::Object representing the summary description to set for table.

	bool add_row_selection(int row);
	//!< Adds the specified row to the selection.
	//!< @param row An integer representing a row in the table.
	//!< @return <EM>true</EM> if the row was successfully added to the selection,
	//!< or <EM>false</EM> if the table does not implement this interface.

	bool remove_row_selection(int row);
	//!< Removes the specified row from the selection.
	//!< @param row An integer representing a row in the table.
	//!< @return <EM>true</EM> if the row was successfully removed from the selection,
	//!< or <EM>false</EM> if the table does not implement this interface.

	bool add_column_selection(int column);
	//!< Adds the specified column to the selection.
	//!< @param column An integer representing a column in the table.
	//!< @return <EM>true</EM> if the column was successfully added to the selection,
	//!< or <EM>false</EM> if the table does not implement this interface.

	bool remove_column_selection(int column);
	//!< Removes the specified column from the selection.
	//!< @param column An integer representing a column in the table.
	//!< @return <EM>true</EM> if the column was successfully removed from the selection,
	//!< or <EM>false</EM> if the table does not implement this interface.

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

	const RowInsertedSignalProxy sig_row_inserted()
	{
		return RowInsertedSignalProxy(this, &row_inserted_signal);
	}
	//!< Connect to the row_inserted_signal; emitted when one or more rows are inserted into a table.

	const ColumnInsertedSignalProxy sig_column_inserted()
	{
		return ColumnInsertedSignalProxy(this, &column_inserted_signal);
	}
	//!< Connect to the column_inserted_signal; emitted when one or more columns are inserted into a table.

	const RowDeletedSignalProxy sig_row_deleted()
	{
		return RowDeletedSignalProxy(this, &row_deleted_signal);
	}
	//!< Connect to the row_deleted_signal; emitted when one or more rows in a table are deleted.

	const ColumnDeletedSignalProxy sig_column_deleted()
	{
		return ColumnDeletedSignalProxy(this, &column_deleted_signal);
	}
	//!< Connect to the column_deleted_signal; emitted when one or more columns in a table are deleted.

	const RowReorderedSignalProxy sig_row_reordered()
	{
		return RowReorderedSignalProxy(this, &row_reordered_signal);
	}
	//!< Connect to the row_reordered_signal; emitted when the rows in a table are reordered.

	const ColumnReorderedSignalProxy sig_column_reordered()
	{
		return ColumnReorderedSignalProxy(this, &column_reordered_signal);
	}
	//!< Connect to the column_reordered_signal; emitted when the columns in a table are reordered.

	const ModelChangedSignalProxy sig_model_changed()
	{
		return ModelChangedSignalProxy(this, &model_changed_signal);
	}
	//!< Connect to the model_changed_signal.

//! @}
};

} // namespace Atk

} // namespace Inti

#endif // INTI_ATK_TABLE_H

