/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.
*/
#include "../../SDL_internal.h"

#if SDL_VIDEO_DRIVER_WINRT

/* Windows includes */
#include <roapi.h>
#include <windows.foundation.h>
#include <EventToken.h>


/* SDL includes */
extern "C" {
#include "SDL_mouse.h"
#include "../SDL_sysvideo.h"
}
#include "SDL_winrtvideo_cpp.h"


/* Game Bar events can come in off the main thread.  Use the following
   WinRT CoreDispatcher to deal with them on SDL's thread.
*/
static Platform::WeakReference WINRT_MainThreadDispatcher;


/* Win10's initial SDK (the 10.0.10240.0 release) does not include references
   to Game Bar APIs, as the Game Bar was released via Win10 10.0.10586.0.

   Declare its WinRT/COM interface here, to allow compilation with earlier
   Windows SDKs.
*/
MIDL_INTERFACE("1DB9A292-CC78-4173-BE45-B61E67283EA7")
IGameBarStatics_ : public IInspectable
{
public:
    virtual HRESULT STDMETHODCALLTYPE add_VisibilityChanged( 
        __FIEventHandler_1_IInspectable *handler,
        Windows::Foundation::EventRegistrationToken *token) = 0;
    
    virtual HRESULT STDMETHODCALLTYPE remove_VisibilityChanged( 
        Windows::Foundation::EventRegistrationToken token) = 0;
    
    virtual HRESULT STDMETHODCALLTYPE add_IsInputRedirectedChanged( 
        __FIEventHandler_1_IInspectable *handler,
        Windows::Foundation::EventRegistrationToken *token) = 0;
    
    virtual HRESULT STDMETHODCALLTYPE remove_IsInputRedirectedChanged( 
        Windows::Foundation::EventRegistrationToken token) = 0;
    
    virtual HRESULT STDMETHODCALLTYPE get_Visible( 
        boolean *value) = 0;
    
    virtual HRESULT STDMETHODCALLTYPE get_IsInputRedirected( 
        boolean *value) = 0;
};

/* Declare the game bar's COM GUID */
static GUID IID_IGameBarStatics_ = { MAKELONG(0xA292, 0x1DB9), 0xCC78, 0x4173, { 0xBE, 0x45, 0xB6, 0x1E, 0x67, 0x28, 0x3E, 0xA7 } };

/* Retrieves a pointer to the game bar, or NULL if it is not available.
   If a pointer is returned, it's ->Release() method must be called
   after the caller has finished using it.
*/
static IGameBarStatics_ *
WINRT_GetGameBar()
{
    wchar_t *wClassName = L"Windows.Gaming.UI.GameBar";
    HSTRING hClassName;
    IActivationFactory *pActivationFactory = NULL;
    IGameBarStatics_ *pGameBar = NULL;
    HRESULT hr;

    hr = ::WindowsCreateString(wClassName, (UINT32)wcslen(wClassName), &hClassName);
    if (FAILED(hr)) {
        goto done;
    }

    hr = Windows::Foundation::GetActivationFactory(hClassName, &pActivationFactory);
    if (FAILED(hr)) {
        goto done;
    }

    pActivationFactory->QueryInterface(IID_IGameBarStatics_, (void **) &pGameBar);

done:
    if (pActivationFactory) {
        pActivationFactory->Release();
    }
    if (hClassName) {
        ::WindowsDeleteString(hClassName);
    }
    return pGameBar;
}

static void
WINRT_HandleGameBarIsInputRedirected_MainThread()
{
    IGameBarStatics_ *gameBar;
    boolean isInputRedirected = 0;
    if (!WINRT_MainThreadDispatcher) {
        /* The game bar event handler has been deregistered! */
        return;
    }
    gameBar = WINRT_GetGameBar();
    if (!gameBar) {
        /* Shouldn't happen, but just in case... */
        return;
    }
    if (SUCCEEDED(gameBar->get_IsInputRedirected(&isInputRedirected))) {
        if ( ! isInputRedirected) {
            /* Input-control is now back to the SDL app. Restore the cursor,
               in case Windows does not (it does not in either Win10
               10.0.10240.0 or 10.0.10586.0, maybe later version(s) too.
            */
            SDL_Cursor *cursor = SDL_GetCursor();
            SDL_SetCursor(cursor);
        }
    }
    gameBar->Release();
}

static void
WINRT_HandleGameBarIsInputRedirected_NonMainThread(Platform::Object ^ o1, Platform::Object ^o2)
{
    Windows::UI::Core::CoreDispatcher ^dispatcher = WINRT_MainThreadDispatcher.Resolve<Windows::UI::Core::CoreDispatcher>();
    if (dispatcher) {
        dispatcher->RunAsync(
            Windows::UI::Core::CoreDispatcherPriority::Normal,
            ref new Windows::UI::Core::DispatchedHandler(&WINRT_HandleGameBarIsInputRedirected_MainThread));
    }
}

void
WINRT_InitGameBar(_THIS)
{
    SDL_VideoData *driverdata = (SDL_VideoData *)_this->driverdata;
    IGameBarStatics_ *gameBar = WINRT_GetGameBar();
    if (gameBar) {
        /* GameBar.IsInputRedirected events can come in via something other than
           the main/SDL thread.

           Get a WinRT 'CoreDispatcher' that can be used to call back into the
           SDL thread.
        */
        WINRT_MainThreadDispatcher = Windows::UI::Core::CoreWindow::GetForCurrentThread()->Dispatcher;
        Windows::Foundation::EventHandler<Platform::Object ^> ^handler = \
            ref new Windows::Foundation::EventHandler<Platform::Object ^>(&WINRT_HandleGameBarIsInputRedirected_NonMainThread);
        __FIEventHandler_1_IInspectable * pHandler = reinterpret_cast<__FIEventHandler_1_IInspectable *>(handler);
        gameBar->add_IsInputRedirectedChanged(pHandler, &driverdata->gameBarIsInputRedirectedToken);
        gameBar->Release();
    }
}

void
WINRT_QuitGameBar(_THIS)
{
    SDL_VideoData *driverdata;
    IGameBarStatics_ *gameBar;
    if (!_this || !_this->driverdata) {
        return;
    }
    gameBar = WINRT_GetGameBar();
    if (!gameBar) {
        return;
    }
    driverdata = (SDL_VideoData *)_this->driverdata;
    if (driverdata->gameBarIsInputRedirectedToken.Value) {
        gameBar->remove_IsInputRedirectedChanged(driverdata->gameBarIsInputRedirectedToken);
        driverdata->gameBarIsInputRedirectedToken.Value = 0;
    }
    WINRT_MainThreadDispatcher = nullptr;
    gameBar->Release();
}

#endif /* SDL_VIDEO_DRIVER_WINRT */

/* vi: set ts=4 sw=4 expandtab: */
