// aplWinDefineForGCC.h
// Здесь собраны аналоги определений WinAPI для компиляции кода под GCC

#pragma once

#ifndef _MFC_VER

#ifdef __linux__
	// В Linux у этих спецификаторов нет смысла
	#define __stdcall
	#define __cdecl
	#define  _fileno fileno
#else
	#include <libloaderapi.h> // Для использования GetModuleFileName 
	#include <errhandlingapi.h>  // Для использования GetLastError()
	#include <sysinfoapi.h>  // Для использования GetTickCount
#endif

#define VERIFY(p) {if(!p) throw;}

#define TRY try
#define CATCH catch
#define END_CATCH

#define AFX_EXT_CLASS
#define AFX_EXT_API

#include <cstddef>	// стандартные типы
#include <string.h>
#include <algorithm>
#include <assert.h>
#include <exception>
#include <thread>

#ifdef __GNUC__
    #include <unistd.h> // для getpid()
    #include <sys/time.h> // для gettimeofday
#endif

using namespace std;

typedef uint8_t BYTE;
typedef uint16_t WORD;
typedef unsigned long DWORD;
typedef unsigned char BYTE;	
typedef int BOOL;
typedef unsigned int UINT;
typedef long LONG;
typedef unsigned long ULONG;
//typedef unsigned long LCID;
typedef unsigned short USHORT;
typedef double DATE;
typedef UINT (*AFX_THREADPROC)(void*);
typedef void *LPVOID;

#ifdef __linux__
typedef long long __int64;
typedef __int64 INT_PTR, *PINT_PTR;
//#else
//typedef __int32 INT_PTR, *PINT_PTR;
#endif

#ifndef _APISETLIBLOADER_  // Определено в <libloaderapi.h>

typedef void *HINSTANCE;
typedef void *HANDLE;

#endif

#ifdef __linux__
	typedef int32_t INT32;
	typedef uint32_t UINT32;
	typedef int64_t INT64;
	typedef uint64_t UINT64;
#endif

typedef INT64 LONGLONG;
typedef UINT64 ULONGLONG;

// строки из Windows
typedef wchar_t* LPWSTR;
typedef const wchar_t* LPCWSTR;
typedef char* LPSTR;
typedef const char* LPCSTR;

#ifdef UNICODE
typedef wchar_t TCHAR;
typedef LPWSTR LPTSTR;
typedef LPCWSTR LPCTSTR;
#else
typedef char TCHAR;
typedef LPSTR LPTSTR;
typedef LPCSTR LPCTSTR;
#endif

#define TRUE 1
#define FALSE 0

//?	#define LONG_MIN        (-2147483647L - 1)
//?	#define LONG_MAX        2147483647L


#define MAX_PATH 260
#define MAX_INT32     0x7fffffff

#ifdef _DEBUG
#define TRACE(_p)// printf(_p)
#else
#define TRACE(_p)
#endif

#ifdef UNICODE
#define __T(x) L ## x 
#else
#define __T(x) x
#endif

#define _T(x) __T(x)

#ifndef INVALID_HANDLE_VALUE
	#define INVALID_HANDLE_VALUE ((void*)-1)
#endif


// идентификатор текущего потока
//#define GetCurrentThreadId this_thread::get_id - функция возвращает сложный объект std, который к числу приводится еще более сложным образом
// проще использовать переопределенный системный вызов, который возвращает pid_t, по сути небольшое по разрядности целое число
#ifdef __linux__

#include <unistd.h>
#include <sys/syscall.h>
// описание функции: pid_t GetCurrentThreadId();
#define GetCurrentThreadId() syscall(SYS_gettid)
#else
#include <handleapi.h>
#include <processthreadsapi.h>
#endif

#ifdef __GNUC__
#define GetCurrentProcessId() getpid()  // идентификатор текущего процесса
#endif


#ifndef _APISETLIBLOADER_  // Определено в <libloaderapi.h>

#define ZeroMemory(Destination,Length) memset((Destination),0,(Length))

// определяем структуру времени а ля Windows
typedef struct _SYSTEMTIME {
	WORD wYear;
	WORD wMonth;
	WORD wDayOfWeek;
	WORD wDay;
	WORD wHour;
	WORD wMinute;
	WORD wSecond;
	WORD wMilliseconds;
} SYSTEMTIME, *PSYSTEMTIME;

#endif

#ifndef _OLEAUTO_H_  // Для устранания конфликта с oleauto.h, который входит в MinGW и используется, например,в QQuickWidget 

	#ifndef __GNUC__
		#include <OleAuto.h>
	#else
		typedef struct {
			SYSTEMTIME st;
			USHORT  wDayOfYear;
		} UDATE;
	#endif

#endif

#ifdef __linux__

inline unsigned long APL_AGGR_API GetTickCount()
{
    //return clock(); DIV: функция возвращает некие абстрактные тики, к милисекундам абсолютного времени их не привести
    struct timeval current;
    gettimeofday(&current, NULL);
    // tv_usec - микросекунды, tv_sec - секунды. Приводим их к милисекундам и складываем
    return current.tv_sec * 1000  + (current.tv_usec/1000);
}

void APL_AGGR_API GetLocalTime(PSYSTEMTIME lpSystemTime);

inline DWORD GetLastError(){return (int)errno;}

#endif

class CaplFile;
class CaplFileException;
class CaplFileFind;
class CaplDateTime;
class CaplDateTimeSpan;
typedef CaplFile CFile;
typedef CaplFileException CFileException;
typedef CaplFileFind CFileFind;
typedef CaplDateTime COleDateTime;
typedef CaplDateTimeSpan COleDateTimeSpan;

//****************************************************************************************
//****************************************************************************************
//****************************************************************************************

#ifndef MB_OK

#define MB_OK                       0x00000000L
#define MB_OKCANCEL                 0x00000001L
#define MB_ABORTRETRYIGNORE         0x00000002L
#define MB_YESNOCANCEL              0x00000003L
#define MB_YESNO                    0x00000004L
#define MB_RETRYCANCEL              0x00000005L
#define MB_CANCELTRYCONTINUE        0x00000006L

#define MB_ICONHAND                 0x00000010L
#define MB_ICONQUESTION             0x00000020L
#define MB_ICONEXCLAMATION          0x00000030L
#define MB_ICONASTERISK             0x00000040L
#define MB_USERICON                 0x00000080L
#define MB_ICONWARNING              MB_ICONEXCLAMATION
#define MB_ICONERROR                MB_ICONHAND
#define MB_ICONINFORMATION          MB_ICONASTERISK
#define MB_ICONSTOP                 MB_ICONHAND

#define MB_APPLMODAL                0x00000000L
#define MB_SYSTEMMODAL              0x00001000L
#define MB_TASKMODAL                0x00002000L

#endif

#ifndef IDOK

#define IDOK            1
#define IDCANCEL        2
#define IDABORT         3
#define IDRETRY         4
#define IDIGNORE        5
#define IDYES           6
#define IDNO            7
#define IDCLOSE         8
#define IDHELP          9
#define IDTRYAGAIN      10
#define IDCONTINUE      11

#define MB_DEFBUTTON1               0x00000000L
#define MB_DEFBUTTON2               0x00000100L
#define MB_DEFBUTTON3               0x00000200L
#define MB_DEFBUTTON4               0x00000300L

#endif

//****************************************************************************************
//****************************************************************************************
//****************************************************************************************
// Макросы преобразований CString <-> QString

 #ifdef UNICODE
	#define CS2QS(s) QString::fromWCharArray(LPCWSTR(s))
	#define QS2CS(s) (s.toStdWString()).c_str()
#else
	#define CS2QS(s) QString((LPCSTR)s) 
	#define QS2CS(s) (s.toStdString()).c_str()
#endif

// Старые варианты:
//#define QS2CS(s)   (const wchar_t*)s.utf16()
//#define QS2CS(s)   (const char*)s.toUtf8()

#endif

