#ifndef _FishIDE_AVersion_h_
#define _FishIDE_AVersion_h_

#include <Core/Core.h>

using namespace Upp;

class AVersion : Moveable<AVersion>
{
	private:
	
		int major;
		int minor;
		int release;
		
	protected:
	
	public:
	
		// constuctors
		AVersion();
		AVersion(AVersion const &v);
		AVersion(int maj, int min, int rel);
		AVersion(String const &s);
		
		// clear
		AVersion &Clear(void);
		
		// assignment
		AVersion const &operator=(AVersion const &v);
		AVersion const &operator=(String const &s);
		
		// getters
		int GetMajor(void) const		{ return major; }
		int GetMinor(void) const		{ return minor; }
		int GetRelease(void) const		{ return release; }

		// setters
		AVersion &SetMajor(int maj)		{ major = maj; return *this; }
		AVersion &SetMinor(int min)		{ minor = min; return *this; }
		AVersion &SetRelease(int rel)	{ release = rel; return *this; }
		
		// comparaisons
		bool operator==(AVersion const &v) const;
		bool operator<(AVersion const &v) const;
		bool operator>(AVersion const &v) const;
		bool operator<=(AVersion const &v) const	{ return !operator>(v); }
		bool operator>=(AVersion const &v) const	{ return !operator<(v); }

		bool operator==(String const &s) const		{ return operator==(AVersion(s)); }
		bool operator<(String const &s) const		{ return operator<(AVersion(s)); }
		bool operator>(String const &s) const		{ return operator>(AVersion(s)); }
		bool operator<=(String const &s) const		{ return operator<=(AVersion(s)); }
		bool operator>=(String const &s) const		{ return operator>=(AVersion(s)); }

		// booleans
		bool IsNull(void) const;
		bool operator!(void) const { return IsNull(); }
		operator bool() const { return !IsNull(); }
		
		// to string
		String ToString(void) const;
		String ToStringUndotted(void) const;
		
		// store to xml
		void Xmlize(XmlIO &xml);
		
		unsigned GetHashValue() const { return Upp::GetHashValue(ToString()); }
};

// helper
String ExtractMaintainer(String const &m, String const &auth);

struct MaintainerVersion : Moveable<MaintainerVersion>
{
	String maintainer;
	AVersion version;
	
	String ToString(void) const { return version.ToString() + "(" + maintainer + ")"; }
	unsigned GetHashValue() const { return Upp::GetHashValue(ToString()); }
	
	MaintainerVersion(String const &maint, AVersion const &ver) : maintainer(maint), version(ver) {}
	MaintainerVersion(String const &mv);
	MaintainerVersion() {}
	void Clear(void) { maintainer.Clear(); version.Clear(); }

	bool operator==(MaintainerVersion const &v) const { return maintainer == v.maintainer && version == v.version; }
	bool operator <(MaintainerVersion const &v) const { return ToString() < v.ToString(); }
	bool operator >(MaintainerVersion const &v) const { return ToString() > v.ToString(); }
};

#endif
