/*
 *
 * 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;
    WORD fsType;

    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;

    otm.otmfsType = (fsType = otm.otmfsType) & 0xf;
    if (otm.otmfsType == LICENSE_INSTALLABLE)
        *status = EMBED_INSTALLABLE;
    else if (otm.otmfsType & LICENSE_EDITABLE)
        *status = EMBED_EDITABLE;
    else if (otm.otmfsType & LICENSE_PREVIEWPRINT)
        *status = EMBED_PREVIEWPRINT;
    else if (otm.otmfsType & LICENSE_NOEMBEDDING)
        *status = EMBED_NOEMBEDDING;
    else
    {
        WARN("unrecognized flags, %#x\n", otm.otmfsType);
        *status = EMBED_INSTALLABLE;
    }

    TRACE("fsType 0x%04x, status %u\n", fsType, *status);
    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))
        goto out;

    *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);

out:
    TRACE("embedding %s for %s\n", *enabled ? "enabled" : "disabled", debugstr_a(facename));
    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((LPCSTR)otm + (ULONG_PTR)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;
}
