
#include <windows.h>
#include "die.h"
#include <stdio.h>
#pragma comment(lib, "./../die.lib")
#pragma warning(disable : 4996)  //depreceated function

#define EXPORT comment(linker, "/EXPORT:" __FUNCTION__"=" __FUNCDNAME__)

typedef void(__stdcall* vbCallback)(int, char*);

vbCallback vbStdOut = 0;
wchar_t* g_pwszBuffer;
int g_nBufferSize;
wchar_t* g_pszFileName;
unsigned int g_nFlags;
wchar_t* g_pszDatabase;
int g_ret;
int gAbort = 0;


void __stdcall SetCallBacks(void* lpfnMsgHandler) {
#pragma EXPORT
	vbStdOut = (vbCallback)lpfnMsgHandler;
}

void __stdcall Abort(void) {
#pragma EXPORT
    gAbort=1;
}


DWORD WINAPI MyThreadFunction(LPVOID lpParam)
{
    g_ret = DIE_VB_ScanFile(g_pszFileName, g_nFlags, g_pszDatabase, g_pwszBuffer, g_nBufferSize);
    return g_ret;
}

bool isThreadRunning(HANDLE hThread) {
    DWORD exitCode;
    if (GetExitCodeThread(hThread, &exitCode)) {
        return exitCode == STILL_ACTIVE;
    }
    return false; // Error occurred
}

int __stdcall DIEScan(wchar_t* pszFileName, unsigned int nFlags, wchar_t* pszDatabase, wchar_t* pwszBuffer, int nBufferSize) {
#pragma EXPORT

    gAbort = 0;
    g_ret = 0;

    //single threaded host
    g_pwszBuffer = pwszBuffer;
    g_nBufferSize = nBufferSize;
    g_pszFileName = pszFileName;
    g_nFlags = nFlags;
    g_pszDatabase = pszDatabase;

    int i = 0;
    DWORD dwThreadId = 0;

    HANDLE hThread = CreateThread(
        NULL,                   // default security attributes
        0,                      // use default stack size  
        MyThreadFunction,       // thread function name
        0,                      // argument to thread function 
        0,                      // use default creation flags 
        &dwThreadId);           // returns the thread identifier

    while(isThreadRunning(hThread)){
        Sleep(10);
        i++;
        if (i == 10) {
            if (vbStdOut != 0) vbStdOut(0, 0); //allows ui refresh
            i = 0;
        }
        if (gAbort) {
            TerminateThread(hThread, 0);
        }
    }

    return g_ret;
}
