// Compare.c : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
//


#include <windows.h>
#include <windowsx.h>
#include <stdio.h>



#pragma comment(lib, "Winmm.lib")

//#define DEBUG_PRINTF 1

typedef enum {
	REGIM_INIT = 0,
	REGIM_COMPARE = 1,
	REGIM_RESULT = 2
} eRegim;

typedef struct {
	RECT winRect;
	eRegim regim;
	wchar_t captionWindow[_MAX_PATH];
	wchar_t pathWav1[_MAX_PATH];
	wchar_t pathWav2[_MAX_PATH];

	wchar_t f1[_MAX_PATH];
	wchar_t f2[_MAX_PATH];


	BOOL error;
	int number;
	BOOL isFindResult;
	wchar_t textResult[_MAX_PATH];


} tCompareStruct;


static BOOL setTextHwnd(HWND hwnd, LPCWSTR text1, int timeout) {

	wchar_t text2[_MAX_PATH];
	wcscpy_s(text2, _MAX_PATH, L" ");

	for (int i = 0; i < timeout; ++i) {

		SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)text1);
		SendMessage(hwnd, WM_GETTEXT, _MAX_PATH, (LPARAM)text2);

		if (wcscmp(text1, text2) == 0) {
			return FALSE;
		} else {
			Sleep(100);
		}
	}

	return TRUE;
}

static BOOL setComboBoxHwnd(HWND hwnd, int index1, int timeout) {

	for (int i = 0; i < timeout; ++i) {

		ComboBox_SetCurSel(hwnd, index1);
		int index2 = ComboBox_GetCurSel(hwnd);

		if (index1 == index2) {
			return FALSE;
		}
		else {
			Sleep(100);
		}
	}

	return TRUE;
}

static BOOL CALLBACK enum_wnd_proc(HWND hwnd, LPARAM lParam) {
	tCompareStruct* compareStruct = (tCompareStruct*)lParam;

	wchar_t classText[_MAX_PATH];
	RECT Rect;

	GetClassName(hwnd, classText, _MAX_PATH);
	GetWindowRect(hwnd, &Rect);

	LONG LocalTop = Rect.top - compareStruct->winRect.top;

#ifdef DEBUG_PRINTF
	printf("HWND = %u, CLASS = %ls, GlobalTop = %d LocallTop = %d\n", hwnd, classText, Rect.top, LocalTop);
#endif

	if (compareStruct->regim == REGIM_INIT) {

		if ((wcscmp(classText, L"Edit") == 0) && (compareStruct->number == 4)) {

#ifdef DEBUG_PRINTF
			printf("Edit1 found!\n");
#endif
			compareStruct->error = setTextHwnd(hwnd, compareStruct->pathWav1, 50);

			if (compareStruct->error) {
				printf("Error: Edit1\n");
				return FALSE;
			}
		}

		if ((wcscmp(classText, L"Edit") == 0) && (compareStruct->number == 5)) {
#ifdef DEBUG_PRINTF
			printf("Edit2 found!\n");
#endif
			compareStruct->error = setTextHwnd(hwnd, compareStruct->pathWav2, 50);

			if (compareStruct->error) {
				printf("Error: Edit2\n");
				return FALSE;
			}
		}


		if ((wcscmp(classText, L"Edit") == 0) && (compareStruct->number == 12)) {

#ifdef DEBUG_PRINTF
			printf("Edit3 found!\n");
#endif
			compareStruct->error = setTextHwnd(hwnd, compareStruct->f1, 50);

			if (compareStruct->error) {
				printf("Error: Edit1\n");
				return FALSE;
			}
	}



		if ((wcscmp(classText, L"Edit") == 0) && (compareStruct->number == 14)) {

#ifdef DEBUG_PRINTF
			printf("Edit4 found!\n");
#endif
			compareStruct->error = setTextHwnd(hwnd, compareStruct->f2, 50);

			if (compareStruct->error) {
				printf("Error: Edit1\n");
				return FALSE;
			}
		}



		if ((wcscmp(classText, L"ComboBox") == 0) && (compareStruct->number == 18)) {
#ifdef DEBUG_PRINTF
			printf("ComboBox1 found!\n");
#endif

			compareStruct->error = setComboBoxHwnd(hwnd, 1, 50);

			if (compareStruct->error) {
				printf("Error: ComboBox1\n");
				return FALSE;
			}
		}

		if ((wcscmp(classText, L"ComboBox") == 0) && (compareStruct->number == 23)) {
#ifdef DEBUG_PRINTF
			printf("ComboBox2 found!\n");
#endif

			compareStruct->error = setComboBoxHwnd(hwnd, 1, 50);

			if (compareStruct->error) {
				printf("Error: ComboBox2\n");
				return FALSE;
			}
		}

		if ((wcscmp(classText, L"Static") == 0) && (compareStruct->number == 15)) {
#ifdef DEBUG_PRINTF
			printf("Static found!\n");
#endif
			wchar_t text[_MAX_PATH];
			wcscpy_s(text, _MAX_PATH, L" -200.0%");

			compareStruct->error = setTextHwnd(hwnd, text, 50);

			if (compareStruct->error) {
				printf("Error: Static\n");
				return FALSE;
			}

		}
	}

	if (compareStruct->regim == REGIM_COMPARE) {

		if ((wcscmp(classText, L"Button") == 0) && (compareStruct->number == 17)) {
#ifdef DEBUG_PRINTF
			printf("Button found!\n");
#endif
			LONG lParam = MAKELONG(243, 28);
			SendMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, lParam);
			SendMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, lParam);
			SendMessage(hwnd, WM_LBUTTONDOWN, MK_LBUTTON, lParam);
			Sleep(100);
			SendMessage(hwnd, WM_LBUTTONUP, MK_LBUTTON, lParam);
			SendMessage(hwnd, WM_LBUTTONUP, MK_LBUTTON, lParam);
			SendMessage(hwnd, WM_LBUTTONUP, MK_LBUTTON, lParam);
		}
	}


	if (compareStruct->regim == REGIM_RESULT) {
		if ((wcscmp(classText, L"Static") == 0) && (compareStruct->number == 15)) {
#ifdef DEBUG_PRINTF
			printf("Static found!\n");
#endif
			//wchar_t text[_MAX_PATH];
			//wcscpy_s(text, _MAX_PATH, L" ");

			wcscpy_s(compareStruct->textResult, _MAX_PATH, L" ");

			compareStruct->isFindResult = FALSE;

			for (int i = 0; i < 25; ++i) {
				SendMessage(hwnd, WM_GETTEXT, _MAX_PATH, (LPARAM)compareStruct->textResult);

				if (wcscmp(compareStruct->textResult, L" -200.0%") == 0) {
					Sleep(100);
				}
				else {
					compareStruct->isFindResult = TRUE;
					break;
				}
			}


		}
	}

	++compareStruct->number;

	return TRUE;
}

static void CALLBACK TimerUpdate(UINT wTimerID, UINT msg, DWORD dwUser, DWORD dwl, DWORD dw2) {

	tCompareStruct* compareStruct = (tCompareStruct*)dwUser;

	HWND hwnd = FindWindowW(NULL, compareStruct->captionWindow);

	if (hwnd != NULL) {
		PostMessage(hwnd, WM_CLOSE, 0, 0);
	}

}

int wmain(int argc, wchar_t* argv[], wchar_t* envp[]) {

	tCompareStruct compareStruct;

	compareStruct.error = FALSE;

	wchar_t captionWindow[_MAX_PATH];
	wcscpy_s(captionWindow, _MAX_PATH, L"Sound-Similar 1.1  (Free Version)                                                                                                                                                      by Virtins Technology");

	UINT timerUpdate = 0;

	if (argc != 5) {
		printf("Error: Invalid parameters\n");
		return 1;
	}

	wcscpy_s(compareStruct.pathWav1, _MAX_PATH, argv[1]);
	wcscpy_s(compareStruct.pathWav2, _MAX_PATH, argv[2]);
	wcscpy_s(compareStruct.f1, _MAX_PATH, argv[3]);
	wcscpy_s(compareStruct.f2, _MAX_PATH, argv[4]);

	HWND hwnd = FindWindowW(NULL, captionWindow);

	if (hwnd == NULL) {
		WinExec("Sound-Similar-Free.exe", SW_SHOWNORMAL);

		for (int i = 0; i < 500; ++i) {

			hwnd = FindWindowW(NULL, captionWindow);

			if (IsWindowVisible(hwnd) == TRUE) {
				ShowWindow(hwnd, SW_HIDE);
				break;
			}

			Sleep(1);
		}

	}

	if (hwnd != NULL) {

		//DWORD hprocessId = 0;
		//GetWindowThreadProcessId(hwnd, &hprocessId);

		//HANDLE processHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, hprocessId);

		//GetModuleFileNameExW(processHandle, NULL, compareStruct.captionWindow, _MAX_PATH);

		GetFullPathNameW(L"Sound-Similar-Free.exe", _MAX_PATH, compareStruct.captionWindow, NULL);

		timerUpdate = timeSetEvent(10, 0, (LPTIMECALLBACK)TimerUpdate, (DWORD_PTR)&compareStruct, TIME_PERIODIC);

		GetWindowRect(hwnd, &compareStruct.winRect);
		compareStruct.regim = REGIM_INIT;
		compareStruct.number = 0;
		EnumChildWindows(hwnd, enum_wnd_proc, (LPARAM)(&compareStruct));

		if (compareStruct.error)
			return 3;

		compareStruct.regim = REGIM_COMPARE;
		compareStruct.number = 0;
		EnumChildWindows(hwnd, enum_wnd_proc, (LPARAM)(&compareStruct));
		
		compareStruct.regim = REGIM_RESULT;
		compareStruct.number = 0;
		EnumChildWindows(hwnd, enum_wnd_proc, (LPARAM)(&compareStruct));

		if (compareStruct.isFindResult) {
			printf("Similarity Score:%ls\n", compareStruct.textResult);
		}
		else {
			GetWindowRect(hwnd, &compareStruct.winRect);
			compareStruct.regim = REGIM_INIT;
			compareStruct.number = 0;
			EnumChildWindows(hwnd, enum_wnd_proc, (LPARAM)(&compareStruct));

			if (compareStruct.error)
				return 3;

			compareStruct.regim = REGIM_COMPARE;
			compareStruct.number = 0;
			EnumChildWindows(hwnd, enum_wnd_proc, (LPARAM)(&compareStruct));

			compareStruct.regim = REGIM_RESULT;
			compareStruct.number = 0;
			EnumChildWindows(hwnd, enum_wnd_proc, (LPARAM)(&compareStruct));

			printf("Similarity Score:%ls\n", compareStruct.textResult);

		}


		timeKillEvent(timerUpdate);

		//PostMessage(hwnd, WM_CLOSE, 0, 0);
	}
	else {
		printf("Error: Window not found\n");
		return 2;
	}

}

// Запуск программы: CTRL+F5 или меню "Отладка" > "Запуск без отладки"
// Отладка программы: F5 или меню "Отладка" > "Запустить отладку"

// Советы по началу работы 
//   1. В окне обозревателя решений можно добавлять файлы и управлять ими.
//   2. В окне Team Explorer можно подключиться к системе управления версиями.
//   3. В окне "Выходные данные" можно просматривать выходные данные сборки и другие сообщения.
//   4. В окне "Список ошибок" можно просматривать ошибки.
//   5. Последовательно выберите пункты меню "Проект" > "Добавить новый элемент", чтобы создать файлы кода, или "Проект" > "Добавить существующий элемент", чтобы добавить в проект существующие файлы кода.
//   6. Чтобы снова открыть этот проект позже, выберите пункты меню "Файл" > "Открыть" > "Проект" и выберите SLN-файл.
