/*
 Copyright (C) 2002  Lakin Wecker
	
 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 General Public License for more details. 

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software Foundation,
 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#ifndef STREAMLOGOBSERVER_H
#define STREAMLOGOBSERVER_H

#include "Log.h"
#include "LogObserver.h"

#include <iostream>
#include <chrono>

#include <boost/noncopyable.hpp>
namespace Ember {

/**
 * Log Observer which logs stuff to the stream provided on creation.
 *
 * This log observer takes an arbitrary ostream at it's creation
 * and logs all messages sent to it to this stream.
 * 
 * Log *logging = EmberServices::getSingleton().getLog();
 * //Create log observer that prints everything to cerr
 * StreamLogObserver* obs = new StreamLogObserver(std::cerr);
 * obs->setFilter(Log::VERBOSE);
 * logging->addObserver(obs);
 *
 * @author Lakin Wecker aka nikal
 *
 * @see Log::Observer
 */

class StreamLogObserver : public LogObserver, boost::noncopyable {

	//======================================================================
	// Private Variables
	//======================================================================/
private:

	/**
	 * @brief The output stream to which the log will be written.
	 */
	std::ostream& myOut;

	/**
	 * @brief If true, the output will be detailed.
	 *
	 * Meaning that it will contain millisecond precision as well as the thread id.
	 */
	bool mDetailed;

	/**
	 * @brief Record the start time.
	 *
	 * To be used when in detailed mode.
	 */
	std::chrono::steady_clock::time_point mStart;


public:

	explicit StreamLogObserver(std::ostream& out);


	~StreamLogObserver() override;

	/**
	 * Prints out the message provided with file, line and datestamp to myOut;
	 */
	void onNewMessage(const std::string& message, const std::string& file, const int& line,
					  const Log::MessageImportance& importance) override;

	/**
	 * @brief Sets whether the log output should be detailed or not.
	 *
	 * If detailed is enabled, millisecond timestamp as well as thread id will be included.
	 * @param enabled True if enabled.
	 */
	void setDetailed(bool enabled);


	/**
	 * @brief Counter for the current frame.
	 *
	 * Used when providing detailed log output. This needs to be set from outside.
	 */
	static unsigned long sCurrentFrame;

	/**
	 * @brief Start time of the current frame.
	 *
	 * Used when providing detailed log output. This needs to be set from outside.
	 */
	static std::chrono::steady_clock::time_point sCurrentFrameStartMilliseconds;

	//----------------------------------------------------------------------
	// Disable Assignment operator
private:
	/**
	 * Disabled Assignment operator.
	 */
	StreamLogObserver& operator=(const StreamLogObserver& source);

};

}
#endif
