#ifndef __MEMMGR_H__
#define __MEMMGR_H__

extern "C" {
#include "multiboot.h"
}

#include "types.h"

struct Region {
    uint32  start;
    size_t  size;
    Region* prev;
    Region* next;
};

class RegionList {
public:
    RegionList(void) : top(0), bottom(0) {}
    void    add(Region& region);
    void    remove(Region& region);
    Region* merge(Region& region);
    Region* get(uint32 i);
    Region* searchBySize(size_t size);
    Region* searchByAddr(void*  addr);
    void show(void);

private:
    Region* top;
    Region* bottom;
};

class MemMgr
{
public:
    MemMgr(void);
    void  init(multiboot_info_t* mbi);
    void* alloc(size_t size);
    void  free(void* addr);
    // void* realloc(void* addr, size_t size);

private:
    static const uint32 PAGE_SIZE  = 0x1000;
    static const uint32 REGION_NUM = 1000; // Temporary

    uint32  start;
    size_t  size;

    RegionList allocs;
    RegionList notassigns;
    RegionList frees;

    Region regions[REGION_NUM];

    size_t getAllocSize(size_t size) const {
        return ((size + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE;
    }
};

extern MemMgr MemoryManager;

extern void* operator new(size_t size);
extern void  operator delete(void* addr);

#endif /* __MEMMGR_H__ */
