/* -----------------------------------------------------------------------------
	GSFramework
	Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */


#ifndef	__NVARIANT__
#define	__NVARIANT__


		#include "nstring/nstring.h"


namespace GS {

/*!
	@short	Base property.
	@author	Emmanuel Julien (ejulien@gsworks.fr)
*/
class	Variant
{
public:

enum	Type
{
	VariantNone		=	0,
	VariantFloat,
	VariantBool,
	VariantInteger,
	VariantString,
	VariantBinary
};

protected:

		void				Reset();

public:

/*!
	@name	Property value.
	@{
*/
		Type			type;

		union
		{
			char		*d_value;
			bool		b_value;
			float		f_value;
			int			i_value;
			uint		u_value;
		};

		size_t			d_size;				/// Binary data size.
		String			s_value;
/// @}

		String			id;					///< Variant id.

		bool			operator < (const Variant &b) const;
		bool			operator > (const Variant &b) const;
		bool			operator == (const Variant &b) const;
		bool			operator != (const Variant &b) const;

		Variant			&operator = (bool v);
		Variant			&operator = (int v);
		Variant			&operator = (uint v);
		Variant			&operator = (const char *v);
		Variant			&operator = (float v);

		Variant			&operator = (const Variant &v);

		/// Get property type.
		Type			GetType() const { return type; }
		/// Free current property value.
		void			Free();

		/// Get string value.
		bool			Get(const char * &v) const;
		/// Get bool value.
		bool			Get(bool &v) const;
		/// Get integer value.
		bool			Get(int &v) const;
		/// Get unsigned value.
		bool			Get(uint &v) const;
		/// Get float value.
		bool			Get(float &v) const;

		/// Set binary data.
		bool			SetBinary(const void *data, size_t size);
		/// Get binary data.
		bool			GetBinary(void *&data, size_t &size) const;

		/// Direct access to the binary buffer.
		void			*GetBinaryBuffer() const { return GetType() == VariantBinary ? (void *)d_value : 0; }
		/// Binary buffer size.
		size_t			GetBinarySize() const { return GetType() == VariantBinary ? d_size : 0; }

		/// Get children array.
		bool			Get(List <Variant *> &a);

		Variant(const char *v)
		{	Reset(); *this = v;	}
		Variant(bool v)
		{	Reset(); *this = v;	}
		Variant(int v)
		{	Reset(); *this = v;	}
		Variant(uint v)
		{	Reset(); *this = v;	}
		Variant(float v)
		{	Reset(); *this = v;	}
		Variant(void *d, size_t l)
		{	Reset(); SetBinary(d, l);  }

		Variant(const char *i, const char *v)
		{	Reset(); id = i; *this = v;	}
		Variant(const char *i, bool v)
		{	Reset(); id = i; *this = v;	}
		Variant(const char *i, int v)
		{	Reset(); id = i; *this = v;	}
		Variant(const char *i, uint v)
		{	Reset(); id = i; *this = v;	}
		Variant(const char *i, float v)
		{	Reset(); id = i; *this = v;	}

		Variant()
		{	Reset();	}
		~Variant();
};

}


#endif	// __NVARIANT__

