using namespace System;

/// <summary>
/// Représente une donnée dont le type peut évoluer
///	</summary>
public ref class Variant
{
public:

	/// <summary>
	/// Type de données possibles pour un Variant
	///	</summary>
	enum class VType 
	{ 
		UNDEFINED,NUMBER,STRING,BOOL
	};

private:
	/// <summary>
	/// valeur courante de type String^ (membre privé)
	///	</summary>
	String^ _sValue;

	/// <summary>
	/// valeur courante de type double (membre privé)
	///	</summary>
	double _nValue;

	/// <summary>
	/// valeur courante de type booléen (membre privé)
	///	</summary>
	bool _bValue;
	
	/// <summary>
	/// type courant (membre privé)
	///	</summary>
	VType vType;

public:
	/// <summary>
	/// Constructeur, type = UNDEFINED, valeur = UNDEFINED
	///	</summary>
	Variant()
	{
		vType = VType::UNDEFINED;

		_sValue = "";
		_nValue = 0;
		_bValue = false;
	}

	/// <summary>
	/// Obtient le type
	///	</summary>
	property VType Type
	{
		VType get() 
		{ 
			return vType; 
		}
	}

	/// <summary>
	/// Obtient ou définit la valeur String^
	///	</summary>
	property String^ sValue
	{
		String^ get() 
		{ 
			switch(vType)
			{
			default:
			case VType::STRING:
					return _sValue; 

			case VType::NUMBER:
					return "" + _nValue;
			}
		}

		void set(String^ value)
		{
			this->_sValue = value;
			this->vType = VType::STRING;
		}
	}

	/// <summary>
	/// Obtient ou définit la valeur double
	///	</summary>
	property double nValue
	{
		double get() 
		{ 
			return _nValue; 
		}

		void set(double value)
		{
			this->_nValue = value;
			this->vType = VType::NUMBER;
		}
	}

	/// <summary>
	/// Obtient ou définit la valeur booléenne
	///	</summary>
	property bool bValue
	{
		bool get() 
		{ 
			return _bValue; 
		}

		void set(bool value)
		{
			this->_bValue = value;
			this->vType = VType::BOOL;
		}
	}

	/// <summary>
	/// Recopie à partir d'une autre Variant
	///	</summary>	
	void CopyFrom(Variant^ v)
	{
		this->vType = v->vType;
		this->nValue = v->nValue;
		this->bValue = v->bValue;
		this->sValue = v->sValue;
	}	
};