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

#pragma once

#include "glmCoreAPI.h"
#include "glmMemory.h"

namespace glm
{
	/**
	* \brief information class about a plugin.
	*
	* Describes the properties of a plugin, such as the plugin name, version and release date.
	*
	* \ingroup utils
	* \author Golaem <dev@golaem.com>
	*/
	class GLM_CORE_API ProductInformation
	{
	public:

		GLM_CLASS_STAT_ID( glm::MemoryStatIds::GolaemShared)

			/**
			* \brief constructor
			*/
			ProductInformation(const char* productName,
				const char* description,
				unsigned int majorVersion,
				unsigned int minorVersion,
				unsigned int patchVersion,
				unsigned int branchVersion,
				const char* versionLabel,
				const char* releaseDate);

		/**
		* \brief destructor
		*/
		virtual ~ProductInformation();


		/**
		* \brief Get the name of the plugin.
		* \return the name of the plugin
		*/
		const char* getProductName() const;

		/**
		* \brief Get the description of the plugin.
		* \return the description of the plugin
		*/
		const char* getDescription() const;

		/**
		* \brief Get the major part of the plugin version number.
		* \return the major part of the plugin version number
		*/
		unsigned int getMajorVersion() const;

		/**
		* \brief Get the minor part of the plugin version number.
		* \return the minor part of the plugin version number
		*/
		unsigned int getMinorVersion() const;

		/**
		* \brief Get the patch part of the plugin version number.
		* \return the patch part of the plugin version number
		*/
		unsigned int getPatchVersion() const;

		/**
		* \brief Get the branch part of the plugin version number.
		* \return the branch part of the plugin version number
		*/
		unsigned int getBranchVersion() const;

		/**
		* \brief Get the label of the plugin version.
		* \return the label of the plugin version
		*/
		const char* getVersionLabel() const;

		/**
		* \brief Get the release date (in a string form).
		* \return the release date (in a string form)
		*/
		const char* getReleaseDate() const;

		/**
		* \brief less operator (check only version related facts i.e. minor, major, versionLabel)
		* \param pluginInformation instance to compare to this
		* \return true if the major version is less than or equal to pluginInformation's, and minor version striclty less than pluginInformation's
		*/
		bool operator < (const ProductInformation& pluginInformation) const;

		/**
		* \brief comparison operator (check only version related facts i.e. minor, major, versionLabel)
		* \param pluginInformation instance to compare to this
		* \return true major version, minor version and version label are identical
		*/
		bool operator == (const ProductInformation& pluginInformation) const;

		/**
		* \brief comparison operator (check only version related facts i.e. minor, major, versionLabel)
		* \param pluginInformation instance to compare to this
		* \return true major version, minor version or version label are different
		*/
		bool operator != (const ProductInformation& pluginInformation) const;

		/**
		* \brief C-string conversion method
		* \return a C-string representation of this plugin information
		*/
		const char* getCString() const;

		/// "unknown" definition for missing plugin information
		static const ProductInformation getDefaultUnknown();

	private:
		static const unsigned int _partialInfoLengthMax = 256;
		static const unsigned int _fullInfoLengthMax = 1024;

		/// name of the plugin
		char _productName[_partialInfoLengthMax];

		/// description of the plugin
		char _description[_partialInfoLengthMax];

		/// major part of the plugin version number
		unsigned int _majorVersion;

		/// minor part of the plugin version number
		unsigned int _minorVersion;

		/// patch part of the plugin version number
		unsigned int _patchVersion;

		/// branch part of the plugin version number
		unsigned int _branchVersion;

		/// label of the plugin version
		char _versionLabel[_partialInfoLengthMax];

		/// date of plugin release
		char _releaseDate[_partialInfoLengthMax];

		/// full product information string
		char _fullInfo[_fullInfoLengthMax];

		/// true at the the application launch, to create the file
		static bool truncProductInformationLog;
	};

	//-------------------------------------------------------------------------
	// getProductName
	//-------------------------------------------------------------------------
	inline const char*
		ProductInformation::getProductName() const
	{
		return _productName;
	}

	//-------------------------------------------------------------------------
	// getDescription
	//-------------------------------------------------------------------------
	inline const char*
		ProductInformation::getDescription() const
	{
		return _description;
	}

	//-------------------------------------------------------------------------
	// getMajorVersion
	//-------------------------------------------------------------------------
	inline unsigned int
		ProductInformation::getMajorVersion() const
	{
		return _majorVersion;
	}

	//-------------------------------------------------------------------------
	// getMinorVersion
	//-------------------------------------------------------------------------
	inline unsigned int
		ProductInformation::getMinorVersion() const
	{
		return _minorVersion;
	}

	//-------------------------------------------------------------------------
	// getPatchVersion
	//-------------------------------------------------------------------------
	inline unsigned int
		ProductInformation::getPatchVersion() const
	{
		return _patchVersion;
	}

	//-------------------------------------------------------------------------
	// getBranchVersion
	//-------------------------------------------------------------------------
	inline unsigned int
		ProductInformation::getBranchVersion() const
	{
		return _branchVersion;
	}

	//-------------------------------------------------------------------------
	// getVersionLabel
	//-------------------------------------------------------------------------
	inline const char*
		ProductInformation::getVersionLabel() const
	{
		return _versionLabel;
	}

	//-------------------------------------------------------------------------
	// getReleaseDate
	//-------------------------------------------------------------------------
	inline const char*
		ProductInformation::getReleaseDate() const
	{
		return _releaseDate;
	}

	//-------------------------------------------------------------------------
	// operator <
	//-------------------------------------------------------------------------
	inline bool
		ProductInformation::operator < (const ProductInformation& pluginInformation) const
	{
		return ((_majorVersion < pluginInformation.getMajorVersion())
			|| ((_majorVersion == pluginInformation.getMajorVersion())
				&& ((_minorVersion < pluginInformation.getMinorVersion())
					|| ((_minorVersion == pluginInformation.getMinorVersion())
						&& ((_patchVersion < pluginInformation.getPatchVersion())
							|| ((_patchVersion == pluginInformation.getPatchVersion())
								&& (_branchVersion < pluginInformation.getBranchVersion())))))));
	}

	//-------------------------------------------------------------------------
	// operator ==
	//-------------------------------------------------------------------------
	inline bool
		ProductInformation::operator == (const ProductInformation& pluginInformation) const
	{
		return((_majorVersion == pluginInformation.getMajorVersion()) &&
			(_minorVersion == pluginInformation.getMinorVersion()) &&
			(_patchVersion == pluginInformation.getPatchVersion()) &&
			(_branchVersion == pluginInformation.getBranchVersion()));
	}

	//-------------------------------------------------------------------------
	// operator !=
	//-------------------------------------------------------------------------
	inline bool
		ProductInformation::operator != (const ProductInformation& pluginInformation) const
	{
		return((_majorVersion != pluginInformation.getMajorVersion()) ||
			(_minorVersion != pluginInformation.getMinorVersion()) ||
			(_patchVersion != pluginInformation.getPatchVersion()) ||
			(_branchVersion != pluginInformation.getBranchVersion()));
	}
}

