/** @file encodercontext.h
*	native encoder context interface and base class
*	@author Chris Burns (cburns@ea.com)
*
*	EABaseTypes
*	(c) 2012 Electronic Arts Inc.
*/

#ifndef EABASETYPES_IENCODERCONTEXT_H_
#define EABASETYPES_IENCODERCONTEXT_H_

// for size_t
#include "EABase/eabase.h"

#include "EABaseTypes/basetypefloat.h"
#include "EABaseTypes/autoref.h"

namespace EA
{
	namespace Types
	{
		EABASETYPES_FORWARD_DECLARATION(class, Function)
		EABASETYPES_FORWARD_DECLARATION(class, UserData)
		
		class IEncoderContext;

		class IEncoderContext
		{
		public:

			virtual ~IEncoderContext() {}
	
			virtual IEncoderContext* Reset() = 0;

			virtual void BeginArray() = 0;
			virtual IEncoderContext* EndArray() = 0;

			virtual IEncoderContext* BeginArrayValue(size_t index) = 0;
			virtual void EndArrayValue(size_t index) = 0;

			virtual void BeginObject() = 0;
			virtual IEncoderContext* EndObject() = 0;

			virtual IEncoderContext* BeginObjectValue(const char* key, size_t length) = 0;
			virtual void EndObjectValue(const char* key, size_t length) = 0;

			virtual IEncoderContext* Boolean(bool boolean) = 0;
			virtual IEncoderContext* Number(BaseTypeFloat number) = 0;
			virtual IEncoderContext* String(const char* str, size_t length) = 0;
			virtual IEncoderContext* Function(FunctionIn function) = 0;
			virtual IEncoderContext* UserData(UserDataIn userData) = 0;
			virtual IEncoderContext* Null() = 0;
		};

		class ChildContext : public IEncoderContext
		{
		public:

			inline ChildContext(IEncoderContext* parent, void* value):mParent(parent),mValue(value) {}

			inline void SetParent(IEncoderContext* parent) { mParent = parent; }
		
			virtual IEncoderContext* Reset();
			virtual void BeginArray();
			virtual IEncoderContext* EndArray();
			virtual IEncoderContext* BeginArrayValue(size_t index);
			virtual void EndArrayValue(size_t index);
			virtual void BeginObject();
			virtual IEncoderContext* EndObject();
			virtual IEncoderContext* BeginObjectValue(const char* key, size_t length);
			virtual void EndObjectValue(const char* key, size_t length);
			virtual IEncoderContext* Boolean(bool boolean);
			virtual IEncoderContext* Number(BaseTypeFloat number);
			virtual IEncoderContext* String(const char* str, size_t length);
			virtual IEncoderContext* Function(FunctionIn function);
			virtual IEncoderContext* UserData(UserDataIn userData);
			virtual IEncoderContext* Null();
		
			void*			 mValue;

		protected:

			IEncoderContext* mParent;
		};
	}
}

#endif /* EABASETYPES_IENCODERCONTEXT_H_ */
