/*
 * (C) 2003-2006 Gabest
 * (C) 2006-2015 see Authors.txt
 *
 * This file is part of MPC-BE.
 *
 * MPC-BE 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 3 of the License, or
 * (at your option) any later version.
 *
 * MPC-BE 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, see <http://www.gnu.org/licenses/>.
 *
 */

#include "stdafx.h"
#include "FontInstaller.h"

CFontInstaller::CFontInstaller()
{
	if (HMODULE hGdi = GetModuleHandle(_T("gdi32.dll"))) {
		pAddFontMemResourceEx = (HANDLE (WINAPI *)(PVOID,DWORD,PVOID,DWORD*))GetProcAddress(hGdi, "AddFontMemResourceEx");
		pAddFontResourceEx = (int (WINAPI *)(LPCTSTR,DWORD,PVOID))GetProcAddress(hGdi, "AddFontResourceExW");
		pRemoveFontMemResourceEx = (BOOL (WINAPI *)(HANDLE))GetProcAddress(hGdi, "RemoveFontMemResourceEx");
		pRemoveFontResourceEx = (BOOL (WINAPI *)(LPCTSTR,DWORD,PVOID))GetProcAddress(hGdi, "RemoveFontResourceExW");
	}

	if (HMODULE hGdi = GetModuleHandle(_T("kernel32.dll"))) {
		pMoveFileEx = (BOOL (WINAPI *)(LPCTSTR, LPCTSTR, DWORD))GetProcAddress(hGdi, "MoveFileExW");
	}
}

CFontInstaller::~CFontInstaller()
{
	UninstallFonts();
}

void CFontInstaller::UninstallFonts()
{
	if (pRemoveFontMemResourceEx) {
		POSITION pos = m_fonts.GetHeadPosition();
		while (pos) {
			pRemoveFontMemResourceEx(m_fonts.GetNext(pos));
		}
		m_fonts.RemoveAll();
	}

	if (pRemoveFontResourceEx) {
		POSITION pos = m_files.GetHeadPosition();
		while (pos) {
			CString fn = m_files.GetNext(pos);
			pRemoveFontResourceEx(fn, FR_PRIVATE, 0);
		}
		m_files.RemoveAll();

		pos = m_tempfiles.GetHeadPosition();
		while (pos) {
			CString fn = m_tempfiles.GetNext(pos);
			pRemoveFontResourceEx(fn, FR_PRIVATE, 0);
			if (!DeleteFile(fn) && pMoveFileEx) {
				pMoveFileEx(fn, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
			}
		}
		m_tempfiles.RemoveAll();
	}
}

bool CFontInstaller::InstallFontMemory(const void* pData, UINT len)
{
	if (!pAddFontMemResourceEx) {
		return false;
	}

	DWORD nFonts = 0;
	HANDLE hFont = pAddFontMemResourceEx((PVOID)pData, len, NULL, &nFonts);
	if (hFont && nFonts > 0) {
		m_fonts.AddTail(hFont);
	}
	return hFont && nFonts > 0;
}

bool CFontInstaller::InstallFontFile(LPCTSTR filename)
{
	if (pAddFontResourceEx && pAddFontResourceEx(filename, FR_PRIVATE, 0) > 0) {
		m_files.AddTail(filename);
		return true;
	}

	return false;
}

bool CFontInstaller::InstallFontTempFile(const void* pData, UINT len)
{
	if (!pAddFontResourceEx) {
		return false;
	}

	CFile f;
	TCHAR path[_MAX_PATH], fn[_MAX_PATH];
	if (!GetTempPath(_MAX_PATH, path) || !GetTempFileName(path, _T("g_font"), 0, fn)) {
		return false;
	}

	if (f.Open(fn, CFile::modeWrite)) {
		f.Write(pData, len);
		f.Close();

		if (pAddFontResourceEx(fn, FR_PRIVATE, 0) > 0) {
			m_tempfiles.AddTail(fn);
			return true;
		}
	}

	DeleteFile(fn);
	return false;
}
