#ifndef __KERNEL_MODULE_H
#define __KERNEL_MODULE_H

#include <List.h>
#include <kernel/KObject.h>
#include <kernel/Spinlock.h>

namespace OS {
	class Module : public Kernel::KObject {
	  public:
		enum ModuleInitLevel {
			LEVEL_BOOT = 0,
			LEVEL_HEAP = 100,
			LEVEL_SCHEDULER = 200,
			LEVEL_INTS = 300,
			LEVEL_TIMERS = 400,
			LEVEL_PRETHREAD = 500,
			LEVEL_THREAD = 600,
			LEVEL_DEV = 700,
			MAX_LEVEL = 1000
		};
		Module(const char *name, int initOrder, status_t (*initRoutine)(Module *));
		virtual ~Module();

	  private:
		int mInitOrder;
		status_t (*mInitRoutine)(Module *);
		bool mInitRoutineCalled; // defaults to false, set to true after init routine is called

		ListNode<Module> mModuleListNode;

		friend class ModuleList;
	};

	// classic singleton, to insure it's constructed before any of the modules
	class ModuleList {
	  public:
		static ModuleList *Instance();

		void AddModule(Module *m);
		status_t SetInitLevel(Module::ModuleInitLevel level); // calls all the module init routines up to and including the level

	  private:
		ModuleList(); // private constructor, constructed in Instance

		List<Module> mModuleList;
		Kernel::Spinlock mModuleListLock;
	};
} // namespace OS

#endif
