/*
	New Away System - plugin for Miranda IM
	Copyright (C) 2005-2007 Chervov Dmitry
	Copyright (C) 2004-2005 Iksaif Entertainment
	Copyright (C) 2002-2003 Goblineye Entertainment

    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include "stdafx.h"

struct READAWAYMSGDATA
{
	MCONTACT hContact; // contact
	HANDLE hSeq; // sequence for stat msg request
	HANDLE hAwayMsgEvent; // hooked
};

#define RAMDLGSIZESETTING "ReadAwayMsgDlg"

MWindowList g_hReadWndList = nullptr;

static int ReadAwayMsgDlgResize(HWND, LPARAM, UTILRESIZECONTROL *urc)
{
	switch (urc->wId) {
	case IDC_READAWAYMSG_MSG:
		return RD_ANCHORX_WIDTH | RD_ANCHORY_HEIGHT;

	case IDC_READAWAYMSG_RETRIEVE:
		return RD_ANCHORX_CENTRE | RD_ANCHORY_CENTRE;

	case IDOK:
		return RD_ANCHORX_CENTRE | RD_ANCHORY_BOTTOM;
	}
	return RD_ANCHORX_LEFT | RD_ANCHORY_TOP;
}

static INT_PTR CALLBACK ReadAwayMsgDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg) {
	case WM_INITDIALOG:
		TranslateDialogDefault(hwndDlg);
		Window_SetSkinIcon_IcoLib(hwndDlg, SKINICON_OTHER_MIRANDA);
		Utils_RestoreWindowPosition(hwndDlg, NULL, MOD_NAME, RAMDLGSIZESETTING);
		{
			READAWAYMSGDATA *awayData = new READAWAYMSGDATA;
			SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)awayData);
			awayData->hContact = lParam;
			awayData->hAwayMsgEvent = HookEventMessage(ME_PROTO_ACK, hwndDlg, UM_RAM_AWAYMSGACK);
			awayData->hSeq = (HANDLE)ProtoChainSend(awayData->hContact, PSS_GETAWAYMSG, 0, 0);
			WindowList_Add(g_hReadWndList, hwndDlg, awayData->hContact);

			wchar_t str[256], format[128];
			wchar_t *contactName = pcli->pfnGetContactDisplayName(awayData->hContact, 0);
			char *szProto = GetContactProto(awayData->hContact);
			wchar_t *status = pcli->pfnGetStatusModeDescription(db_get_w(awayData->hContact, szProto, "Status", ID_STATUS_OFFLINE), 0);
			GetWindowText(hwndDlg, format, _countof(format));
			mir_snwprintf(str, format, status, contactName);
			SetWindowText(hwndDlg, str);
			GetDlgItemText(hwndDlg, IDC_READAWAYMSG_RETRIEVE, format, _countof(format));
			mir_snwprintf(str, format, status);
			SetDlgItemText(hwndDlg, IDC_READAWAYMSG_RETRIEVE, str);
		}
		return true;

	case UM_RAM_AWAYMSGACK: // got away msg
		{
			ACKDATA *ack = (ACKDATA*)lParam;
			READAWAYMSGDATA *awayData = (READAWAYMSGDATA*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
			// make sure everything is ok, and this is our ack
			if (ack->hContact != awayData->hContact || ack->type != ACKTYPE_AWAYMSG || ack->hProcess != awayData->hSeq || ack->result != ACKRESULT_SUCCESS)
				break;

			// done with the event
			if (awayData->hAwayMsgEvent) {
				UnhookEvent(awayData->hAwayMsgEvent);
				awayData->hAwayMsgEvent = nullptr;
			}
			const wchar_t *ptszStatusMsg = (const wchar_t*)ack->lParam;
			SetDlgItemText(hwndDlg, IDC_READAWAYMSG_MSG, ptszStatusMsg);
			ShowWindow(GetDlgItem(hwndDlg, IDC_READAWAYMSG_RETRIEVE), SW_HIDE);
			ShowWindow(GetDlgItem(hwndDlg, IDC_READAWAYMSG_MSG), SW_SHOW);
			SetDlgItemText(hwndDlg, IDOK, TranslateT("&Close"));
			db_set_ws(awayData->hContact, "CList", "StatusMsg", ptszStatusMsg);
		}
		break;

	case WM_COMMAND:
		switch (HIWORD(wParam)) {
		case BN_CLICKED:
			switch (LOWORD(wParam)) {
			case IDCANCEL:
			case IDOK:
				DestroyWindow(hwndDlg);
				break;
			}
		}
		break;

	case WM_SIZE:
		Utils_ResizeDialog(hwndDlg, g_hInstance, MAKEINTRESOURCEA(IDD_READAWAYMSG), ReadAwayMsgDlgResize);
		break;

	case WM_CLOSE:
		DestroyWindow(hwndDlg);
		break;

	case WM_DESTROY:
		READAWAYMSGDATA *awayData = (READAWAYMSGDATA*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
		if (awayData->hAwayMsgEvent) {
			UnhookEvent(awayData->hAwayMsgEvent);
			awayData->hAwayMsgEvent = nullptr;
		}
		delete awayData;
		Utils_SaveWindowPosition(hwndDlg, NULL, MOD_NAME, RAMDLGSIZESETTING);
		WindowList_Remove(g_hReadWndList, hwndDlg);
	}
	return false;
}

INT_PTR GetContactStatMsg(WPARAM wParam, LPARAM)
{
	if (HWND hWnd = WindowList_Find(g_hReadWndList, wParam)) // already have it
		SetForegroundWindow(hWnd);
	else
		CreateDialogParam(g_hInstance, MAKEINTRESOURCE(IDD_READAWAYMSG), nullptr, ReadAwayMsgDlgProc, wParam);
	return 0;
}