/*
	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 "Common.h"

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

#define RAMDLGSIZESETTING "ReadAwayMsgDlg"

HANDLE g_hReadWndList = NULL;

static int ReadAwayMsgDlgResize(HWND hwndDlg, LPARAM 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);
		{
			HICON hTitleIcon = LoadSkinnedIcon(SKINICON_OTHER_MIRANDA);
			SendMessage(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hTitleIcon);
			SendMessage(hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM)hTitleIcon);
			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)CallContactService(awayData->hContact, PSS_GETAWAYMSG, 0, 0);
			WindowList_Add(g_hReadWndList, hwndDlg, awayData->hContact);

			TCHAR str[256], format[128];
			TCHAR *contactName = pcli->pfnGetContactDisplayName(awayData->hContact, 0);
			char *szProto = GetContactProto(awayData->hContact);
			TCHAR *status = pcli->pfnGetStatusModeDescription(db_get_w(awayData->hContact, szProto, "Status", ID_STATUS_OFFLINE), 0);
			GetWindowText(hwndDlg, format, SIZEOF(format));
			_sntprintf(str, SIZEOF(str), format, status, contactName);
			SetWindowText(hwndDlg, str);
			GetDlgItemText(hwndDlg, IDC_READAWAYMSG_RETRIEVE, format, sizeof(format));
			_sntprintf(str, SIZEOF(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 = NULL;
			}
			SetDlgItemText(hwndDlg, IDC_READAWAYMSG_MSG, (const TCHAR*)ack->lParam);
			ShowWindow(GetDlgItem(hwndDlg, IDC_READAWAYMSG_RETRIEVE), SW_HIDE);
			ShowWindow(GetDlgItem(hwndDlg, IDC_READAWAYMSG_MSG), SW_SHOW);
			SetDlgItemText(hwndDlg, IDOK, TranslateT("&Close"));
			db_set_s(awayData->hContact, "CList", "StatusMsg", (const char*)ack->lParam);
		}
		break;

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

	case WM_SIZE:
		{
			UTILRESIZEDIALOG urd = { sizeof(urd) };
			urd.hInstance = g_hInstance;
			urd.hwndDlg = hwndDlg;
			urd.lpTemplate = MAKEINTRESOURCEA(IDD_READAWAYMSG);
			urd.pfnResizer = ReadAwayMsgDlgResize;
			CallService(MS_UTILS_RESIZEDIALOG, 0, (LPARAM)&urd);
		}
		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 = NULL;
		}
		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), NULL, ReadAwayMsgDlgProc, wParam);
	return 0;
}