#ifndef MINATO__DEBUG_H
#define MINATO__DEBUG_H

#include <stdlib.h>

#define RESULT
#define ALLOCATED
#define RELEASE

#define BOOL int
#define TRUE 1
#define FALSE 0

ALLOCATED char* mystrdup(char* str);
ALLOCATED void* mymalloc(size_t size);
ALLOCATED void* myrealloc(void* ptr, size_t size);
  
///////////////////////////////////////////////////////////////////////////////
// for debug
///////////////////////////////////////////////////////////////////////////////
#ifdef DEBUG

#include <stdarg.h>

void Assert(BOOL condition, const char* file_name, int line, const char* func_name);
char* Format(char* str, ...);

void CheckMemLeak_Begin();
void CheckMemLeak_End();
ALLOCATED void* CheckMemLeak_Malloc(size_t size, const char* file_name, int line, const char* func_name);
ALLOCATED char* CheckMemLeak_Strdup(char* str, const char* file_name, int line, const char* func_name);
ALLOCATED void* CheckMemLeak_Realloc(void* ptr, size_t size, const char* file_name, int line, const char* func_name);
void CheckMemLeak_Free(RELEASE void* memory, const char* file_name, int line, const char* func_name);

void Log_Begin(BOOL clear);
void Log_End();
void Log_Write(char* str, ...);
int Log_Writeln(char* str, ...);
void Log_Dump(void* buf, int size, BOOL addr);
void Log_TraceBegin(const char* file_name, int line, const char* func_name);
void Log_TraceEnd();

#   define CHECKML_BEGIN() CheckMemLeak_Begin();
#   define LOG_BEGIN() Log_Begin(TRUE); 
#   define CHECKML_END() CheckMemLeak_End(); 
#   define LOG_END()  Log_End();

#   define M(o) Log_Writeln o;
#   define TBEGIN() Log_TraceBegin(__FILE__, __LINE__, __FUNCTION__);
#   define TEND() Log_TraceEnd();
#   define ASSERT(o) Assert(o, __FILE__, __LINE__, __FUNCTION__);

#   define MALLOC(o) CheckMemLeak_Malloc(o, __FILE__, __LINE__, __FUNCTION__)
#   define STRDUP(o) CheckMemLeak_Strdup(o, __FILE__, __LINE__, __FUNCTION__)
#   define REALLOC(o, o2) CheckMemLeak_Realloc(o, o2, __FILE__, __LINE__, __FUNCTION__)
#   define FREE(o) CheckMemLeak_Free(o, __FILE__, __LINE__, __FUNCTION__)

#else

#   define CHECKML_BEGIN()
#   define LOG_BEGIN()
#   define CHECKML_END()  
#   define LOG_END()

#   define M(o)
#   define TBEGIN()
#   define TEND()
#   define ASSERT(o)

#   define MALLOC(o) mymalloc(o)
#   define STRDUP(o) mystrdup(o)
#   define REALLOC(o, o2) myrealloc(o, o2)
#   define FREE(o) free(o)

#endif

#endif
