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

    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 {
        FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
        *ppv = NULL;
        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);
    FIXME("(%p)->(%d %p)\n", This, dwDrawAspect, psizel);
    return E_NOTIMPL;
}

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

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

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