#include <dos/dos.h>
#include <proto/dos.h>

typedef void *HANDLE;
typedef void *LPOVERLAPPED;
typedef uint32 DWORD;
typedef void *LPSECURITY_ATTRIBUTES;
typedef void *LPVOID;
typedef DWORD *LPDWORD;
typedef LONG *PLONG;

#define INVALID_HANDLE_VALUE ((HANDLE)(-1))
#define INVALID_FILE_SIZE    ((DWORD)0xFFFFFFFF)
#define INVALID_FILE_SET_POINTER ((DWORD)-1)
#define MAX_PATH 260

#define FILE_BEGIN    0
#define FILE_CURRENT  1
#define FILE_END      2

typedef char CHAR;
typedef CHAR TCHAR;
typedef char *LPSTR;
typedef TCHAR *LPTSTR;
typedef const char *LPCSTR;
typedef TCHAR *LPCTSTR;

typedef struct _FILETIME
{
  DWORD dwLowDateTime;
  DWORD dwHighDateTime;
} FILETIME,*PFILETIME,*LPFILETIME;

typedef struct _WIN32_FIND_DATA {
  DWORD dwFileAttributes;
  FILETIME ftCreationTime;
  FILETIME ftLastAccessTime;
  FILETIME ftLastWriteTime;
  DWORD nFileSizeHigh;
  DWORD nFileSizeLow;
  DWORD dwReserved0;
  DWORD dwReserved1;
  TCHAR cFileName[MAX_PATH];
  TCHAR cAlternateFileName[14];
} WIN32_FIND_DATA,*PWIN32_FIND_DATA,*LPWIN32_FIND_DATA;

HANDLE CreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
	LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition,
	DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{
	BPTR file;
	file = IDOS->Open(lpFileName, MODE_OLDFILE);
	return file ? (HANDLE)file : INVALID_HANDLE_VALUE;
}

BOOL CloseHandle(HANDLE hHandle) {
	if (hHandle != INVALID_HANDLE_VALUE) {
		IDOS->Close((BPTR)hHandle);
	}
	return TRUE;
}

BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead,
	LPOVERLAPPED lpOverlapped)
{
	BOOL res = FALSE;
	*lpNumberOfBytesRead = 0;
	if (hFile != INVALID_HANDLE_VALUE) {
		int32 bytesread;
		bytesread = IDOS->Read((BPTR)hFile, lpBuffer, nNumberOfBytesToRead);
		if (bytesread != -1) {
			*lpNumberOfBytesRead = bytesread;
			res = TRUE;
		}
	}
	return res;
}

DWORD GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh) {
	if (hFile != INVALID_HANDLE_VALUE) {
		return IDOS->GetFileSize((BPTR)hFile);
	}
	return INVALID_FILE_SIZE;
}

DWORD SetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod) {
	DWORD res = INVALID_FILE_SET_POINTER;
	if (hFile != INVALID_HANDLE_VALUE) {
		int32 mode;
		int64 newpos;
		switch (dwMoveMethod) {
			case FILE_BEGIN:
				mode = OFFSET_BEGINNING;
				break;
			case FILE_CURRENT:
				mode = OFFSET_CURRENT;
				break;
			case FILE_END:
				mode = OFFSET_END;
				break;
			default:
				return res;
		}
		newpos = lDistanceToMove;
		if (lpDistanceToMoveHigh) {
			newpos = ((uint64)*lpDistanceToMoveHigh << 32)|newpos;
		}
		if (IDOS->ChangeFilePosition((BPTR)hFile, newpos, mode)) {
			newpos = IDOS->GetFilePosition((BPTR)hFile);
			res = newpos;
			if (lpDistanceToMoveHigh) {
				*lpDistanceToMoveHigh = (uint64)newpos >> 32;
			} else if (newpos >= 0xffffffff) {
				res = INVALID_FILE_SET_POINTER;
			}
		}
	}
	return res;
}

HANDLE FindFirstFile(LPCTSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData) {
	return INVALID_HANDLE_VALUE;
}

BOOL FindNextFile(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData) {
	return FALSE;
}

BOOL FindClose(HANDLE hFindFile) {
	return TRUE;
}
