#pragma once
#include <new>
#include "typedefs.h"
//#include "ProcessMan.h"

template <class> class Vector;


class MemMan
{
public:
	static void Init();
	static MemMan &Inst(){return *(MemMan *)buf;}

private:
	MemMan(void);
	~MemMan(void);
	static BYTE buf[];
	static void* operator new(size_t size, void* pbuf){ return pbuf; }

#pragma pack(push, 1)
	struct PAGEINFO{
		BYTE commited:1;
		BYTE unpageoutable:1;
		BYTE system:1;
		DWORD pid;
	};
#pragma pack(pop)
	int pages_for_pageinfo, maxfirst, pagecount;
	static const DWORD FIRST_BEGIN = 0x00001000;
	static const DWORD FIRST_END = 0x0009f000;
	static const DWORD SECOND_BEGIN = 0x00400000;

	
	PAGEINFO *getpageinfo(DWORD i);
	DWORD getpageaddr(DWORD i);
	DWORD getpageindex(DWORD addr);

public:
	DWORD malloc(bool unpageoutable, bool system, DWORD pid, DWORD count = 1);
	void free(DWORD addr, DWORD count = 1);

	static DWORD neccesarypagecount(DWORD size){
		return (size + PAGE_SIZE - 1) / PAGE_SIZE;
	}
private:
	DWORD memsize;

	DWORD memtest(DWORD start, DWORD end);
	DWORD memtest_sub(DWORD start, DWORD end);

public:
	void *sys_malloc(size_t size);
	void sys_free(void *p);
private:

	struct MEMINFO{
		DWORD addr, size;
	};
	Vector<MEMINFO> *minfo;

};


class phymemdeleter {
	DWORD count;
public:
	phymemdeleter(DWORD count = 1):count(count){
	}
	template <class T>
	void operator ()(T *p){
		MemMan::Inst().free((DWORD)p, count);
	}
};
