/*
 * Copyright 2014 Jacek Caban for CodeWeavers
 *
 * 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 "wmp_private.h"
#include "olectl.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(wmp);

static HWND get_container_hwnd(WindowsMediaPlayer *This)
{
    IOleWindow *ole_window;
    HWND hwnd = NULL;
    HRESULT hres;

    /* IOleInPlaceSite (which inherits from IOleWindow) is preferred. */
    hres = IOleClientSite_QueryInterface(This->client_site, &IID_IOleInPlaceSite, (void**)&ole_window);
    if(FAILED(hres)) {
        hres = IOleClientSite_QueryInterface(This->client_site, &IID_IOleWindow, (void**)&ole_window);
        if(FAILED(hres)) {
            IOleContainer *container = NULL;

            hres = IOleClientSite_GetContainer(This->client_site, &container);
            if(SUCCEEDED(hres)) {
                hres = IOleContainer_QueryInterface(container, &IID_IOleWindow, (void**)&ole_window);
                IOleContainer_Release(container);
            }
        }
    }

    if(FAILED(hres))
        return NULL;

    hres = IOleWindow_GetWindow(ole_window, &hwnd);
    IOleWindow_Release(ole_window);
    if(FAILED(hres))
        return NULL;

    TRACE("Got window %p\n", hwnd);
    return hwnd;
}

static LRESULT WINAPI wmp_wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch(msg) {
    case WM_PAINT: {
        PAINTSTRUCT ps;
        HFONT font;
        RECT rect;
        HDC hdc;

        TRACE("WM_PAINT\n");

        GetClientRect(hwnd, &rect);
        hdc = BeginPaint(hwnd, &ps);

        SelectObject(hdc, GetStockObject(DC_BRUSH));
        SetDCBrushColor(hdc, RGB(255,0,0));
        SetBkColor(hdc, RGB(255,0,0));

        font = CreateFontA(25,0,0,0,400,0,0,0,ANSI_CHARSET,0,0,DEFAULT_QUALITY,DEFAULT_PITCH,NULL);
        SelectObject(hdc, font);

        Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);
        DrawTextA(hdc, "FIXME: WMP", -1, &rect, DT_CENTER | DT_SINGLELINE | DT_VCENTER);

        DeleteObject(font);
        EndPaint(hwnd, &ps);
        break;
    }
    }

    return DefWindowProcW(hwnd, msg, wParam, lParam);

}

static ATOM wmp_class;

static BOOL WINAPI register_wmp_class(INIT_ONCE *once, void *param, void **context)
{
    /* It seems that native uses ATL for this. We use a fake name to make tests happy. */
    static const WCHAR atl_wmpW[] = {'A','T','L',':','W','M','P',0};

    static WNDCLASSEXW wndclass = {
        sizeof(wndclass), CS_DBLCLKS, wmp_wnd_proc, 0, 0,
        NULL, NULL, NULL, NULL, NULL,
        atl_wmpW, NULL
    };

    wndclass.hInstance = wmp_instance;
    wmp_class = RegisterClassExW(&wndclass);
    return TRUE;
}

void unregister_wmp_class(void)
{
    if(wmp_class)
        UnregisterClassW(MAKEINTRESOURCEW(wmp_class), wmp_instance);
}

static HWND create_wmp_window(WindowsMediaPlayer *wmp, const RECT *posrect)
{
    static INIT_ONCE class_init_once = INIT_ONCE_STATIC_INIT;

    InitOnceExecuteOnce(&class_init_once, register_wmp_class, NULL, NULL);
    if(!wmp_class)
        return NULL;

    return CreateWindowExW(0, MAKEINTRESOURCEW(wmp_class), NULL, WS_CLIPCHILDREN|WS_CLIPSIBLINGS|WS_VISIBLE|WS_CHILD,
            posrect->left, posrect->top, posrect->right-posrect->left, posrect->bottom-posrect->top,
            get_container_hwnd(wmp), NULL, wmp_instance, NULL);
}

static HRESULT activate_inplace(WindowsMediaPlayer *This)
{
    IOleInPlaceSiteWindowless *ipsite_windowless;
    IOleInPlaceSiteEx *ipsiteex = NULL;
    IOleInPlaceSite *ipsite;
    IOleInPlaceUIWindow *ip_window = NULL;
    IOleInPlaceFrame *ip_frame = NULL;
    RECT posrect = {0}, cliprect = {0};
    OLEINPLACEFRAMEINFO frameinfo = { sizeof(frameinfo) };
    HRESULT hres;

    if(This->hwnd) {
        FIXME("Already activated\n");
        return E_UNEXPECTED;
    }

    hres = IOleClientSite_QueryInterface(This->client_site, &IID_IOleInPlaceSiteWindowless, (void**)&ipsite_windowless);
    if(SUCCEEDED(hres)) {
        hres = IOleInPlaceSiteWindowless_CanWindowlessActivate(ipsite_windowless);
        IOleInPlaceSiteWindowless_Release(ipsite_windowless);
        if(hres == S_OK)
            FIXME("Windowless activation not supported\n");
        ipsiteex = (IOleInPlaceSiteEx*)ipsite_windowless;
    }else {
        IOleClientSite_QueryInterface(This->client_site, &IID_IOleInPlaceSiteEx, (void**)&ipsiteex);
    }

    if(ipsiteex) {
        BOOL redraw = FALSE; /* Not really used. */
        IOleInPlaceSiteEx_OnInPlaceActivateEx(ipsiteex, &redraw, 0);
        ipsite = (IOleInPlaceSite*)ipsiteex;
    }else {
        IOleClientSite_QueryInterface(This->client_site, &IID_IOleInPlaceSite, (void**)&ipsite);
        if(FAILED(hres)) {
            FIXME("No IOleInPlaceSite instance\n");
            return hres;
        }

        IOleInPlaceSite_OnInPlaceActivate(ipsite);
    }

    hres = IOleInPlaceSite_GetWindowContext(ipsite, &ip_frame, &ip_window, &posrect, &cliprect, &frameinfo);
    IOleInPlaceSite_Release(ipsite);
    if(FAILED(hres)) {
        FIXME("GetWindowContext failed: %08x\n", hres);
        return hres;
    }

    This->hwnd = create_wmp_window(This, &posrect);
    if(!This->hwnd)
        return E_FAIL;

    IOleClientSite_ShowObject(This->client_site);
    return S_OK;
}

static void deactivate_window(WindowsMediaPlayer *This)
{
    IOleInPlaceSite *ip_site;
    HRESULT hres;

    hres = IOleClientSite_QueryInterface(This->client_site, &IID_IOleInPlaceSite, (void**)&ip_site);
    if(SUCCEEDED(hres)) {
        IOleInPlaceSite_OnInPlaceDeactivate(ip_site);
        IOleInPlaceSite_Release(ip_site);
    }

    DestroyWindow(This->hwnd);
    This->hwnd = NULL;
}

static void release_client_site(WindowsMediaPlayer *This)
{
    if(!This->client_site)
        return;

    if(This->hwnd)
        deactivate_window(This);

    IOleClientSite_Release(This->client_site);
    This->client_site = NULL;
}

static inline WindowsMediaPlayer *impl_from_IOleObject(IOleObject *iface)
{
    return CONTAINING_RECORD(iface, WindowsMediaPlayer, IOleObject_iface);
}

static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, void **ppv)
{
    WindowsMediaPlayer *This = impl_from_IOleObject(iface);

    *ppv = NULL;

    if(IsEqualGUID(riid, &IID_IUnknown)) {
        TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
        *ppv = &This->IOleObject_iface;
    }else if(IsEqualGUID(riid, &IID_IOleObject)) {
        TRACE("(%p)->(IID_IOleObject %p)\n", This, ppv);
        *ppv = &This->IOleObject_iface;
    }else if(IsEqualGUID(riid, &IID_IProvideClassInfo)) {
        TRACE("(%p)->(IID_IProvideClassInfo %p)\n", This, ppv);
        *ppv = &This->IProvideClassInfo2_iface;
    }else if(IsEqualGUID(riid, &IID_IProvideClassInfo2)) {
        TRACE("(%p)->(IID_IProvideClassInfo2 %p)\n", This, ppv);
        *ppv = &This->IProvideClassInfo2_iface;
    }else if(IsEqualGUID(riid, &IID_IPersist)) {
        TRACE("(%p)->(IID_IPersist %p)\n", This, ppv);
        *ppv = &This->IPersistStreamInit_iface;
    }else if(IsEqualGUID(riid, &IID_IPersistStreamInit)) {
        TRACE("(%p)->(IID_IPersistStreamInit %p)\n", This, ppv);
        *ppv = &This->IPersistStreamInit_iface;
    }else if(IsEqualGUID(riid, &IID_IOleWindow)) {
        TRACE("(%p)->(IID_IOleWindow %p)\n", This, ppv);
        *ppv = &This->IOleInPlaceObjectWindowless_iface;
    }else if(IsEqualGUID(riid, &IID_IOleInPlaceObject)) {
        TRACE("(%p)->(IID_IOleInPlaceObject %p)\n", This, ppv);
        *ppv = &This->IOleInPlaceObjectWindowless_iface;
    }else if(IsEqualGUID(riid, &IID_IOleInPlaceObjectWindowless)) {
        TRACE("(%p)->(IID_IOleInPlaceObjectWindowless %p)\n", This, ppv);
        *ppv = &This->IOleInPlaceObjectWindowless_iface;
    }else if(IsEqualGUID(riid, &IID_IConnectionPointContainer)) {
        TRACE("(%p)->(IID_IConnectionPointContainer %p)\n", This, ppv);
        *ppv = &This->IConnectionPointContainer_iface;
    }else if(IsEqualGUID(riid, &IID_IWMPCore)) {
        TRACE("(%p)->(IID_IWMPCore %p)\n", This, ppv);
        *ppv = &This->IWMPPlayer4_iface;
    }else if(IsEqualGUID(riid, &IID_IWMPCore2)) {
        TRACE("(%p)->(IID_IWMPCore2 %p)\n", This, ppv);
        *ppv = &This->IWMPPlayer4_iface;
    }else if(IsEqualGUID(riid, &IID_IWMPCore3)) {
        TRACE("(%p)->(IID_IWMPCore3 %p)\n", This, ppv);
        *ppv = &This->IWMPPlayer4_iface;
    }else if(IsEqualGUID(riid, &IID_IWMPPlayer4)) {
        TRACE("(%p)->(IID_IWMPPlayer4 %p)\n", This, ppv);
        *ppv = &This->IWMPPlayer4_iface;
    }else if(IsEqualGUID(riid, &IID_IWMPSettings)) {
        TRACE("(%p)->(IID_IWMPSettings %p)\n", This, ppv);
        *ppv = &This->IWMPSettings_iface;
    }else if(IsEqualGUID(riid, &IID_IOleControl)) {
        TRACE("(%p)->(IID_IOleControl %p)\n", This, ppv);
        *ppv = &This->IOleControl_iface;
    }else if(IsEqualGUID(riid, &IID_IMarshal)) {
        TRACE("(%p)->(IID_IMarshal %p)\n", This, ppv);
        return E_NOINTERFACE;
    }else if(IsEqualGUID(riid, &IID_IQuickActivate)) {
        TRACE("(%p)->(IID_IQuickActivate %p)\n", This, ppv);
        return E_NOINTERFACE;
    }else {
        FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
        return E_NOINTERFACE;
    }

    IUnknown_AddRef((IUnknown*)*ppv);
    return S_OK;
}

static ULONG WINAPI OleObject_AddRef(IOleObject *iface)
{
    WindowsMediaPlayer *This = impl_from_IOleObject(iface);
    LONG ref = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    return ref;
}

static ULONG WINAPI OleObject_Release(IOleObject *iface)
{
    WindowsMediaPlayer *This = impl_from_IOleObject(iface);
    LONG ref = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref=%d\n", This, ref);

    if(!ref) {
        release_client_site(This);
        heap_free(This);
    }

    return ref;
}

static HRESULT WINAPI OleObject_SetClientSite(IOleObject *iface, IOleClientSite *pClientSite)
{
    WindowsMediaPlayer *This = impl_from_IOleObject(iface);
    IOleControlSite *control_site;
    HRESULT hres;

    TRACE("(%p)->(%p)\n", This, pClientSite);

    release_client_site(This);
    if(!pClientSite)
        return S_OK;

    IOleClientSite_AddRef(pClientSite);
    This->client_site = pClientSite;

    hres = IOleClientSite_QueryInterface(pClientSite, &IID_IOleControlSite, (void**)&control_site);
    if(SUCCEEDED(hres)) {
        IDispatch *disp;

        hres = IOleControlSite_GetExtendedControl(control_site, &disp);
        if(SUCCEEDED(hres) && disp) {
            FIXME("Use extended control\n");
            IDispatch_Release(disp);
        }

        IOleControlSite_Release(control_site);
    }

    return S_OK;
}

static HRESULT WINAPI OleObject_GetClientSite(IOleObject *iface, IOleClientSite **ppClientSite)
{
    WindowsMediaPlayer *This = impl_from_IOleObject(iface);

    TRACE("(%p)->(%p)\n", This, ppClientSite);

    *ppClientSite = This->client_site;
    return This->client_site ? S_OK : E_FAIL;
}

static HRESULT WINAPI OleObject_SetHostNames(IOleObject *iface, LPCOLESTR szContainerApp, LPCOLESTR szContainerObj)
{
    WindowsMediaPlayer *This = impl_from_IOleObject(iface);
    FIXME("(%p)->(%s %s)\n", This, debugstr_w(szContainerApp), debugstr_w(szContainerObj));
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_Close(IOleObject *iface, DWORD dwSaveOption)
{
    WindowsMediaPlayer *This = impl_from_IOleObject(iface);

    TRACE("(%p)->(%08x)\n", This, dwSaveOption);

    if(dwSaveOption)
        FIXME("Unsupported option %d\n", dwSaveOption);

    if(This->hwnd) /* FIXME: Possibly hide window */
        deactivate_window(This);
    return S_OK;
}

static HRESULT WINAPI OleObject_SetMoniker(IOleObject *iface, DWORD dwWhichMoniker, IMoniker *pmk)
{
    WindowsMediaPlayer *This = impl_from_IOleObject(iface);
    FIXME("(%p %d %p)->()\n", This, dwWhichMoniker, pmk);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_GetMoniker(IOleObject *iface, DWORD dwAssign, DWORD dwWhichMoniker, IMoniker **ppmk)
{
    WindowsMediaPlayer *This = impl_from_IOleObject(iface);
    FIXME("(%p)->(%d %d %p)\n", This, dwAssign, dwWhichMoniker, ppmk);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_InitFromData(IOleObject *iface, IDataObject *pDataObject, BOOL fCreation,
                                        DWORD dwReserved)
{
    WindowsMediaPlayer *This = impl_from_IOleObject(iface);
    FIXME("(%p)->(%p %x %d)\n", This, pDataObject, fCreation, dwReserved);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_GetClipboardData(IOleObject *iface, DWORD dwReserved, IDataObject **ppDataObject)
{
    WindowsMediaPlayer *This = impl_from_IOleObject(iface);
    FIXME("(%p)->(%d %p)\n", This, dwReserved, ppDataObject);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_DoVerb(IOleObject *iface, LONG iVerb, LPMSG lpmsg, IOleClientSite *pActiveSite,
                                        LONG lindex, HWND hwndParent, LPCRECT lprcPosRect)
{
    WindowsMediaPlayer *This = impl_from_IOleObject(iface);

    switch(iVerb) {
    case OLEIVERB_INPLACEACTIVATE:
        TRACE("(%p)->(OLEIVERB_INPLACEACTIVATE)\n", This);
        return activate_inplace(This);

    case OLEIVERB_HIDE:
        if(!This->hwnd) {
            FIXME("No window to hide\n");
            return E_UNEXPECTED;
        }

        ShowWindow(This->hwnd, SW_HIDE);
        return S_OK;

    default:
        FIXME("Unsupported iVerb %d\n", iVerb);
    }

    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_EnumVerbs(IOleObject *iface, IEnumOLEVERB **ppEnumOleVerb)
{
    WindowsMediaPlayer *This = impl_from_IOleObject(iface);
    FIXME("(%p)->(%p)\n", This, ppEnumOleVerb);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_Update(IOleObject *iface)
{
    WindowsMediaPlayer *This = impl_from_IOleObject(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_IsUpToDate(IOleObject *iface)
{
    WindowsMediaPlayer *This = impl_from_IOleObject(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_GetUserClassID(IOleObject *iface, CLSID *pClsid)
{
    WindowsMediaPlayer *This = impl_from_IOleObject(iface);
    FIXME("(%p)->(%p)\n", This, pClsid);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_GetUserType(IOleObject *iface, DWORD dwFormOfType, LPOLESTR *pszUserType)
{
    WindowsMediaPlayer *This = impl_from_IOleObject(iface);
    FIXME("(%p)->(%d %p)\n", This, dwFormOfType, pszUserType);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_SetExtent(IOleObject *iface, DWORD dwDrawAspect, SIZEL *psizel)
{
    WindowsMediaPlayer *This = impl_from_IOleObject(iface);

    TRACE("(%p)->(%d %p)\n", This, dwDrawAspect, psizel);

    if(dwDrawAspect != DVASPECT_CONTENT)
        return DV_E_DVASPECT;

    This->extent = *psizel;
    return S_OK;
}

static HRESULT WINAPI OleObject_GetExtent(IOleObject *iface, DWORD dwDrawAspect, SIZEL *psizel)
{
    WindowsMediaPlayer *This = impl_from_IOleObject(iface);

    TRACE("(%p)->(%d %p)\n", This, dwDrawAspect, psizel);

    if(dwDrawAspect != DVASPECT_CONTENT)
        return E_FAIL;

    *psizel = This->extent;
    return S_OK;
}

static HRESULT WINAPI OleObject_Advise(IOleObject *iface, IAdviseSink *pAdvSink, DWORD *pdwConnection)
{
    WindowsMediaPlayer *This = impl_from_IOleObject(iface);
    FIXME("(%p)->(%p %p)\n", This, pAdvSink, pdwConnection);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_Unadvise(IOleObject *iface, DWORD dwConnection)
{
    WindowsMediaPlayer *This = impl_from_IOleObject(iface);
    FIXME("(%p)->(%d)\n", This, dwConnection);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_EnumAdvise(IOleObject *iface, IEnumSTATDATA **ppenumAdvise)
{
    WindowsMediaPlayer *This = impl_from_IOleObject(iface);
    FIXME("(%p)->(%p)\n", This, ppenumAdvise);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleObject_GetMiscStatus(IOleObject *iface, DWORD dwAspect, DWORD *pdwStatus)
{
    WindowsMediaPlayer *This = impl_from_IOleObject(iface);

    TRACE("(%p)->(%d %p)\n", This, dwAspect, pdwStatus);

    switch(dwAspect) {
    case DVASPECT_CONTENT:
        *pdwStatus = OLEMISC_SETCLIENTSITEFIRST|OLEMISC_ACTIVATEWHENVISIBLE|OLEMISC_INSIDEOUT
            |OLEMISC_CANTLINKINSIDE|OLEMISC_RECOMPOSEONRESIZE;
        break;
    default:
        FIXME("Unhandled aspect %d\n", dwAspect);
        return E_NOTIMPL;
    }

    return S_OK;
}

static HRESULT WINAPI OleObject_SetColorScheme(IOleObject *iface, LOGPALETTE *pLogpal)
{
    WindowsMediaPlayer *This = impl_from_IOleObject(iface);
    FIXME("(%p)->(%p)\n", This, pLogpal);
    return E_NOTIMPL;
}

static const IOleObjectVtbl OleObjectVtbl = {
    OleObject_QueryInterface,
    OleObject_AddRef,
    OleObject_Release,
    OleObject_SetClientSite,
    OleObject_GetClientSite,
    OleObject_SetHostNames,
    OleObject_Close,
    OleObject_SetMoniker,
    OleObject_GetMoniker,
    OleObject_InitFromData,
    OleObject_GetClipboardData,
    OleObject_DoVerb,
    OleObject_EnumVerbs,
    OleObject_Update,
    OleObject_IsUpToDate,
    OleObject_GetUserClassID,
    OleObject_GetUserType,
    OleObject_SetExtent,
    OleObject_GetExtent,
    OleObject_Advise,
    OleObject_Unadvise,
    OleObject_EnumAdvise,
    OleObject_GetMiscStatus,
    OleObject_SetColorScheme
};

static inline WindowsMediaPlayer *impl_from_IOleInPlaceObjectWindowless(IOleInPlaceObjectWindowless *iface)
{
    return CONTAINING_RECORD(iface, WindowsMediaPlayer, IOleInPlaceObjectWindowless_iface);
}

static HRESULT WINAPI OleInPlaceObjectWindowless_QueryInterface(IOleInPlaceObjectWindowless *iface,
        REFIID riid, void **ppv)
{
    WindowsMediaPlayer *This = impl_from_IOleInPlaceObjectWindowless(iface);
    return IOleObject_QueryInterface(&This->IOleObject_iface, riid, ppv);
}

static ULONG WINAPI OleInPlaceObjectWindowless_AddRef(IOleInPlaceObjectWindowless *iface)
{
    WindowsMediaPlayer *This = impl_from_IOleInPlaceObjectWindowless(iface);
    return IOleObject_AddRef(&This->IOleObject_iface);
}

static ULONG WINAPI OleInPlaceObjectWindowless_Release(IOleInPlaceObjectWindowless *iface)
{
    WindowsMediaPlayer *This = impl_from_IOleInPlaceObjectWindowless(iface);
    return IOleObject_Release(&This->IOleObject_iface);
}

static HRESULT WINAPI OleInPlaceObjectWindowless_GetWindow(IOleInPlaceObjectWindowless *iface, HWND *phwnd)
{
    WindowsMediaPlayer *This = impl_from_IOleInPlaceObjectWindowless(iface);

    TRACE("(%p)->(%p)\n", This, phwnd);

    *phwnd = This->hwnd;
    return This->hwnd ? S_OK : E_UNEXPECTED;
}

static HRESULT WINAPI OleInPlaceObjectWindowless_ContextSensitiveHelp(IOleInPlaceObjectWindowless *iface,
        BOOL fEnterMode)
{
    WindowsMediaPlayer *This = impl_from_IOleInPlaceObjectWindowless(iface);
    FIXME("(%p)->(%x)\n", This, fEnterMode);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleInPlaceObjectWindowless_InPlaceDeactivate(IOleInPlaceObjectWindowless *iface)
{
    WindowsMediaPlayer *This = impl_from_IOleInPlaceObjectWindowless(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleInPlaceObjectWindowless_UIDeactivate(IOleInPlaceObjectWindowless *iface)
{
    WindowsMediaPlayer *This = impl_from_IOleInPlaceObjectWindowless(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleInPlaceObjectWindowless_SetObjectRects(IOleInPlaceObjectWindowless *iface,
        LPCRECT lprcPosRect, LPCRECT lprcClipRect)
{
    WindowsMediaPlayer *This = impl_from_IOleInPlaceObjectWindowless(iface);

    TRACE("(%p)->(%s %s)\n", This, wine_dbgstr_rect(lprcPosRect), wine_dbgstr_rect(lprcClipRect));

    if(This->hwnd) {
       SetWindowPos(This->hwnd, NULL, lprcPosRect->left, lprcPosRect->top,
               lprcPosRect->right-lprcPosRect->left, lprcPosRect->bottom-lprcPosRect->top,
               SWP_NOZORDER | SWP_NOACTIVATE);
    }

    return S_OK;
}

static HRESULT WINAPI OleInPlaceObjectWindowless_ReactivateAndUndo(IOleInPlaceObjectWindowless *iface)
{
    WindowsMediaPlayer *This = impl_from_IOleInPlaceObjectWindowless(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleInPlaceObjectWindowless_OnWindowMessage(IOleInPlaceObjectWindowless *iface,
        UINT msg, WPARAM wParam, LPARAM lParam, LRESULT *lpResult)
{
    WindowsMediaPlayer *This = impl_from_IOleInPlaceObjectWindowless(iface);
    FIXME("(%p)->(%u %lu %lu %p)\n", This, msg, wParam, lParam, lpResult);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleInPlaceObjectWindowless_GetDropTarget(IOleInPlaceObjectWindowless *iface,
        IDropTarget **ppDropTarget)
{
    WindowsMediaPlayer *This = impl_from_IOleInPlaceObjectWindowless(iface);
    FIXME("(%p)->(%p)\n", This, ppDropTarget);
    return E_NOTIMPL;
}

static const IOleInPlaceObjectWindowlessVtbl OleInPlaceObjectWindowlessVtbl = {
    OleInPlaceObjectWindowless_QueryInterface,
    OleInPlaceObjectWindowless_AddRef,
    OleInPlaceObjectWindowless_Release,
    OleInPlaceObjectWindowless_GetWindow,
    OleInPlaceObjectWindowless_ContextSensitiveHelp,
    OleInPlaceObjectWindowless_InPlaceDeactivate,
    OleInPlaceObjectWindowless_UIDeactivate,
    OleInPlaceObjectWindowless_SetObjectRects,
    OleInPlaceObjectWindowless_ReactivateAndUndo,
    OleInPlaceObjectWindowless_OnWindowMessage,
    OleInPlaceObjectWindowless_GetDropTarget
};

static inline WindowsMediaPlayer *impl_from_IOleControl(IOleControl *iface)
{
    return CONTAINING_RECORD(iface, WindowsMediaPlayer, IOleControl_iface);
}

static HRESULT WINAPI OleControl_QueryInterface(IOleControl *iface, REFIID riid, void **ppv)
{
    WindowsMediaPlayer *This = impl_from_IOleControl(iface);
    return IOleObject_QueryInterface(&This->IOleObject_iface, riid, ppv);
}

static ULONG WINAPI OleControl_AddRef(IOleControl *iface)
{
    WindowsMediaPlayer *This = impl_from_IOleControl(iface);
    return IOleObject_AddRef(&This->IOleObject_iface);
}

static ULONG WINAPI OleControl_Release(IOleControl *iface)
{
    WindowsMediaPlayer *This = impl_from_IOleControl(iface);
    return IOleObject_Release(&This->IOleObject_iface);
}

static HRESULT WINAPI OleControl_GetControlInfo(IOleControl *iface, CONTROLINFO *pCI)
{
    WindowsMediaPlayer *This = impl_from_IOleControl(iface);
    FIXME("(%p)->(%p)\n", This, pCI);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleControl_OnMnemonic(IOleControl *iface, MSG *msg)
{
    WindowsMediaPlayer *This = impl_from_IOleControl(iface);
    FIXME("(%p)->(%p)\n", This, msg);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleControl_OnAmbientPropertyChange(IOleControl *iface, DISPID dispID)
{
    WindowsMediaPlayer *This = impl_from_IOleControl(iface);
    FIXME("(%p)->(%d)\n", This, dispID);
    return E_NOTIMPL;
}

static HRESULT WINAPI OleControl_FreezeEvents(IOleControl *iface, BOOL freeze)
{
    WindowsMediaPlayer *This = impl_from_IOleControl(iface);
    FIXME("(%p)->(%x)\n", This, freeze);
    return E_NOTIMPL;
}

static const IOleControlVtbl OleControlVtbl = {
    OleControl_QueryInterface,
    OleControl_AddRef,
    OleControl_Release,
    OleControl_GetControlInfo,
    OleControl_OnMnemonic,
    OleControl_OnAmbientPropertyChange,
    OleControl_FreezeEvents
};

static inline WindowsMediaPlayer *impl_from_IProvideClassInfo2(IProvideClassInfo2 *iface)
{
    return CONTAINING_RECORD(iface, WindowsMediaPlayer, IProvideClassInfo2_iface);
}

static HRESULT WINAPI ProvideClassInfo2_QueryInterface(IProvideClassInfo2 *iface, REFIID riid, void **ppv)
{
    WindowsMediaPlayer *This = impl_from_IProvideClassInfo2(iface);
    return IOleObject_QueryInterface(&This->IOleObject_iface, riid, ppv);
}

static ULONG WINAPI ProvideClassInfo2_AddRef(IProvideClassInfo2 *iface)
{
    WindowsMediaPlayer *This = impl_from_IProvideClassInfo2(iface);
    return IOleObject_AddRef(&This->IOleObject_iface);
}

static ULONG WINAPI ProvideClassInfo2_Release(IProvideClassInfo2 *iface)
{
    WindowsMediaPlayer *This = impl_from_IProvideClassInfo2(iface);
    return IOleObject_Release(&This->IOleObject_iface);
}

static HRESULT WINAPI ProvideClassInfo2_GetClassInfo(IProvideClassInfo2 *iface, ITypeInfo **ppTI)
{
    WindowsMediaPlayer *This = impl_from_IProvideClassInfo2(iface);
    FIXME("(%p)->(%p)\n", This, ppTI);
    return E_NOTIMPL;
}

static HRESULT WINAPI ProvideClassInfo2_GetGUID(IProvideClassInfo2 *iface, DWORD dwGuidKind, GUID *pGUID)
{
    WindowsMediaPlayer *This = impl_from_IProvideClassInfo2(iface);

    TRACE("(%p)->(%d %p)\n", This, dwGuidKind, pGUID);

    if(dwGuidKind != GUIDKIND_DEFAULT_SOURCE_DISP_IID) {
        FIXME("Unexpected dwGuidKind %d\n", dwGuidKind);
        return E_INVALIDARG;
    }

    *pGUID = IID__WMPOCXEvents;
    return S_OK;
}

static const IProvideClassInfo2Vtbl ProvideClassInfo2Vtbl = {
    ProvideClassInfo2_QueryInterface,
    ProvideClassInfo2_AddRef,
    ProvideClassInfo2_Release,
    ProvideClassInfo2_GetClassInfo,
    ProvideClassInfo2_GetGUID
};

static inline WindowsMediaPlayer *impl_from_IPersistStreamInit(IPersistStreamInit *iface)
{
    return CONTAINING_RECORD(iface, WindowsMediaPlayer, IPersistStreamInit_iface);
}

static HRESULT WINAPI PersistStreamInit_QueryInterface(IPersistStreamInit *iface,
                                                       REFIID riid, void **ppv)
{
    WindowsMediaPlayer *This = impl_from_IPersistStreamInit(iface);
    return IOleObject_QueryInterface(&This->IOleObject_iface, riid, ppv);
}

static ULONG WINAPI PersistStreamInit_AddRef(IPersistStreamInit *iface)
{
    WindowsMediaPlayer *This = impl_from_IPersistStreamInit(iface);
    return IOleObject_AddRef(&This->IOleObject_iface);
}

static ULONG WINAPI PersistStreamInit_Release(IPersistStreamInit *iface)
{
    WindowsMediaPlayer *This = impl_from_IPersistStreamInit(iface);
    return IOleObject_Release(&This->IOleObject_iface);
}

static HRESULT WINAPI PersistStreamInit_GetClassID(IPersistStreamInit *iface, CLSID *pClassID)
{
    WindowsMediaPlayer *This = impl_from_IPersistStreamInit(iface);
    FIXME("(%p)->(%p)\n", This, pClassID);
    return E_NOTIMPL;
}

static HRESULT WINAPI PersistStreamInit_IsDirty(IPersistStreamInit *iface)
{
    WindowsMediaPlayer *This = impl_from_IPersistStreamInit(iface);
    FIXME("(%p)\n", This);
    return E_NOTIMPL;
}

static HRESULT WINAPI PersistStreamInit_Load(IPersistStreamInit *iface, LPSTREAM pStm)
{
    WindowsMediaPlayer *This = impl_from_IPersistStreamInit(iface);
    FIXME("(%p)->(%p)\n", This, pStm);
    return E_NOTIMPL;
}

static HRESULT WINAPI PersistStreamInit_Save(IPersistStreamInit *iface, LPSTREAM pStm,
                                             BOOL fClearDirty)
{
    WindowsMediaPlayer *This = impl_from_IPersistStreamInit(iface);
    FIXME("(%p)->(%p %x)\n", This, pStm, fClearDirty);
    return E_NOTIMPL;
}

static HRESULT WINAPI PersistStreamInit_GetSizeMax(IPersistStreamInit *iface,
                                                   ULARGE_INTEGER *pcbSize)
{
    WindowsMediaPlayer *This = impl_from_IPersistStreamInit(iface);
    FIXME("(%p)->(%p)\n", This, pcbSize);
    return E_NOTIMPL;
}

static HRESULT WINAPI PersistStreamInit_InitNew(IPersistStreamInit *iface)
{
    WindowsMediaPlayer *This = impl_from_IPersistStreamInit(iface);

    TRACE("(%p)\n", This);

    if(!This->client_site)
        return E_FAIL;

    /* Nothing to do, yet. */
    get_container_hwnd(This);
    return S_OK;
}

static const IPersistStreamInitVtbl PersistStreamInitVtbl = {
    PersistStreamInit_QueryInterface,
    PersistStreamInit_AddRef,
    PersistStreamInit_Release,
    PersistStreamInit_GetClassID,
    PersistStreamInit_IsDirty,
    PersistStreamInit_Load,
    PersistStreamInit_Save,
    PersistStreamInit_GetSizeMax,
    PersistStreamInit_InitNew
};

static inline WindowsMediaPlayer *impl_from_IConnectionPointContainer(IConnectionPointContainer *iface)
{
    return CONTAINING_RECORD(iface, WindowsMediaPlayer, IConnectionPointContainer_iface);
}

static HRESULT WINAPI ConnectionPointContainer_QueryInterface(IConnectionPointContainer *iface,
        REFIID riid, LPVOID *ppv)
{
    WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface);
    return IOleObject_QueryInterface(&This->IOleObject_iface, riid, ppv);
}

static ULONG WINAPI ConnectionPointContainer_AddRef(IConnectionPointContainer *iface)
{
    WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface);
    return IOleObject_AddRef(&This->IOleObject_iface);
}

static ULONG WINAPI ConnectionPointContainer_Release(IConnectionPointContainer *iface)
{
    WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface);
    return IOleObject_Release(&This->IOleObject_iface);
}

static HRESULT WINAPI ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer *iface,
        IEnumConnectionPoints **ppEnum)
{
    WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface);
    FIXME("(%p)->(%p)\n", This, ppEnum);
    return E_NOTIMPL;
}

static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer *iface,
        REFIID riid, IConnectionPoint **ppCP)
{
    WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface);
    FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppCP);
    return CONNECT_E_NOCONNECTION;
}

static const IConnectionPointContainerVtbl ConnectionPointContainerVtbl =
{
    ConnectionPointContainer_QueryInterface,
    ConnectionPointContainer_AddRef,
    ConnectionPointContainer_Release,
    ConnectionPointContainer_EnumConnectionPoints,
    ConnectionPointContainer_FindConnectionPoint
};

HRESULT WINAPI WMPFactory_CreateInstance(IClassFactory *iface, IUnknown *outer,
        REFIID riid, void **ppv)
{
    WindowsMediaPlayer *wmp;
    DWORD dpi_x, dpi_y;
    HDC hdc;
    HRESULT hres;

    TRACE("(%p %s %p)\n", outer, debugstr_guid(riid), ppv);

    wmp = heap_alloc_zero(sizeof(*wmp));
    if(!wmp)
        return E_OUTOFMEMORY;

    wmp->IOleObject_iface.lpVtbl = &OleObjectVtbl;
    wmp->IProvideClassInfo2_iface.lpVtbl = &ProvideClassInfo2Vtbl;
    wmp->IPersistStreamInit_iface.lpVtbl = &PersistStreamInitVtbl;
    wmp->IOleInPlaceObjectWindowless_iface.lpVtbl = &OleInPlaceObjectWindowlessVtbl;
    wmp->IConnectionPointContainer_iface.lpVtbl = &ConnectionPointContainerVtbl;
    wmp->IOleControl_iface.lpVtbl = &OleControlVtbl;

    wmp->ref = 1;

    init_player_ifaces(wmp);

    hdc = GetDC(0);
    dpi_x = GetDeviceCaps(hdc, LOGPIXELSX);
    dpi_y = GetDeviceCaps(hdc, LOGPIXELSY);
    ReleaseDC(0, hdc);

    wmp->extent.cx = MulDiv(192, 2540, dpi_x);
    wmp->extent.cy = MulDiv(192, 2540, dpi_y);

    hres = IOleObject_QueryInterface(&wmp->IOleObject_iface, riid, ppv);
    IOleObject_Release(&wmp->IOleObject_iface);
    return hres;
}
