#pragma once

#include "Proxies.hpp"

namespace Proxies {

	//
	//#########################################################################
	//########################    GenericProxy    #############################
	//#########################################################################
	//
	class _declspec(novtable) GenericProxy:
		public Stuff::Plug
	{
	public:
		static void
			InitializeClass();
		static void
			TerminateClass();

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Constructors
	//
	public:
		virtual void
			Destroy() = 0;

	protected:
		GenericProxy(ClassData *class_data):
			Plug(class_data)
				{referenceCount = 1;}

		virtual ~GenericProxy()
			{Check_Object(this); Verify(!referenceCount);}

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Class Data Support
	//
	public:
		static ClassData
			*DefaultData;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Proxy name
	//
	public:
		//
		// Get the name of the proxy
		//
		virtual bool
			GetName(Stuff::MString *name) = 0;

		//
		// Set the name of the proxy
		//
		virtual void
			SetName(const char* name) = 0;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Reference counting
	//
	public:
		void
			AttachReference()
				{Check_Object(this); ++referenceCount;}
		void
			DetachReference()
				{
					Check_Object(this); Verify(referenceCount > 0);
					if ((--referenceCount) == 0)
					{
						Unregister_Object(this);
						delete this;
					}
				}

		int
			GetReferenceCount()
				{return referenceCount;}

	protected:
		int
			referenceCount;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	// Testing
	//
	public:
		void
			TestInstance() const;
	};

}
