#include "stdafx.h"

struct SmpData
{
	HWND dialog;
	TrustLevel oldlevel;
	ConnContext *context;
	bool responder;
	TCHAR *question;
};
typedef std::map<HANDLE, SmpData> SmpForContactMap;
SmpForContactMap smp_for_contact;


static INT_PTR CALLBACK DlgSMPUpdateProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg) {
	case WM_DESTROY: {
			ConnContext *context = (ConnContext*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
			if (context)
				otr_abort_smp(context);
			break; }
	case WM_INITDIALOG:
		{
			if (!lParam) {
				DestroyWindow(hwndDlg);
				return FALSE;
			}
			TranslateDialogDefault(hwndDlg);

			SmpData *data = (SmpData*)lParam;
			ConnContext *context = data->context;
			MCONTACT hContact = (UINT_PTR)context->app_data;
			data->dialog = hwndDlg;
			//smp_for_contact.insert(SmpForContactMap::value_type(context->app_data, *data));
			if (smp_for_contact[context->app_data].dialog) SendMessage(smp_for_contact[context->app_data].dialog, WMU_REFRESHSMP, 0, 0);
			smp_for_contact[context->app_data].context = data->context;
			smp_for_contact[context->app_data].dialog = hwndDlg;
			smp_for_contact[context->app_data].oldlevel = data->oldlevel;
			smp_for_contact[context->app_data].responder = data->responder;
			mir_free(data);

			TCHAR title[512], *proto = mir_a2t(GetContactProto(hContact));
			const TCHAR *name = contact_get_nameT(hContact);
			mir_sntprintf(title, TranslateT(LANG_SMP_PROGRESS_TITLE), name, proto);
			SetWindowText(hwndDlg, title);
			mir_sntprintf(title, TranslateT(LANG_SMP_PROGRESS_DESC), name, proto);
			mir_free(proto);
			SetDlgItemText(hwndDlg, IDC_STC_SMP_HEADPRO, title);
			SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)context);

			// Move window to screen center
			// Get the owner window and dialog box rectangles. 
			HWND hwndOwner; RECT rcOwner, rcDlg, rc;
			if ((hwndOwner = GetParent(hwndDlg)) == NULL) {
				hwndOwner = GetDesktopWindow();
			}

			GetWindowRect(hwndOwner, &rcOwner);
			GetWindowRect(hwndDlg, &rcDlg);
			CopyRect(&rc, &rcOwner);

			// Offset the owner and dialog box rectangles so that right and bottom 
			// values represent the width and height, and then offset the owner again 
			// to discard space taken up by the dialog box. 

			OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
			OffsetRect(&rc, -rc.left, -rc.top);
			OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);

			// The new position is the sum of half the remaining space and the owner's 
			// original position. 

			SetWindowPos(hwndDlg,
				HWND_TOP,
				rcOwner.left + (rc.right / 2),
				rcOwner.top + (rc.bottom / 2),
				0, 0,          // Ignores size arguments. 
				SWP_NOSIZE);

			// end center dialog

			SendDlgItemMessage(hwndDlg, IDC_PGB_SMP, PBM_SETRANGE, 0, MAKELONG(0, 100));
			SendDlgItemMessage(hwndDlg, IDC_PGB_SMP, PBM_SETPOS, 10, 0);

			EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), true);
			EnableWindow(GetDlgItem(hwndDlg, IDOK), false);

			return TRUE;
		}

	case WMU_REFRESHSMP:
		{
			ConnContext *context = (ConnContext*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
			SendDlgItemMessage(hwndDlg, IDC_PGB_SMP, PBM_SETPOS, wParam, 0);
			switch (wParam) {
			case 0:
				EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), false);
				EnableWindow(GetDlgItem(hwndDlg, IDOK), true);
				SetDlgItemText(hwndDlg, IDC_STC_SMP_PROGRESS, TranslateT(LANG_SMP_ERROR));
				smp_for_contact.erase(context->app_data);
				break;
			case 100:
				{
					EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), false);
					EnableWindow(GetDlgItem(hwndDlg, IDOK), true);
					smp_for_contact.erase(context->app_data);
					if (context->smstate->sm_prog_state == OTRL_SMP_PROG_SUCCEEDED) {
						if (context->active_fingerprint->trust && context->active_fingerprint->trust[0]) {
							SetDlgItemText(hwndDlg, IDC_STC_SMP_PROGRESS, TranslateT(LANG_SMP_SUCCESS));
						}
						else {
							SetDlgItemText(hwndDlg, IDC_STC_SMP_PROGRESS, TranslateT(LANG_SMP_SUCCESS_VERIFY));
						}
					}
					else {
						SetDlgItemText(hwndDlg, IDC_STC_SMP_PROGRESS, TranslateT(LANG_SMP_FAILED));
					}
				}
				break;
			default:
				SetDlgItemText(hwndDlg, IDC_STC_SMP_PROGRESS, _T(""));
			}
		}
		break;

	case WM_COMMAND:
		switch (HIWORD(wParam)) {
		case BN_CLICKED:
			{
				ConnContext *context = (ConnContext*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
				switch (LOWORD(wParam)) {
				case IDOK:
					smp_for_contact.erase(context->app_data);
					SetWindowLongPtr(hwndDlg, GWLP_USERDATA, NULL);
				case IDCANCEL:
					DestroyWindow(hwndDlg);
					break;
				}
			}break;
		}

	}

	return FALSE;
}

static void SMPInitUpdateDialog(ConnContext *context, bool responder)
{
	if (!context) return;
	SmpData *data = (SmpData*)mir_calloc(sizeof(SmpData));
	data->context = context;
	data->oldlevel = otr_context_get_trust(context);
	data->responder = responder;
	CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_SMP_PROGRESS), 0, DlgSMPUpdateProc, (LPARAM)data);
}

static INT_PTR CALLBACK DlgSMPResponseProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg) {
	case WM_DESTROY: {
			ConnContext *context = (ConnContext*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
			if (context)
				otr_abort_smp(context);
			break; }
	case WM_INITDIALOG:
		{
			if (!lParam) {
				DestroyWindow(hwndDlg);
				return FALSE;
			}
			TranslateDialogDefault(hwndDlg);

			SmpData *data = (SmpData*)lParam;
			ConnContext *context = data->context;
			MCONTACT hContact = (UINT_PTR)context->app_data;
			data->dialog = hwndDlg;
			//smp_for_contact.insert(SmpForContactMap::value_type(context->app_data, *data));
			if (smp_for_contact[context->app_data].dialog) SendMessage(smp_for_contact[context->app_data].dialog, WMU_REFRESHSMP, 0, 0);
			smp_for_contact[context->app_data].context = data->context;
			smp_for_contact[context->app_data].dialog = hwndDlg;
			smp_for_contact[context->app_data].oldlevel = data->oldlevel;
			smp_for_contact[context->app_data].responder = data->responder;

			TCHAR buff[512], *proto = mir_a2t(GetContactProto(hContact));
			mir_sntprintf(buff, TranslateT(LANG_SMP_VERIFY_TITLE), contact_get_nameT(hContact), proto);
			mir_free(proto);
			SetWindowText(hwndDlg, buff);
			SetDlgItemText(hwndDlg, IDC_STC_SMP_HEAD, buff);
			SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)context);

			if (data->question) {
				mir_sntprintf(buff, TranslateT(LANG_OTR_SMPQUESTION_RESPOND_DESC), contact_get_nameT(hContact));

				SetDlgItemText(hwndDlg, IDC_STC_SMP_INFO, buff);

				SetDlgItemText(hwndDlg, IDC_EDT_SMP_FIELD1, data->question);
				SendDlgItemMessage(hwndDlg, IDC_EDT_SMP_FIELD1, EM_SETREADONLY, TRUE, 0);
				SetDlgItemText(hwndDlg, IDC_STC_SMP_FIELD1, TranslateT(LANG_SMP_QUESTION));

				SetDlgItemText(hwndDlg, IDC_EDT_SMP_FIELD2, _T(""));
				SendDlgItemMessage(hwndDlg, IDC_EDT_SMP_FIELD2, EM_SETREADONLY, FALSE, 0);
				SetDlgItemText(hwndDlg, IDC_STC_SMP_FIELD2, TranslateT(LANG_SMP_ANSWER));


				ShowWindow(GetDlgItem(hwndDlg, IDOK), SW_SHOWNA);
				ShowWindow(GetDlgItem(hwndDlg, IDYES), SW_HIDE);
				ShowWindow(GetDlgItem(hwndDlg, IDNO), SW_HIDE);

				mir_free(data->question);
			}
			else {
				mir_sntprintf(buff, TranslateT(LANG_OTR_SMPPASSWORD_RESPOND_DESC), contact_get_nameT(hContact));

				SetDlgItemText(hwndDlg, IDC_STC_SMP_INFO, buff);

				SetDlgItemText(hwndDlg, IDC_EDT_SMP_FIELD1, _T(""));
				SendDlgItemMessage(hwndDlg, IDC_EDT_SMP_FIELD1, EM_SETREADONLY, TRUE, 0);
				SetDlgItemText(hwndDlg, IDC_STC_SMP_FIELD1, _T(""));

				SetDlgItemText(hwndDlg, IDC_EDT_SMP_FIELD2, _T(""));
				SendDlgItemMessage(hwndDlg, IDC_EDT_SMP_FIELD2, EM_SETREADONLY, FALSE, 0);
				SetDlgItemText(hwndDlg, IDC_STC_SMP_FIELD2, TranslateT(LANG_SMP_PASSWORD));


				ShowWindow(GetDlgItem(hwndDlg, IDOK), SW_SHOWNA);
				ShowWindow(GetDlgItem(hwndDlg, IDYES), SW_HIDE);
				ShowWindow(GetDlgItem(hwndDlg, IDNO), SW_HIDE);
			}
			mir_free(data);

			// Move window to screen center
			// Get the owner window and dialog box rectangles. 
			HWND hwndOwner = GetParent(hwndDlg); 
			if (hwndOwner == NULL)
				hwndOwner = GetDesktopWindow();

			RECT rcOwner, rcDlg, rc;
			GetWindowRect(hwndOwner, &rcOwner);
			GetWindowRect(hwndDlg, &rcDlg);
			CopyRect(&rc, &rcOwner);

			// Offset the owner and dialog box rectangles so that right and bottom 
			// values represent the width and height, and then offset the owner again 
			// to discard space taken up by the dialog box. 

			OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
			OffsetRect(&rc, -rc.left, -rc.top);
			OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);

			// The new position is the sum of half the remaining space and the owner's 
			// original position. 

			SetWindowPos(hwndDlg,
				HWND_TOP,
				rcOwner.left + (rc.right / 2),
				rcOwner.top + (rc.bottom / 2),
				0, 0,          // Ignores size arguments. 
				SWP_NOSIZE);

			// end center dialog
			return TRUE;
		}

	case WM_COMMAND:
		switch (HIWORD(wParam)) {
		case BN_CLICKED:
			ConnContext *context = (ConnContext *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
			switch (LOWORD(wParam)) {
			case IDOK:
				SMPInitUpdateDialog(context, true);
				{
					int len = SendDlgItemMessage(hwndDlg, IDC_EDT_SMP_FIELD2, WM_GETTEXTLENGTH, 0, 0);
					TCHAR *answer = new TCHAR[len + 1];
					GetDlgItemText(hwndDlg, IDC_EDT_SMP_FIELD2, answer, len + 1);

					T2Utf ans(answer);
					otr_continue_smp(context, (const unsigned char *)ans, mir_strlen(ans));
					delete[] answer;

					SetWindowLongPtr(hwndDlg, GWLP_USERDATA, NULL);
					DestroyWindow(hwndDlg);
				}
				break;

			case IDCANCEL:
				smp_for_contact.erase(context->app_data);
				DestroyWindow(hwndDlg);
				break;
			}
		}
		break;
	}

	return FALSE;
}

/*
void SMPInitResponseDialog(ConnContext *context, const TCHAR *question) {
	if (!context) return;
	SmpData *data = (SmpData*)mir_calloc(sizeof(SmpData));
	data->context = context;
	data->oldlevel = TRUST_NOT_PRIVATE;
	data->responder = true;
	data->question = (question) ? mir_tstrdup(question) : NULL;
	CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_SMP_INPUT), 0, DlgSMPResponseProc, (LPARAM) data);
}
*/

static INT_PTR CALLBACK DlgProcSMPInitProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg) {
	case WM_INITDIALOG:
		{
			if (!lParam) {
				DestroyWindow(hwndDlg);
				return FALSE;
			}
			TranslateDialogDefault(hwndDlg);

			ConnContext *context = (ConnContext*)lParam;
			if (smp_for_contact.find(context->app_data) != smp_for_contact.end()) {
				DestroyWindow(hwndDlg);
				return FALSE;
			}

			MCONTACT hContact = (UINT_PTR)context->app_data;
			TCHAR title[512], *proto = mir_a2t(GetContactProto(hContact));
			mir_sntprintf(title, TranslateT(LANG_SMP_VERIFY_TITLE), contact_get_nameT(hContact), proto);
			mir_free(proto);
			SetWindowText(hwndDlg, title);
			SetDlgItemText(hwndDlg, IDC_STC_SMP_HEAD, title);
			SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam);

			// Move window to screen center
			// Get the owner window and dialog box rectangles. 
			HWND hwndOwner = GetParent(hwndDlg); 
			if (hwndOwner == NULL)
				hwndOwner = GetDesktopWindow();

			RECT rcOwner, rcDlg, rc;
			GetWindowRect(hwndOwner, &rcOwner);
			GetWindowRect(hwndDlg, &rcDlg);
			CopyRect(&rc, &rcOwner);

			// Offset the owner and dialog box rectangles so that right and bottom 
			// values represent the width and height, and then offset the owner again 
			// to discard space taken up by the dialog box. 

			OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
			OffsetRect(&rc, -rc.left, -rc.top);
			OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);

			// The new position is the sum of half the remaining space and the owner's 
			// original position. 

			SetWindowPos(hwndDlg,
				HWND_TOP,
				rcOwner.left + (rc.right / 2),
				rcOwner.top + (rc.bottom / 2),
				0, 0,          // Ignores size arguments. 
				SWP_NOSIZE);

			// end center dialog


			HWND cmb = GetDlgItem(hwndDlg, IDC_CBO_SMP_CHOOSE);
			SendMessage(cmb, CB_ADDSTRING, 0, (WPARAM)TranslateT(LANG_SMPTYPE_QUESTION));
			SendMessage(cmb, CB_ADDSTRING, 0, (WPARAM)TranslateT(LANG_SMPTYPE_PASSWORD));
			SendMessage(cmb, CB_ADDSTRING, 0, (WPARAM)TranslateT(LANG_SMPTYPE_FINGERPRINT));
			SendMessage(cmb, CB_SELECTSTRING, -1, (WPARAM)TranslateT(LANG_SMPTYPE_QUESTION));
			EnableWindow(GetDlgItem(hwndDlg, IDC_CBO_SMP_CHOOSE), TRUE);


			Fingerprint *fp = context->active_fingerprint;
			if (!fp) {
				DestroyWindow(hwndDlg);
				return FALSE;
			}
			TCHAR buff[1024];
			if (!fp->trust || fp->trust[0] == '\0')
				mir_sntprintf(buff, TranslateT(LANG_OTR_SMPQUESTION_VERIFY_DESC), contact_get_nameT(hContact));
			else
				mir_sntprintf(buff, TranslateT(LANG_OTR_SMPQUESTION_VERIFIED_DESC), contact_get_nameT(hContact));

			SetDlgItemText(hwndDlg, IDC_STC_SMP_INFO, buff);

			SetDlgItemText(hwndDlg, IDC_EDT_SMP_FIELD1, _T(""));
			SendDlgItemMessage(hwndDlg, IDC_EDT_SMP_FIELD1, EM_SETREADONLY, FALSE, 0);
			SetDlgItemText(hwndDlg, IDC_STC_SMP_FIELD1, TranslateT(LANG_SMP_QUESTION));

			SetDlgItemText(hwndDlg, IDC_EDT_SMP_FIELD2, _T(""));
			SendDlgItemMessage(hwndDlg, IDC_EDT_SMP_FIELD2, EM_SETREADONLY, FALSE, 0);
			SetDlgItemText(hwndDlg, IDC_STC_SMP_FIELD2, TranslateT(LANG_SMP_ANSWER));


			ShowWindow(GetDlgItem(hwndDlg, IDOK), SW_SHOWNA);
			ShowWindow(GetDlgItem(hwndDlg, IDYES), SW_HIDE);
			ShowWindow(GetDlgItem(hwndDlg, IDNO), SW_HIDE);
			SetFocus(GetDlgItem(hwndDlg, IDC_CBO_SMP_CHOOSE));

			return FALSE;
		}

	case WM_COMMAND:
		switch (HIWORD(wParam)) {
		case BN_CLICKED:
			{
				ConnContext *context = (ConnContext*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
				MCONTACT hContact = (UINT_PTR)context->app_data;
				TCHAR msg[1024];
				switch (LOWORD(wParam)) {
				case IDCANCEL:
					DestroyWindow(hwndDlg);
					break;
				case IDOK:
					GetDlgItemText(hwndDlg, IDC_CBO_SMP_CHOOSE, msg, 255);
					if (_tcsncmp(msg, TranslateT(LANG_SMPTYPE_QUESTION), 255) == 0) {
						if (smp_for_contact.find(context->app_data) != smp_for_contact.end()) {
							TCHAR msg[512];
							mir_sntprintf(msg, TranslateT(LANG_SMP_IN_PROGRESS), contact_get_nameT(hContact));
							ShowError(msg);
						}
						else {
							int len = SendDlgItemMessage(hwndDlg, IDC_EDT_SMP_FIELD1, WM_GETTEXTLENGTH, 0, 0);
							TCHAR *question = new TCHAR[len + 1];
							GetDlgItemText(hwndDlg, IDC_EDT_SMP_FIELD1, question, len + 1);
							T2Utf quest(question);
							delete question;

							len = SendDlgItemMessage(hwndDlg, IDC_EDT_SMP_FIELD2, WM_GETTEXTLENGTH, 0, 0);
							TCHAR *answer = new TCHAR[len + 1];
							GetDlgItemText(hwndDlg, IDC_EDT_SMP_FIELD2, answer, len + 1);
							T2Utf ans(answer);
							delete[] answer;

							SMPInitUpdateDialog(context, false);
							otr_start_smp(context, quest, (const unsigned char*)ans, mir_strlen(ans));
						}

					}
					else if (_tcsncmp(msg, TranslateT(LANG_SMPTYPE_PASSWORD), 255) == 0) {
						if (smp_for_contact.find(context->app_data) != smp_for_contact.end()) {
							TCHAR msg[512];
							mir_sntprintf(msg, TranslateT(LANG_SMP_IN_PROGRESS), contact_get_nameT(hContact));
							ShowError(msg);
						}
						else {
							int len = SendDlgItemMessage(hwndDlg, IDC_EDT_SMP_FIELD2, WM_GETTEXTLENGTH, 0, 0);
							TCHAR *answer = new TCHAR[len + 1];
							GetDlgItemText(hwndDlg, IDC_EDT_SMP_FIELD2, answer, len + 1);
							T2Utf ans(answer);
							delete[] answer;

							SMPInitUpdateDialog(context, false);
							otr_start_smp(context, NULL, (const unsigned char*)ans, mir_strlen(ans));
						}

					}
					else break;
					DestroyWindow(hwndDlg);
					break;
				case IDYES:
					VerifyFingerprint(context, true);
					DestroyWindow(hwndDlg);
					break;
				case IDNO:
					VerifyFingerprint(context, false);
					DestroyWindow(hwndDlg);
					break;
				}
			}
			break;
		
		case CBN_SELCHANGE:
			switch (LOWORD(wParam)) {
			case IDC_CBO_SMP_CHOOSE:
				{
					ConnContext *context = (ConnContext*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
					MCONTACT hContact = (UINT_PTR)context->app_data;
					Fingerprint *fp = context->active_fingerprint;
					if (!fp) {
						DestroyWindow(hwndDlg);
						return TRUE;
					}
					BOOL trusted = false;
					if (fp->trust && fp->trust[0] != '\0') trusted = true;

					TCHAR buff[512];
					GetDlgItemText(hwndDlg, IDC_CBO_SMP_CHOOSE, buff, 255);
					if (_tcsncmp(buff, TranslateT(LANG_SMPTYPE_QUESTION), 255) == 0) {
						if (trusted)
							mir_sntprintf(buff, TranslateT(LANG_OTR_SMPQUESTION_VERIFIED_DESC), contact_get_nameT(hContact));
						else
							mir_sntprintf(buff, TranslateT(LANG_OTR_SMPQUESTION_VERIFY_DESC), contact_get_nameT(hContact));

						SetDlgItemText(hwndDlg, IDC_STC_SMP_INFO, buff);

						SetDlgItemText(hwndDlg, IDC_EDT_SMP_FIELD1, _T(""));
						SendDlgItemMessage(hwndDlg, IDC_EDT_SMP_FIELD1, EM_SETREADONLY, FALSE, 0);
						SetDlgItemText(hwndDlg, IDC_STC_SMP_FIELD1, TranslateT(LANG_SMP_QUESTION));

						SetDlgItemText(hwndDlg, IDC_EDT_SMP_FIELD2, _T(""));
						SendDlgItemMessage(hwndDlg, IDC_EDT_SMP_FIELD2, EM_SETREADONLY, FALSE, 0);
						SetDlgItemText(hwndDlg, IDC_STC_SMP_FIELD2, TranslateT(LANG_SMP_ANSWER));


						ShowWindow(GetDlgItem(hwndDlg, IDOK), SW_SHOWNA);
						ShowWindow(GetDlgItem(hwndDlg, IDYES), SW_HIDE);
						ShowWindow(GetDlgItem(hwndDlg, IDNO), SW_HIDE);
					}
					else if (_tcsncmp(buff, TranslateT(LANG_SMPTYPE_PASSWORD), 255) == 0) {
						if (trusted)
							mir_sntprintf(buff, TranslateT(LANG_OTR_SMPPASSWORD_VERIFIED_DESC), contact_get_nameT(hContact));
						else
							mir_sntprintf(buff, TranslateT(LANG_OTR_SMPPASSWORD_VERIFY_DESC), contact_get_nameT(hContact));

						SetDlgItemText(hwndDlg, IDC_STC_SMP_INFO, buff);

						SetDlgItemText(hwndDlg, IDC_EDT_SMP_FIELD1, _T(""));
						SendDlgItemMessage(hwndDlg, IDC_EDT_SMP_FIELD1, EM_SETREADONLY, TRUE, 0);
						SetDlgItemText(hwndDlg, IDC_STC_SMP_FIELD1, _T(""));

						SetDlgItemText(hwndDlg, IDC_EDT_SMP_FIELD2, _T(""));
						SendDlgItemMessage(hwndDlg, IDC_EDT_SMP_FIELD2, EM_SETREADONLY, FALSE, 0);
						SetDlgItemText(hwndDlg, IDC_STC_SMP_FIELD2, TranslateT(LANG_SMP_PASSWORD));


						ShowWindow(GetDlgItem(hwndDlg, IDOK), SW_SHOWNA);
						ShowWindow(GetDlgItem(hwndDlg, IDYES), SW_HIDE);
						ShowWindow(GetDlgItem(hwndDlg, IDNO), SW_HIDE);
					}
					else if (_tcsncmp(buff, TranslateT(LANG_SMPTYPE_FINGERPRINT), 255) == 0) {
						if (trusted)
							mir_sntprintf(buff, TranslateT(LANG_OTR_FPVERIFIED_DESC), contact_get_nameT(hContact));
						else
							mir_sntprintf(buff, TranslateT(LANG_OTR_FPVERIFY_DESC), contact_get_nameT(hContact));

						SetDlgItemText(hwndDlg, IDC_STC_SMP_INFO, buff);

						unsigned char hash[20];
						lib_cs_lock();
						if (!otrl_privkey_fingerprint_raw(otr_user_state, hash, context->accountname, context->protocol)) {
							DestroyWindow(hwndDlg);
							return FALSE;
						}
						otrl_privkey_hash_to_humanT(buff, hash);
						SetDlgItemText(hwndDlg, IDC_EDT_SMP_FIELD1, buff);
						SendDlgItemMessage(hwndDlg, IDC_EDT_SMP_FIELD1, EM_SETREADONLY, TRUE, 0);
						SetDlgItemText(hwndDlg, IDC_STC_SMP_FIELD1, TranslateT(LANG_YOUR_PRIVKEY));

						otrl_privkey_hash_to_humanT(buff, fp->fingerprint);
						SetDlgItemText(hwndDlg, IDC_EDT_SMP_FIELD2, buff);
						SendDlgItemMessage(hwndDlg, IDC_EDT_SMP_FIELD2, EM_SETREADONLY, TRUE, 0);
						SetDlgItemText(hwndDlg, IDC_STC_SMP_FIELD2, TranslateT(LANG_CONTACT_FINGERPRINT));

						ShowWindow(GetDlgItem(hwndDlg, IDOK), SW_HIDE);
						ShowWindow(GetDlgItem(hwndDlg, IDYES), SW_SHOWNA);
						ShowWindow(GetDlgItem(hwndDlg, IDNO), SW_SHOWNA);

					}
				}break;
			}
		}
		break;

	}

	return FALSE;
}
void SMPInitDialog(ConnContext *context)
{
	if (context)
		CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_SMP_INPUT), 0, DlgProcSMPInitProc, (LPARAM)context);
}

void SMPDialogUpdate(ConnContext *context, int percent)
{
	if (!context) return;
	SmpForContactMap::iterator it = smp_for_contact.find(context->app_data);
	if (it == smp_for_contact.end())	return;
	if (it->second.dialog) PostMessage(it->second.dialog, WMU_REFRESHSMP, percent, 0);
	TrustLevel level = otr_context_get_trust(context);
	if (!it->second.responder && it->second.oldlevel != level) {
		if (level == TRUST_PRIVATE)
			VerifyFingerprintMessage(context, true);
		else if (level == TRUST_UNVERIFIED)
			VerifyFingerprintMessage(context, false);
	}
	//if (percent == 100)
	/*
	switch (percent){
		case 0:
			VerifyFingerprint(context, false);
			ShowWarning(_T("SMP failed"));
			break;
		case 100:
			VerifyFingerprint(context, true);
			ShowWarning(_T("SMP successful"));
			break;
		default:
			ShowWarning(_T("Received an SMP update"));
	}
	*/
}
void SMPDialogReply(ConnContext *context, const char* question)
{
	SmpData *data = (SmpData*)mir_calloc(sizeof(SmpData));
	data->context = context;
	data->oldlevel = TRUST_NOT_PRIVATE;
	data->responder = true;
	data->question = (question) ? mir_utf8decodeT(question) : NULL;
	CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_SMP_INPUT), 0, DlgSMPResponseProc, (LPARAM)data);
	/*
	ShowError(_T("SMP requires user password (NOT IMPL YET)"));
	otr_abort_smp(context);
	*/
	//otr_continue_smp(context, pass, mir_strlen(pass));
}

static INT_PTR CALLBACK DlgBoxProcVerifyContext(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg) {
	case WM_INITDIALOG:
	{
		if (!lParam) {
			EndDialog(hwndDlg, IDCANCEL);
			return FALSE;
		}
		SetWindowText(hwndDlg, _T(LANG_OTR_FPVERIFY_TITLE));
		SetDlgItemText(hwndDlg, IDC_STC_SMP_HEAD, _T(LANG_OTR_FPVERIFY_TITLE));
		TranslateDialogDefault(hwndDlg);
		SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam);

		// Move window to screen center
		// Get the owner window and dialog box rectangles. 
		HWND hwndOwner = GetParent(hwndDlg);
		if (hwndOwner == NULL)
			hwndOwner = GetDesktopWindow();

		RECT rcOwner, rcDlg, rc;
		GetWindowRect(hwndOwner, &rcOwner);
		GetWindowRect(hwndDlg, &rcDlg);
		CopyRect(&rc, &rcOwner);

		// Offset the owner and dialog box rectangles so that right and bottom 
		// values represent the width and height, and then offset the owner again 
		// to discard space taken up by the dialog box. 

		OffsetRect(&rcDlg, -rcDlg.left, -rcDlg.top);
		OffsetRect(&rc, -rc.left, -rc.top);
		OffsetRect(&rc, -rcDlg.right, -rcDlg.bottom);

		// The new position is the sum of half the remaining space and the owner's 
		// original position. 

		SetWindowPos(hwndDlg,
			HWND_TOP,
			rcOwner.left + (rc.right / 2),
			rcOwner.top + (rc.bottom / 2),
			0, 0,          // Ignores size arguments. 
			SWP_NOSIZE);

		// end center dialog

		ConnContext *context = (ConnContext*)lParam;
		MCONTACT hContact = (UINT_PTR)context->app_data;
		Fingerprint *fp = context->active_fingerprint;
		if (!fp) {
			EndDialog(hwndDlg, IDCANCEL);
			return FALSE;
		}
		TCHAR buff[512];
		if (!fp->trust || fp->trust[0] == '\0')
			mir_sntprintf(buff, TranslateT(LANG_OTR_FPVERIFY_DESC), contact_get_nameT(hContact));
		else
			mir_sntprintf(buff, TranslateT(LANG_OTR_FPVERIFIED_DESC), contact_get_nameT(hContact));

		SetDlgItemText(hwndDlg, IDC_STC_SMP_INFO, buff);

		unsigned char hash[20];
		lib_cs_lock();
		if (!otrl_privkey_fingerprint_raw(otr_user_state, hash, context->accountname, context->protocol)) {
			EndDialog(hwndDlg, IDCANCEL);
			return FALSE;
		}
		otrl_privkey_hash_to_humanT(buff, hash);
		SetDlgItemText(hwndDlg, IDC_EDT_SMP_FIELD1, buff);
		SendDlgItemMessage(hwndDlg, IDC_EDT_SMP_FIELD1, EM_SETREADONLY, TRUE, 0);
		SetDlgItemText(hwndDlg, IDC_STC_SMP_FIELD1, TranslateT(LANG_YOUR_PRIVKEY));

		otrl_privkey_hash_to_humanT(buff, fp->fingerprint);
		SetDlgItemText(hwndDlg, IDC_EDT_SMP_FIELD2, buff);
		SendDlgItemMessage(hwndDlg, IDC_EDT_SMP_FIELD2, EM_SETREADONLY, TRUE, 0);
		SetDlgItemText(hwndDlg, IDC_STC_SMP_FIELD2, TranslateT(LANG_CONTACT_FINGERPRINT));

		EnableWindow(GetDlgItem(hwndDlg, IDC_CBO_SMP_CHOOSE), FALSE);

		ShowWindow(GetDlgItem(hwndDlg, IDOK), SW_HIDE);
		ShowWindow(GetDlgItem(hwndDlg, IDYES), SW_SHOWNA);
		ShowWindow(GetDlgItem(hwndDlg, IDNO), SW_SHOWNA);
		SetFocus(GetDlgItem(hwndDlg, IDCANCEL));
	}
	return FALSE;

	case WM_COMMAND:
		switch (HIWORD(wParam)) {
		case BN_CLICKED:
			switch (LOWORD(wParam)) {
			case IDYES:
			case IDNO:
			case IDCANCEL:
			case IDOK:
				EndDialog(hwndDlg, LOWORD(wParam));
				break;
			}
		}
		break;

	}

	return FALSE;
}

static unsigned int CALLBACK verify_context_thread(void *param)
{
	Thread_Push(0);

	if (param) {
		ConnContext *context = (ConnContext *)param;
		MCONTACT hContact = (UINT_PTR)context->app_data;
		TCHAR msg[1024];
		switch (DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_SMP_INPUT), 0, DlgBoxProcVerifyContext, (LPARAM)param)) {
		case IDOK:
		case IDYES:
			lib_cs_lock();
			otrl_context_set_trust(context->active_fingerprint, "verified");
			otrl_privkey_write_fingerprints(otr_user_state, _T2A(g_fingerprint_store_filename));
			mir_sntprintf(msg, TranslateT(LANG_FINGERPRINT_VERIFIED), contact_get_nameT(hContact));
			ShowMessage(hContact, msg);
			SetEncryptionStatus(hContact, otr_context_get_trust(context));
			break;

		case IDNO:
			lib_cs_lock();
			otrl_context_set_trust(context->active_fingerprint, NULL);
			otrl_privkey_write_fingerprints(otr_user_state, _T2A(g_fingerprint_store_filename));
			mir_sntprintf(msg, TranslateT(LANG_FINGERPRINT_NOT_VERIFIED), contact_get_nameT(hContact));
			ShowMessage(hContact, msg);
			SetEncryptionStatus(hContact, otr_context_get_trust(context));
			break;
		}
	}

	Thread_Pop();
	return 0;
}

void VerifyContextDialog(ConnContext* context)
{
	if (!context) return;
	CloseHandle((HANDLE)_beginthreadex(0, 0, verify_context_thread, context, 0, 0));
}