/** @file notifier.h
 *
 *	Declaration of notification module interface.
 *
 *	This module provides two global objects that ease error and progress notifying
 *	from inside of various methods. This approach is prefered to direct writes to
 *	streams, because it keeps code more consistent. Moreover progress notifier also
 *	hold static timer, which does measure of program execution time and so it's easy
 *	to print out progress notifications with time elapsed so far.
 *
 *	(C) Ceslav Przywara 2008, MFF UK Prague
 *
 */


#ifndef _NOTIFIER_H
#define _NOTIFIER_H

#include <iostream>
#include <string>

// Comment out following line, if boost library is not available.
// Progress bar display is based on boost "progress" library. It's not
// necessary to have progress bar displayed - it's just comfortable.
#define _BOOST_ON

#ifdef _BOOST_ON
#include <boost/progress.hpp>
#endif

namespace ace {

#ifdef _BOOST_ON
/** Simply progress bar display is provided by one of boost libraries.
 */
typedef boost::progress_display progress_display_t;
#endif

/** Notifier is very simple - just binds itself to given stream and flushes passed
 *	notification to that stream.
 */
class Notifier {
protected:
	/** Notifier object holds reference to output stream, where the notifications
	 *	are flushed.
	 */
	std::ostream& _output;
public:
	/** Object needs to know which output stream tie itself to.
	 *	@param output Reference to output stream to tie itself to.
	 */
	Notifier(std::ostream& output): _output(output) {}
	/** Procedure prints the message to output stream tied within instance.
	 *	@param message Notification to be print.
	 */
	void fatal_error(const std::string& message) const;
	/** Procedure prints the message to output stream tied within instance.
	 *	@param message Notification to be print.
	 */
	void info(const std::string& message) const;
	/** @return Reference to stream tied with.
	 */
	inline std::ostream& output_stream(void) { return _output; }
	/** Procedure prints the message to output stream tied within instance.
	 *	@param message Notification to be print.
	 */
	void warning(const std::string& message) const;
};

/** ProgressNotifier holds static stored timer within, which starts timing
 *	of program execution time immediately on program start.
 *	The notifications can then be printed with elapsed time appended.
 *	This functionality depends on availibility of boost.org progress library!
 */
class ProgressNotifier: public Notifier {	
#ifdef _BOOST_ON
	/** Timer is picked up from boost library.
	 */
	static boost::progress_timer _timer;  // static - so starts timing immediately
#endif
public:
	/** Object needs to know which output stream tie itself to.
	 *	@param output Reference to output stream to tie itself to.
	 */
	ProgressNotifier(std::ostream& output): Notifier(output) {}	
	/** Procedure prints out the message and then append ":" and elapsed time (on new line).
	 *	@param message Notification to be print.
	 */
	void elapsed(const std::string& message) const;	
};

/** Procedure prints program usage information.
 */
void print_usage(void);

/** Module declares (global) variables, which are wrapped into separate
 *	namespace.
 */
namespace notifier {

/** Notifier used to print out error messages.
 */
extern Notifier error;
/** Notifier used to print out progress messages.
 */
extern ProgressNotifier progress;

} // namespace notifier

} // namespace ace

#endif
