//------------------------------------------------------------------------------
//	Copyright (C) 2002 - 2010 Humboldt-Universitaet zu Berlin
//
//	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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//------------------------------------------------------------------------------

/**
 * @file Report.h
 * @author Ralf Gerstenberger
 * @date created at 2002/06/21
 * @brief Declaration of class odemx::data::Report
 * @sa Report.cpp
 * @since 1.0
 */

#ifndef ODEMX_DATA_REPORT_INCLUDED
#define ODEMX_DATA_REPORT_INCLUDED

#include <odemx/data/ReportTable.h>

#include <set>
#include <string>
#include <vector>

//----------------------------------------------------------forward declarations
namespace odemx {
namespace data {

class ReportProducer;

//-----------------------------------------------------------header declarations

/**
	\ingroup data

	\author Ralf Gerstenberger

	\brief Base class for special report objects

	\sa ReportTable ReportProducer

	Report is the base class for user defined report objects.
	Report manages ReportTables, ReportProducers and the report generation.
	Each Report object represents an individual report. There can be
	multiple reports in a simulation.

	\since 1.0
*/
class Report {
public:

	/// Destruction
	virtual ~Report();

	/// \name Reporter handling
	//@{
	/// Add a reporter to this Report
	void addReportProducer( ReportProducer& reporter );
	/// Remove a reporter from this Report
	void removeReportProducer( ReportProducer& reporter );
	//@}

	/// @name ReportTable handling
	//@{
	/**
		\brief Create or retrieve a suitable table by name and definition

		\param name
			name of new Table
		\param def
			TableDefinition of new Table

		\return new Table

		\note If there is already a Table with an equal name and
		definition it will be returned instead of creating a new Table.
	*/
	ReportTable& getTable( const std::string& name, const ReportTable::Definition& def );

	/**
		\brief generate report by getting data from ReportProducers

		Report generation:
		@li call all registered ReportProducer objects
		@li call processTables
	*/
	void generateReport();

protected:
	/**
		\brief find a Table

		\param name
			name of Table
		\param def
			TableDefinition of Table

		\return found Table or 0
	*/
	ReportTable* findTable( const std::string& name, const ReportTable::Definition& def ) const;
	/**
	 * @brief Allows defining some actions before the tables get processed
	 *
	 * The idea is to give Report specializations a means to do some pre-
	 * and some post-processing. This can useful for XML output, for example,
	 * where one might want to start a document.
	 */
	virtual void startProcessing() {};

	/**
		\brief Process arbitrary tables for output

		Report objects have to provide a meaningful processTables() function.
		This method is responsible for transforming tables from ReportProducers
		into some output format such as plain text or XML.
	*/
	virtual void processTables() = 0;

	/**
	 * @brief Allows defining some actions after the tables got processed
	 *
	 * This method provides the oportunity to do post-processing.
	 * This can useful for XML output, for example where one might want
	 * to properly close a document.
	 */
	virtual void endProcessing() {};
	//@}

	/// Vector type to store pointers to generated tables
	typedef std::vector< ReportTable* > TableVec;
	/// Vector type to store pointers to registered producers
	typedef std::set< ReportProducer* > ReportProducerSet;

	/// Contained tables
	TableVec tables_;
	/// Associated reporters
	ReportProducerSet producers_;
};

} } // namespace odemx::data

#endif /* ODEMX_DATA_REPORT_INCLUDED */
