/*
 *
 * Copyright 2009 Austin English
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */


#include "config.h"

#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winreg.h"
#include "t2embapi.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(t2embed);

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{

    switch (fdwReason)
    {
        case DLL_WINE_PREATTACH:
            return FALSE;    /* prefer native version */
        case DLL_PROCESS_ATTACH:
            DisableThreadLibraryCalls(hinstDLL);
            break;
    }

    return TRUE;
}

LONG WINAPI TTLoadEmbeddedFont(HANDLE *phFontReference, ULONG ulFlags,
                               ULONG *pulPrivStatus, ULONG ulPrivs,
                               ULONG *pulStatus, READEMBEDPROC lpfnReadFromStream,
                               LPVOID lpvReadStream, LPWSTR szWinFamilyName,
                               LPSTR szMacFamilyName, TTLOADINFO *pTTLoadInfo)
{
    FIXME("(%p 0x%08x %p 0x%08x %p %p %p %s %s %p) stub\n", phFontReference,
          ulFlags, pulPrivStatus, ulPrivs, pulStatus, lpfnReadFromStream,
          lpvReadStream, debugstr_w(szWinFamilyName), szMacFamilyName,
          pTTLoadInfo);

    return E_API_NOTIMPL;
}

LONG WINAPI TTEmbedFont(HDC hDC, ULONG ulFlags, ULONG ulCharSet, ULONG *pulPrivStatus,
                         ULONG *pulStatus, WRITEEMBEDPROC lpfnWriteToStream, LPVOID lpvWriteStream,
                         USHORT *pusCharCodeSet, USHORT usCharCodeCount, USHORT usLanguage,
                         TTEMBEDINFO *pTTEmbedInfo)
{
    FIXME("(%p 0x%08x 0x%08x %p %p %p %p %p %u %u %p) stub\n", hDC,
          ulFlags, ulCharSet, pulPrivStatus, pulStatus, lpfnWriteToStream,
          lpvWriteStream, pusCharCodeSet, usCharCodeCount, usLanguage,
          pTTEmbedInfo);

    return E_API_NOTIMPL;
}

LONG WINAPI TTGetEmbeddingType(HDC hDC, ULONG *status)
{
    OUTLINETEXTMETRICW otm;

    TRACE("(%p %p)\n", hDC, status);

    if (!hDC)
        return E_HDCINVALID;

    otm.otmSize = sizeof(otm);
    if (!GetOutlineTextMetricsW(hDC, otm.otmSize, &otm))
        return E_NOTATRUETYPEFONT;

    if (!status)
        return E_PERMISSIONSINVALID;

    if (otm.otmfsType == LICENSE_INSTALLABLE)
        *status = EMBED_INSTALLABLE;
    else if (otm.otmfsType & LICENSE_NOEMBEDDING)
        *status = EMBED_NOEMBEDDING;
    else if (otm.otmfsType & LICENSE_PREVIEWPRINT)
        *status = EMBED_PREVIEWPRINT;
    else if (otm.otmfsType & LICENSE_EDITABLE)
        *status = EMBED_EDITABLE;

    return E_NONE;
}

LONG WINAPI TTIsEmbeddingEnabledForFacename(LPCSTR facename, BOOL *enabled)
{
    static const WCHAR exclusionlistW[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
        'S','h','a','r','e','d',' ','T','o','o','l','s','\\','t','2','e','m','b','e','d',0};
    DWORD index;
    HKEY hkey;
    LONG ret;

    TRACE("(%s %p)\n", debugstr_a(facename), enabled);

    if (!facename)
        return E_FACENAMEINVALID;

    if (!enabled)
        return E_PBENABLEDINVALID;

    *enabled = TRUE;
    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, exclusionlistW, 0, GENERIC_READ, &hkey))
        return E_NONE;

    *enabled = TRUE;
    ret = ERROR_SUCCESS;
    index = 0;
    while (ret != ERROR_NO_MORE_ITEMS)
    {
        DWORD name_len, value_len, value, type;
        CHAR name[LF_FACESIZE];

        name_len = sizeof(name)/sizeof(*name);
        value_len = sizeof(value);
        ret = RegEnumValueA(hkey, index++, name, &name_len, NULL, &type, (BYTE*)&value, &value_len);
        if (ret || type != REG_DWORD)
            continue;

        if (!lstrcmpiA(name, facename))
        {
            *enabled = !!value;
            break;
        }
    }
    RegCloseKey(hkey);

    return E_NONE;
}

LONG WINAPI TTIsEmbeddingEnabled(HDC hDC, BOOL *enabled)
{
    OUTLINETEXTMETRICA *otm;
    LONG ret;
    UINT len;

    TRACE("(%p %p)\n", hDC, enabled);

    if (!hDC)
        return E_HDCINVALID;

    len = GetOutlineTextMetricsA(hDC, 0, NULL);
    if (!len)
        return E_ERRORACCESSINGFACENAME;

    otm = HeapAlloc(GetProcessHeap(), 0, len);
    if (!otm)
        return E_NOFREEMEMORY;

    GetOutlineTextMetricsA(hDC, len, otm);
    ret = TTIsEmbeddingEnabledForFacename(otm->otmpFaceName, enabled);
    HeapFree(GetProcessHeap(), 0, otm);
    return ret;
}

LONG WINAPI TTDeleteEmbeddedFont(HANDLE hFontReference, ULONG flags, ULONG *status)
{
    FIXME("(%p 0x%08x %p) stub\n", hFontReference, flags, status);
    return E_API_NOTIMPL;
}
