/***************************************************************************
*                                                                          *
*  Copyright (C) Golaem S.A.  All Rights Reserved.                         *
*                                                                          *
****************************************************************************/
#pragma once

#include "glmCoreAPI.h"
#include "glmEvent.h"
#include "glmTypes.h"
#include "glmMemory.h"

#include "glmString.h"

namespace glm
{
	class Progress;
	/** 
	* \brief Event generated by the progress handling class \ref Progress.
	*
	* \ingroup progress
	* \author Golaem <dev@golaem.com>
	*/
	class GLM_CORE_API ProgressEvent : public Event< Progress >
	{
	public:
		/**
		* \brief Event types definitions.
		*/
		struct Type
		{
			enum Value
			{
				NONE,		//!< Not a relevant event, used for the initial last event of \ref Progress.
				START,		//!< Process start.
				PROGRESS,	//!< Process has significantly progressed
				MESSAGE,	//!< Process output a message
				SUCCES,		//!< Process ends in succes
				FAILURE,	//!< Process ends in failure
				END
			};
		};
	public:

		GLM_CLASS_STAT_ID( glm::MemoryStatIds::GolaemShared)

		/**
		* \brief constructor.
		* \param source The progress that is the source of the event.
		* \param type The type of progress event.
		* \param message The message (optionnal).
		*/
		ProgressEvent(const Progress& source, Type::Value type, const char* message = "");

		/**
		* \brief destructor.
		*/
		virtual ~ProgressEvent();

		/**
		* \brief Retrieve the type of event.
		*/
		Type::Value getType() const;

		/**
		* \brief Retrieve the name of the process.
		*/
		const char* getProcessName() const;

		/**
		* \brief Retrieve the time elapsed since the process started.
		*/
		Time getElapsedTime() const;

		/**
		* \brief Retrieve the amount of work done.
		*/
		unsigned int getDone() const;

		/**
		* \brief Retrieve the amount of work todo.
		*/
		unsigned int getTodo() const;

		/**
		* \brief Retrieve the current progress as a float value between 0 and 1.
		*/
		float getProgress() const;

		/**
		* \brief Retrieve the current progress as a percentage.
		*/
		unsigned int getProgressPercentage() const;

		/**
		* \brief Retrieve the message.
		*/
		const char* getMessage() const;

	private:

		/// Type of event.
		int _type;

		/// Name of the process.
		glm::GlmString _processName;

		/// Time elapsed since process start.
		Time _elapsedTime;

		/// Amount of work done.
		unsigned int _done; 

		/// Amount of work todo.
		unsigned int _todo;

		/// Message.
		glm::GlmString _message;
	} ;

	//*****************************************************************************
	// ProgressEvent inline definitions
	//*****************************************************************************

	//-----------------------------------------------------------------------------
	// getType
	//-----------------------------------------------------------------------------
	inline ProgressEvent::Type::Value ProgressEvent::getType() const
	{
		return Type::Value(_type);
	}

	//-----------------------------------------------------------------------------
	// getProcessName
	//-----------------------------------------------------------------------------
	inline const char* ProgressEvent::getProcessName() const
	{
		return _processName.c_str();
	}

	//-----------------------------------------------------------------------------
	// getElapsedTime
	//-----------------------------------------------------------------------------
	inline Time ProgressEvent::getElapsedTime() const
	{
		return _elapsedTime;
	}

	//-----------------------------------------------------------------------------
	// getDone
	//-----------------------------------------------------------------------------
	inline unsigned int ProgressEvent::getDone() const
	{
		return _done;
	}

	//-----------------------------------------------------------------------------
	// getTodo
	//-----------------------------------------------------------------------------
	inline unsigned int ProgressEvent::getTodo() const
	{
		return _todo;
	}

	//-----------------------------------------------------------------------------
	// getMessage
	//-----------------------------------------------------------------------------
	inline const char* ProgressEvent::getMessage() const
	{
		return _message.c_str();
	}
}

