// ---------------------------------------------------------------------------80
//                ICQ plugin for Miranda Instant Messenger
//                ________________________________________
//
// Copyright © 2000-2001 Richard Hughes, Roland Rabien, Tristan Van de Vreede
// Copyright © 2001-2002 Jon Keating, Richard Hughes
// Copyright © 2002-2004 Martin Öberg, Sam Kothari, Robert Rainwater
// Copyright © 2004-2010 Joe Kucera
// Copyright © 2012-2018 Miranda NG team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
// -----------------------------------------------------------------------------
//  DESCRIPTION:
//
//  Code for User details ICQ specific pages
// -----------------------------------------------------------------------------

#include "stdafx.h"

#define SVS_NORMAL        0
#define SVS_ZEROISUNSPEC  2
#define SVS_IP            3
#define SVS_SIGNED        6
#define SVS_ICQVERSION    8
#define SVS_TIMESTAMP     9
#define SVS_STATUSID      10

extern const char *nameXStatus[];

/////////////////////////////////////////////////////////////////////////////////////////

static void SetValue(CIcqProto* ppro, HWND hwndDlg, int idCtrl, MCONTACT hContact, char* szModule, char* szSetting, int special)
{
	DBVARIANT dbv = { 0 };
	char str[MAX_PATH];
	char* pstr = nullptr;
	int unspecified = 0;
	int bUtf = 0, bDbv = 0, bAlloc = 0;

	dbv.type = DBVT_DELETED;

	if ((hContact == NULL) && ((INT_PTR)szModule < 0x100)) {
		dbv.type = (INT_PTR)szModule;

		switch ((INT_PTR)szModule) {
		case DBVT_BYTE:
			dbv.cVal = (INT_PTR)szSetting;
			break;
		case DBVT_WORD:
			dbv.wVal = (INT_PTR)szSetting;
			break;
		case DBVT_DWORD:
			dbv.dVal = (UINT_PTR)szSetting;
			break;
		case DBVT_ASCIIZ:
			dbv.pszVal = pstr = szSetting;
			break;
		default:
			unspecified = 1;
			dbv.type = DBVT_DELETED;
		}
	}
	else {
		if (szModule == nullptr)
			unspecified = 1;
		else {
			unspecified = db_get(hContact, szModule, szSetting, &dbv);
			bDbv = 1;
		}
	}

	if (!unspecified) {
		switch (dbv.type) {
		case DBVT_BYTE:
			unspecified = (special == SVS_ZEROISUNSPEC && dbv.bVal == 0);
			pstr = _itoa(special == SVS_SIGNED ? dbv.cVal : dbv.bVal, str, 10);
			break;

		case DBVT_WORD:
			if (special == SVS_ICQVERSION) {
				if (dbv.wVal != 0) {
					char szExtra[80];

					mir_snprintf(str, "%d", dbv.wVal);
					pstr = str;

					if (hContact && ppro->IsDirectConnectionOpen(hContact, DIRECTCONN_STANDARD, 1)) {
						ICQTranslateUtfStatic(LPGEN(" (DC Established)"), szExtra, _countof(szExtra));
						mir_strcat(str, (char*)szExtra);
						bUtf = 1;
					}
				}
				else
					unspecified = 1;
			}
			else if (special == SVS_STATUSID) {
				char *pszStatus = MirandaStatusToStringUtf(dbv.wVal);
				BYTE bXStatus = ppro->getContactXStatus(hContact);

				if (bXStatus) {
					char *pXName = ppro->getSettingStringUtf(hContact, DBSETTING_XSTATUS_NAME, nullptr);
					if (pXName == nullptr) // give default name
						pXName = ICQTranslateUtf(nameXStatus[bXStatus - 1]);

					mir_snprintf(str, "%s (%s)", pszStatus, pXName);
					SAFE_FREE((void**)&pXName);
				}
				else strncpy_s(str, pszStatus, _TRUNCATE);

				bUtf = 1;
				SAFE_FREE(&pszStatus);
				pstr = str;
				unspecified = 0;
			}
			else {
				unspecified = (special == SVS_ZEROISUNSPEC && dbv.wVal == 0);
				pstr = _itoa(special == SVS_SIGNED ? dbv.sVal : dbv.wVal, str, 10);
			}
			break;

		case DBVT_DWORD:
			unspecified = (special == SVS_ZEROISUNSPEC && dbv.dVal == 0);
			if (special == SVS_IP) {
				struct in_addr ia;
				ia.S_un.S_addr = htonl(dbv.dVal);
				pstr = inet_ntoa(ia);
				if (dbv.dVal == 0)
					unspecified = 1;
			}
			else if (special == SVS_TIMESTAMP) {
				if (dbv.dVal == 0)
					unspecified = 1;
				else
					pstr = time2text(dbv.dVal);
			}
			else
				pstr = _itoa(special == SVS_SIGNED ? dbv.lVal : dbv.dVal, str, 10);
			break;

		case DBVT_ASCIIZ:
		case DBVT_WCHAR:
			unspecified = (special == SVS_ZEROISUNSPEC && dbv.pszVal[0] == '\0');
			if (!unspecified && pstr != szSetting) {
				pstr = ppro->getSettingStringUtf(hContact, szModule, szSetting, nullptr);
				bUtf = 1;
				bAlloc = 1;
			}
			if (idCtrl == IDC_UIN)
				SetDlgItemText(hwndDlg, IDC_UINSTATIC, TranslateT("ScreenName:"));
			break;

		default:
			pstr = str;
			mir_strcpy(str, "???");
			break;
		}
	}

	EnableDlgItem(hwndDlg, idCtrl, !unspecified);
	if (unspecified)
		SetDlgItemText(hwndDlg, idCtrl, TranslateT("<not specified>"));
	else if (bUtf)
		SetDlgItemTextUtf(hwndDlg, idCtrl, pstr);
	else
		SetDlgItemTextA(hwndDlg, idCtrl, pstr);

	if (bDbv)
		db_free(&dbv);

	if (bAlloc)
		SAFE_FREE(&pstr);
}

/////////////////////////////////////////////////////////////////////////////////////////

static INT_PTR CALLBACK IcqDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg) {
	case WM_INITDIALOG:
		TranslateDialogDefault(hwndDlg);
		break;

	case WM_NOTIFY:
		switch (((LPNMHDR)lParam)->idFrom) {
		case 0:
			switch (((LPNMHDR)lParam)->code) {
			case PSN_PARAMCHANGED:
				SetWindowLongPtr(hwndDlg, GWLP_USERDATA, ((PSHNOTIFY*)lParam)->lParam);
				break;

			case PSN_INFOCHANGED:
				CIcqProto* ppro = (CIcqProto*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
				if (!ppro)
					break;

				char* szProto;
				MCONTACT hContact = (MCONTACT)((LPPSHNOTIFY)lParam)->lParam;

				if (hContact == NULL)
					szProto = ppro->m_szModuleName;
				else
					szProto = GetContactProto(hContact);

				if (!szProto)
					break;

				SetValue(ppro, hwndDlg, IDC_UIN, hContact, szProto, UNIQUEIDSETTING, SVS_NORMAL);
				SetValue(ppro, hwndDlg, IDC_ONLINESINCE, hContact, szProto, "LogonTS", SVS_TIMESTAMP);
				SetValue(ppro, hwndDlg, IDC_IDLETIME, hContact, szProto, "IdleTS", SVS_TIMESTAMP);
				SetValue(ppro, hwndDlg, IDC_IP, hContact, szProto, "IP", SVS_IP);
				SetValue(ppro, hwndDlg, IDC_REALIP, hContact, szProto, "RealIP", SVS_IP);

				if (hContact) {
					SetValue(ppro, hwndDlg, IDC_PORT, hContact, szProto, "UserPort", SVS_ZEROISUNSPEC);
					SetValue(ppro, hwndDlg, IDC_VERSION, hContact, szProto, "Version", SVS_ICQVERSION);
					SetValue(ppro, hwndDlg, IDC_MIRVER, hContact, szProto, "MirVer", SVS_ZEROISUNSPEC);
					if (ppro->getByte(hContact, "ClientID", 0))
						ppro->setDword(hContact, "TickTS", 0);
					SetValue(ppro, hwndDlg, IDC_SYSTEMUPTIME, hContact, szProto, "TickTS", SVS_TIMESTAMP);
					SetValue(ppro, hwndDlg, IDC_STATUS, hContact, szProto, "Status", SVS_STATUSID);
				}
				else {
					MFileVersion v;
					Miranda_GetFileVersion(&v);

					char str[MAX_PATH];
					mir_snprintf(str, "Miranda NG %d.%d.%d.%d (ICQ %s)", v[0], v[1], v[2], v[3], __VERSION_STRING_DOTS);

					SetValue(ppro, hwndDlg, IDC_PORT, hContact, (char*)DBVT_WORD, (char*)ppro->wListenPort, SVS_ZEROISUNSPEC);
					SetValue(ppro, hwndDlg, IDC_VERSION, hContact, (char*)DBVT_WORD, (char*)ICQ_VERSION, SVS_ICQVERSION);
					SetValue(ppro, hwndDlg, IDC_MIRVER, hContact, (char*)DBVT_ASCIIZ, str, SVS_ZEROISUNSPEC);
					SetDlgItemText(hwndDlg, IDC_SUPTIME, TranslateT("Member since:"));
					SetValue(ppro, hwndDlg, IDC_SYSTEMUPTIME, hContact, szProto, "MemberTS", SVS_TIMESTAMP);
					SetValue(ppro, hwndDlg, IDC_STATUS, hContact, (char*)DBVT_WORD, (char*)ppro->m_iStatus, SVS_STATUSID);
				}
			}
		}
		break;

	case WM_COMMAND:
		switch (LOWORD(wParam)) {
		case IDCANCEL:
			SendMessage(GetParent(hwndDlg), msg, wParam, lParam);
			break;
		}
		break;
	}

	return FALSE;
}

/////////////////////////////////////////////////////////////////////////////////////////

int CIcqProto::OnUserInfoInit(WPARAM wParam, LPARAM lParam)
{
	if ((!IsICQContact(lParam)) && lParam)
		return 0;

	OPTIONSDIALOGPAGE odp = { 0 };
	odp.flags = ODPF_UNICODE | ODPF_DONTTRANSLATE;
	odp.hInstance = hInst;
	odp.dwInitParam = LPARAM(this);
	odp.pfnDlgProc = IcqDlgProc;
	odp.position = -1900000000;
	odp.szTitle.w = m_tszUserName;
	odp.pszTemplate = MAKEINTRESOURCEA(IDD_INFO_ICQ);
	UserInfo_AddPage(wParam, &odp);

	if (!lParam) {
		wchar_t buf[200];
		mir_snwprintf(buf, TranslateT("%s Details"), m_tszUserName);
		odp.szTitle.w = buf;

		odp.position = -1899999999;
		odp.pszTemplate = MAKEINTRESOURCEA(IDD_INFO_CHANGEINFO);
		odp.pfnDlgProc = ChangeInfoDlgProc;
		UserInfo_AddPage(wParam, &odp);
	}
	return 0;
}