/** @file ptruserdata.h
*	Userdata type for raw pointers
*	@author Jeff Skelton (jeff@ea.com)
*
*	EABaseTypes
*	(c) 2012 Electronic Arts Inc.
*/

#ifndef EABASETYPES_PTRUSERDATA_H
#define EABASETYPES_PTRUSERDATA_H

#include "eabasetypes/datatypes.h"

namespace EA
{
	namespace Types
	{
		template<typename T> class PtrUserData : public EA::Types::UserData
		{
		public:

			virtual BaseTypeReturn Clone() { return Create(mFactory, mPtr); }

			virtual bool Equals(UserDataIn pCompare)
			{
				return EA::Type::TypeOf(*this) == pCompare->GetUserDataType() && mPtr == static_cast<PtrUserData<T>*>(pCompare.GetUnsafePointer())->mPtr;
			}

			virtual EA::Type::TypeID GetUserDataType() { return EA::Type::TypeOf(*this); }

			static UserDataReturn Create(Factory* factory, T* ptr) { return new(factory) PtrUserData<T>(factory, ptr); }

			static T* AsPtr(BaseTypeIn baseType)
			{
				if(baseType != NULL && baseType->GetType() == EA::Types::USERDATA_TYPE && baseType->AsUserData()->GetUserDataType() == EA::Type::TypeOf<PtrUserData<T> >())
				{
					return static_cast<PtrUserData<T>*>(baseType.GetUnsafePointer())->mPtr;
				}
				else
				{
					return NULL;
				}
			}

		private:

			PtrUserData(Factory* factory, T* ptr):UserData(factory), mPtr(ptr) {}

			T*	mPtr;
		};
        
        template <class T>
        UserDataReturn PtrUserDataCreate(EA::Types::Factory* f, T* p)
        {
            return PtrUserData<T>::Create(f, p);
        }
	}
}

#endif // EABASETYPES_PTRUSERDATA_H
