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

  M.A.M.E.32  -  Multiple Arcade Machine Emulator for Win32
  Win32 Portions Copyright (C) 1997-2001 Michael Soderstrom and Chris Kirmse

  This file is part of MAME32, and may only be used, modified and
  distributed under the terms of the MAME license, in "readme.txt".
  By continuing to use, modify or distribute this file you indicate
  that you have read the license and understand and accept it fully.

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

  audit32.c

  Audit dialog

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

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <stdio.h>

#ifdef BUILD_ENGLISH
#include "resrce.h"
#else
#include "resrcj.h"
#endif

#include <driver.h>
#include <audit.h>
#include <unzip.h>

#include "win32ui.h"
#include "audit32.h"
#include "Properties.h"
#include "win32text.h"
#include "tsv.h"

/***************************************************************************
    function prototypes
 ***************************************************************************/

static DWORD WINAPI AuditThreadProc(LPVOID hDlg);
static INT_PTR CALLBACK AuditWindowProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam);
static void ProcessNextRom(void);
static void __cdecl DetailsPrintf(char *fmt, ...);
static char * StatusString(int iStatus);

/***************************************************************************
    Internal variables
 ***************************************************************************/

HWND hAudit;
static int rom_index;
static int roms_correct;
static int roms_incorrect;

static BOOL bPaused = FALSE;
static BOOL bCancel = FALSE;

/***************************************************************************
    External functions  
 ***************************************************************************/

void AuditDialog(HWND hParent)
{
	rom_index         = 0;
	roms_correct      = 0;
	roms_incorrect    = 0;

	DialogBox(GetModuleHandle(NULL),
			  MAKEINTRESOURCE(IDD_AUDIT),
			  hParent,
			  AuditWindowProc);
}

void InitGameAudit(int gameIndex)
{
	rom_index = gameIndex;
}

/***************************************************************************
    Internal functions
 ***************************************************************************/

static DWORD WINAPI AuditThreadProc(LPVOID hDlg)
{
	char buffer[200];

	while (!bCancel)
	{
		if (!bPaused)
		{
			if (rom_index != -1)
			{
				sprintf(buffer, "Checking Game %s - %s",
					drivers[rom_index]->name, drivers[rom_index]->description);
				SetWindowText(hDlg, buffer);
				ProcessNextRom();
			}
			else
			{
				sprintf(buffer, "%s", "File Audit");
				SetWindowText(hDlg, buffer);
				EnableWindow(GetDlgItem(hDlg, IDPAUSE), FALSE);
				ExitThread(1);
			}
		}
	}
	return 0;
}

static INT_PTR CALLBACK AuditWindowProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
{
	static HANDLE hThread;
	static DWORD dwThreadID;
	DWORD dwExitCode;

	switch (Msg)
	{
	case WM_INITDIALOG:
		hAudit = hDlg;
		SendDlgItemMessage(hDlg, IDC_ROMS_PROGRESS,    PBM_SETRANGE, 0, MAKELPARAM(0, GetNumGames()));
		bPaused = FALSE;
		bCancel = FALSE;
		rom_index = 0;

		hThread = CreateThread(NULL, 0, AuditThreadProc, hDlg, 0, &dwThreadID);
		return 1;

	case WM_COMMAND:
		switch (LOWORD(wParam))
		{
		case IDCANCEL:
			if (hThread)
			{
				bCancel = TRUE;
				if (GetExitCodeThread(hThread, &dwExitCode) && dwExitCode == STILL_ACTIVE)
				{
					PostMessage(hDlg, WM_COMMAND, wParam, lParam);
					return 1;
				}
				CloseHandle(hThread);
			}
			EndDialog(hDlg,0);
			break;

		case IDPAUSE:
			if (bPaused)
			{
				SendDlgItemMessage(hAudit, IDPAUSE, WM_SETTEXT, 0, (LPARAM)"Pause");
				bPaused = FALSE;
			}
			else
			{
				SendDlgItemMessage(hAudit, IDPAUSE, WM_SETTEXT, 0, (LPARAM)"Continue");
				bPaused = TRUE;
			}
			break;
		}
		return 1;
	}
	return 0;
}


/* Callback for the Audit property sheet */
INT_PTR CALLBACK GameAuditDialogProc(HWND hDlg,UINT Msg,WPARAM wParam,LPARAM lParam)
{
	switch (Msg)
	{
	case WM_INITDIALOG:
		unzip_cache_clear();
		hAudit = hDlg;
		Static_SetText(GetDlgItem(hDlg, IDC_PROP_TITLE), GameInfoTitle(rom_index));
		SetTimer(hDlg, 0, 1, NULL);
		return 1;

	case WM_TIMER:
		KillTimer(hDlg, 0);
		{
			int iStatus;

			iStatus = VerifyRomSet(rom_index, DetailsPrintf);
			SetHasRoms(rom_index, (iStatus == CORRECT || iStatus == BEST_AVAILABLE) ? 1 : 0);
			SetWindowText(GetDlgItem(hDlg, IDC_PROP_ROMS), StatusString(iStatus));
		}
		ShowWindow(hDlg, SW_SHOW);
		break;
	}
	return 0;
}

static void ProcessNextRom()
{
	int retval;
	char buffer[200];

	retval = VerifyRomSet(rom_index, DetailsPrintf);
	switch (retval)
	{
	case BEST_AVAILABLE: /* correct, incorrect or separate count? */
	case CORRECT:
		roms_correct++;
		sprintf(buffer, "%i", roms_correct);
		SendDlgItemMessage(hAudit, IDC_ROMS_CORRECT, WM_SETTEXT, 0, (LPARAM)buffer);
		sprintf(buffer, "%i", roms_correct + roms_incorrect);
		SendDlgItemMessage(hAudit, IDC_ROMS_TOTAL, WM_SETTEXT, 0, (LPARAM)buffer);
		break;

	case NOTFOUND:
		break;

	case INCORRECT:
		roms_incorrect++;
		sprintf(buffer, "%i", roms_incorrect);
		SendDlgItemMessage(hAudit, IDC_ROMS_INCORRECT, WM_SETTEXT, 0, (LPARAM)buffer);
		sprintf(buffer, "%i", roms_correct + roms_incorrect);
		SendDlgItemMessage(hAudit, IDC_ROMS_TOTAL, WM_SETTEXT, 0, (LPARAM)buffer);
		break;
	}

	SetHasRoms(rom_index, (retval == CORRECT || retval == BEST_AVAILABLE) ? 1 : 0);
	rom_index++;
	SendDlgItemMessage(hAudit, IDC_ROMS_PROGRESS, PBM_SETPOS, rom_index, 0);

	if (rom_index == GetNumGames())
	{
		rom_index = -1;
	}
}

static void __cdecl DetailsPrintf(char *fmt, ...)
{
	HWND	hEdit;
	va_list marker;
	char	buffer[2000];
	char	buffer2[4000];
	int 	source;
	int 	dest;
	
	hEdit = GetDlgItem(hAudit, IDC_AUDIT_DETAILS);
	
	va_start(marker, fmt);
	
	vsprintf(buffer, fmt, marker);
	
	va_end(marker);
	
	/* convert \n's to \r\n */
	source = 0;
	dest = 0;
	while (buffer[source] != 0)
	{
		if (buffer[source] == '\n')
		{
			buffer2[dest++] = '\r';
			buffer2[dest++] = '\n';
		}
		else
			buffer2[dest++] = buffer[source];
		source++;
	}
	buffer2[dest] = 0;
	
	Edit_SetSel(hEdit, Edit_GetTextLength(hEdit), Edit_GetTextLength(hEdit));
	Edit_ReplaceSel(hEdit, buffer2);
}

static char * StatusString(int iStatus)
{
	static char* ptr;

	ptr = (char *)win32_getstring(WIN32_audit_nonerequired);

	switch (iStatus)
	{
	case CORRECT:
		ptr = (char *)win32_getstring(WIN32_audit_passed);
		break;
		
	case BEST_AVAILABLE:
		ptr = (char *)win32_getstring(WIN32_audit_bestavailable);
		break;
		
	case CLONE_NOTFOUND:
	case NOTFOUND:
		ptr = (char *)win32_getstring(WIN32_audit_notfound);
		break;
		
	case INCORRECT:
		ptr = (char *)win32_getstring(WIN32_audit_failed);
		break;
	}

	return ptr;
}
