//***************************************************************************************
//
//   Google Extension plugin for the Miranda IM's Jabber protocol
//   Copyright (c) 2011 bems@jabber.org, George Hazan (ghazan@jabber.ru)
//
//   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"
#include "resources.h"
#include "options.h"

#define AVA_FILE_NAME_FORMAT  L"%s\\%s\\AvatarCache\\Jabber\\" _T(SHORT_PLUGIN_NAME) L".pseudoava.png"
#define AVA_RES_TYPE  L"PNG"
#define SRMM_MODULE_NAME  "SRMM"
#define SRMM_AVATAR_SETTING_NAME  "Avatar"

#define SET_AVATAR_INTERVAL 2000

LPTSTR CreateAvaFile(HANDLE *hFile)
{
	wchar_t name[MAX_PATH + 2];
	if (Profile_GetNameW(_countof(name), name))
		return NULL;

	wchar_t *p = wcsrchr(name, '.');
	if (p)
		*p = 0;

	wchar_t path[MAX_PATH + 2];
	Profile_GetPathW(_countof(path), path);

	wchar_t full[MAX_PATH + 2];
	mir_snwprintf(full, AVA_FILE_NAME_FORMAT, path, name);
	CreateDirectoryTreeW(full);

	HANDLE h = CreateFile(full, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
	if (h == INVALID_HANDLE_VALUE)
		return NULL;

	if (hFile)
		*hFile = h;
	else
		CloseHandle(h);

	return mir_wstrdup(full);
}

BOOL SaveAvatar(HANDLE hFile)
{
	HRSRC hres = FindResource(g_hInst, MAKEINTRESOURCE(IDI_PSEUDOAVA), AVA_RES_TYPE);
	if (!hres) return FALSE;

	HGLOBAL hglob = LoadResource(g_hInst, hres);
	if (!hglob) return FALSE;

	PVOID p = LockResource(hglob);
	if (!p) return FALSE;

	DWORD l = SizeofResource(g_hInst, hres);
	if (!l) return FALSE;

	DWORD written;
	if (!WriteFile(hFile, p, l, &written, NULL)) return FALSE;
	return written == l;
}

struct AVACHANGED {
	HANDLE hTimer;
	MCONTACT hContact;
};

VOID CALLBACK CallSetAvatar(PVOID lpParameter, BOOLEAN)
{
	Thread_Push(0);
	__try {
		AVACHANGED *ach = (AVACHANGED*)lpParameter;
		__try {
			SetAvatar(ach->hContact);
			DeleteTimerQueueTimer(NULL, ach->hTimer, NULL);
		}
		__finally {
			free(ach);
		}
	}
	__finally {
		Thread_Pop();
	}
}

int AvaChanged(WPARAM hContact, LPARAM lParam)
{
	if (!lParam && db_get_b(hContact, SHORT_PLUGIN_NAME, PSEUDOCONTACT_FLAG, 0)) {
		BOOL enqueued = FALSE;
		AVACHANGED *ach = (AVACHANGED*)malloc(sizeof(AVACHANGED));
		__try {
			ach->hContact = hContact;
			enqueued = CreateTimerQueueTimer(&ach->hTimer, NULL, CallSetAvatar, ach, SET_AVATAR_INTERVAL, 0, WT_EXECUTEONLYONCE);
		}
		__finally {
			if (!enqueued) free(ach);
		}
	}
	return 0;
}

mir_cs g_csSetAvatar;
HANDLE hAvaChanged = 0;

BOOL InitAvaUnit(BOOL init)
{
	if (init) {
		hAvaChanged = HookEvent(ME_AV_AVATARCHANGED, AvaChanged);
		return hAvaChanged != 0;
	}

	if (hAvaChanged) {
		UnhookEvent(hAvaChanged);
		hAvaChanged = 0;
	}
	return TRUE;
}

void SetAvatar(MCONTACT hContact)
{
	mir_cslock lck(g_csSetAvatar);

	AVATARCACHEENTRY *ava = (AVATARCACHEENTRY*)CallService(MS_AV_GETAVATARBITMAP, hContact, 0);
	if (ava && GetFileAttributes(&ava->szFilename[0]) != INVALID_FILE_ATTRIBUTES)
		return;

	HANDLE hFile;
	ptrW avaFile(CreateAvaFile(&hFile));
	if (avaFile == NULL)
		return;

	BOOL saved = SaveAvatar(hFile);
	CloseHandle(hFile); hFile = 0;
	if (!saved)
		return;

	if (ava)
		CallService(MS_AV_SETAVATARW, hContact, (LPARAM)L"");
	CallService(MS_AV_SETAVATARW, hContact, (LPARAM)avaFile);
	db_set_ws(hContact, SRMM_MODULE_NAME, SRMM_AVATAR_SETTING_NAME, avaFile);
}