#pragma once

#include "Vector.h"
#include "BaseObj.h"
#include "ehs/system/Mutex.h"
#include "ehs/system/Thread.h"

namespace ehs
{
	typedef bool (*GcLogic)(BaseObj*);

	class EHS_LIB_IO GC
	{
	private:
		static Array<GcLogic> logic;
		static Vector<BaseObj*> garbage;
		static UInt_64 max;
		static Thread thread;
        static Mutex mutex;
		static bool running;

		static bool Has(const BaseObj* obj);

	public:
		static void Start();

		static void Stop();

		static bool HasLogic(GcLogic logicCb);

		static bool AddLogic(GcLogic logicCb);

		/// Adds an object to the garbage pile to be deleted.
		/// @param[in] obj The object to be deleted.
		static void Add(BaseObj* obj);

		/// Sets the maximum amount of garbage to delete per poll.
		/// @param[in] newMax The new maximum.
		static void SetMax(UInt_64 newMax);

		/// Gets the maximum amount of garbage to delete per poll.
		/// @returns The maximum.
		static UInt_64 GetMax();

		/// Sets a new amount for memory pre-allocation to save on memory operations.
		/// @param[in] newStride The stride to pre-allocate.
		static void SetStride(UInt_64 newStride);

		/// The amount of data pre-allocated to save on memory operations.
		/// @returns The stride.
		static UInt_64 GetStride();

		/// Gets the garbage count.
		/// @returns Garbage count.
		static UInt_64 Size();

		/// Used to delete objects over time.
		static void Poll();

		/// Deletes all of the data at once.
		/// @warning Use Poll instead to prevent stutter.
		static void Dump();

		static bool IsRunning();

	private:
		static bool ShouldDelete(BaseObj *obj);
	};
}