/*
  Simple DirectMedia Layer
  Copyright (C) 1997-2020 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"

/* Standard C++11 includes */
#include <functional>
#include <string>
#include <sstream>
using namespace std;


/* Windows includes */
#include "ppltasks.h"
using namespace concurrency;
using namespace Windows::ApplicationModel;
using namespace Windows::ApplicationModel::Core;
using namespace Windows::ApplicationModel::Activation;
using namespace Windows::Devices::Input;
using namespace Windows::Graphics::Display;
using namespace Windows::Foundation;
using namespace Windows::System;
using namespace Windows::UI::Core;
using namespace Windows::UI::Input;

#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
using namespace Windows::Phone::UI::Input;
#endif


/* SDL includes */
extern "C" {
#include "SDL_assert.h"
#include "SDL_events.h"
#include "SDL_hints.h"
#include "SDL_main.h"
#include "SDL_stdinc.h"
#include "SDL_render.h"
#include "../../video/SDL_sysvideo.h"
//#include "../../SDL_hints_c.h"
#include "../../events/SDL_events_c.h"
#include "../../events/SDL_keyboard_c.h"
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_windowevents_c.h"
#include "../../render/SDL_sysrender.h"
#include "../windows/SDL_windows.h"
}

#include "../../video/winrt/SDL_winrtevents_c.h"
#include "../../video/winrt/SDL_winrtvideo_cpp.h"
#include "SDL_winrtapp_common.h"
#include "SDL_winrtapp_direct3d.h"

#if SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED
/* Calling IDXGIDevice3::Trim on the active Direct3D 11.x device is necessary
 * when Windows 8.1 apps are about to get suspended.
 */
extern "C" void D3D11_Trim(SDL_Renderer *);
#endif


// Compile-time debugging options:
// To enable, uncomment; to disable, comment them out.
//#define LOG_POINTER_EVENTS 1
//#define LOG_WINDOW_EVENTS 1
//#define LOG_ORIENTATION_EVENTS 1


// HACK, DLudwig: record a reference to the global, WinRT 'app'/view.
// SDL/WinRT will use this throughout its code.
//
// TODO, WinRT: consider replacing SDL_WinRTGlobalApp with something
// non-global, such as something created inside
// SDL_InitSubSystem(SDL_INIT_VIDEO), or something inside
// SDL_CreateWindow().
SDL_WinRTApp ^ SDL_WinRTGlobalApp = nullptr;

ref class SDLApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource
{
public:
    virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView();
};

IFrameworkView^ SDLApplicationSource::CreateView()
{
    // TODO, WinRT: see if this function (CreateView) can ever get called
    // more than once.  For now, just prevent it from ever assigning
    // SDL_WinRTGlobalApp more than once.
    SDL_assert(!SDL_WinRTGlobalApp);
    SDL_WinRTApp ^ app = ref new SDL_WinRTApp();
    if (!SDL_WinRTGlobalApp)
    {
        SDL_WinRTGlobalApp = app;
    }
    return app;
}

int SDL_WinRTInitNonXAMLApp(int (*mainFunction)(int, char **))
{
    WINRT_SDLAppEntryPoint = mainFunction;
    auto direct3DApplicationSource = ref new SDLApplicationSource();
    CoreApplication::Run(direct3DApplicationSource);
    return 0;
}

static void SDLCALL
WINRT_SetDisplayOrientationsPreference(void *userdata, const char *name, const char *oldValue, const char *newValue)
{
    SDL_assert(SDL_strcmp(name, SDL_HINT_ORIENTATIONS) == 0);

    /* HACK: prevent SDL from altering an app's .appxmanifest-set orientation
     * from being changed on startup, by detecting when SDL_HINT_ORIENTATIONS
     * is getting registered.
     *
     * TODO, WinRT: consider reading in an app's .appxmanifest file, and apply its orientation when 'newValue == NULL'.
     */
    if ((oldValue == NULL) && (newValue == NULL)) {
        return;
    }

    // Start with no orientation flags, then add each in as they're parsed
    // from newValue.
    unsigned int orientationFlags = 0;
    if (newValue) {
        std::istringstream tokenizer(newValue);
        while (!tokenizer.eof()) {
            std::string orientationName;
            std::getline(tokenizer, orientationName, ' ');
            if (orientationName == "LandscapeLeft") {
                orientationFlags |= (unsigned int) DisplayOrientations::LandscapeFlipped;
            } else if (orientationName == "LandscapeRight") {
                orientationFlags |= (unsigned int) DisplayOrientations::Landscape;
            } else if (orientationName == "Portrait") {
                orientationFlags |= (unsigned int) DisplayOrientations::Portrait;
            } else if (orientationName == "PortraitUpsideDown") {
                orientationFlags |= (unsigned int) DisplayOrientations::PortraitFlipped;
            }
        }
    }

    // If no valid orientation flags were specified, use a reasonable set of defaults:
    if (!orientationFlags) {
        // TODO, WinRT: consider seeing if an app's default orientation flags can be found out via some API call(s).
        orientationFlags = (unsigned int) ( \
            DisplayOrientations::Landscape |
            DisplayOrientations::LandscapeFlipped |
            DisplayOrientations::Portrait |
            DisplayOrientations::PortraitFlipped);
    }

    // Set the orientation/rotation preferences.  Please note that this does
    // not constitute a 100%-certain lock of a given set of possible
    // orientations.  According to Microsoft's documentation on WinRT [1]
    // when a device is not capable of being rotated, Windows may ignore
    // the orientation preferences, and stick to what the device is capable of
    // displaying.
    //
    // [1] Documentation on the 'InitialRotationPreference' setting for a
    // Windows app's manifest file describes how some orientation/rotation
    // preferences may be ignored.  See
    // http://msdn.microsoft.com/en-us/library/windows/apps/hh700343.aspx
    // for details.  Microsoft's "Display orientation sample" also gives an
    // outline of how Windows treats device rotation
    // (http://code.msdn.microsoft.com/Display-Orientation-Sample-19a58e93).
    WINRT_DISPLAY_PROPERTY(AutoRotationPreferences) = (DisplayOrientations) orientationFlags;
}

static void
WINRT_ProcessWindowSizeChange() // TODO: Pass an SDL_Window-identifying thing into WINRT_ProcessWindowSizeChange()
{
    CoreWindow ^ coreWindow = CoreWindow::GetForCurrentThread();
    if (coreWindow) {
        if (WINRT_GlobalSDLWindow) {
            SDL_Window * window = WINRT_GlobalSDLWindow;
            SDL_WindowData * data = (SDL_WindowData *) window->driverdata;

            int x = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Left);
            int y = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Top);
            int w = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Width);
            int h = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Height);

#if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) && (NTDDI_VERSION == NTDDI_WIN8)
            /* WinPhone 8.0 always keeps its native window size in portrait,
               regardless of orientation.  This changes in WinPhone 8.1,
               in which the native window's size changes along with
               orientation.

               Attempt to emulate WinPhone 8.1's behavior on WinPhone 8.0, with
               regards to window size.  This fixes a rendering bug that occurs
               when a WinPhone 8.0 app is rotated to either 90 or 270 degrees.
            */
            const DisplayOrientations currentOrientation = WINRT_DISPLAY_PROPERTY(CurrentOrientation);
            switch (currentOrientation) {
                case DisplayOrientations::Landscape:
                case DisplayOrientations::LandscapeFlipped: {
                    int tmp = w;
                    w = h;
                    h = tmp;
                } break;
            }
#endif

            const Uint32 latestFlags = WINRT_DetectWindowFlags(window);
            if (latestFlags & SDL_WINDOW_MAXIMIZED) {
                SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MAXIMIZED, 0, 0);
            } else {
                SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESTORED, 0, 0);
            }

            WINRT_UpdateWindowFlags(window, SDL_WINDOW_FULLSCREEN_DESKTOP);

            /* The window can move during a resize event, such as when maximizing
               or resizing from a corner */
            SDL_SendWindowEvent(window, SDL_WINDOWEVENT_MOVED, x, y);
            SDL_SendWindowEvent(window, SDL_WINDOWEVENT_RESIZED, w, h);
        }
    }
}

SDL_WinRTApp::SDL_WinRTApp() :
    m_windowClosed(false),
    m_windowVisible(true)
{
}

void SDL_WinRTApp::Initialize(CoreApplicationView^ applicationView)
{
    applicationView->Activated +=
        ref new TypedEventHandler<CoreApplicationView^, IActivatedEventArgs^>(this, &SDL_WinRTApp::OnAppActivated);

    CoreApplication::Suspending +=
        ref new EventHandler<SuspendingEventArgs^>(this, &SDL_WinRTApp::OnSuspending);

    CoreApplication::Resuming +=
        ref new EventHandler<Platform::Object^>(this, &SDL_WinRTApp::OnResuming);

    CoreApplication::Exiting +=
        ref new EventHandler<Platform::Object^>(this, &SDL_WinRTApp::OnExiting);

#if NTDDI_VERSION >= NTDDI_WIN10
    /* HACK ALERT!  Xbox One doesn't seem to detect gamepads unless something
       gets registered to receive Win10's Windows.Gaming.Input.Gamepad.GamepadAdded
       events.  We'll register an event handler for these events here, to make
       sure that gamepad detection works later on, if requested.
    */
    Windows::Gaming::Input::Gamepad::GamepadAdded +=
        ref new Windows::Foundation::EventHandler<Windows::Gaming::Input::Gamepad^>(
            this, &SDL_WinRTApp::OnGamepadAdded
        );
#endif
}

#if NTDDI_VERSION > NTDDI_WIN8
void SDL_WinRTApp::OnOrientationChanged(DisplayInformation^ sender, Object^ args)
#else
void SDL_WinRTApp::OnOrientationChanged(Object^ sender)
#endif
{
#if LOG_ORIENTATION_EVENTS==1
    {
        CoreWindow^ window = CoreWindow::GetForCurrentThread();
        if (window) {
            SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d, CoreWindow Bounds={%f,%f,%f,%f}\n",
                __FUNCTION__,
                WINRT_DISPLAY_PROPERTY(CurrentOrientation),
                WINRT_DISPLAY_PROPERTY(NativeOrientation),
                WINRT_DISPLAY_PROPERTY(AutoRotationPreferences),
                window->Bounds.X,
                window->Bounds.Y,
                window->Bounds.Width,
                window->Bounds.Height);
        } else {
            SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d\n",
                __FUNCTION__,
                WINRT_DISPLAY_PROPERTY(CurrentOrientation),
                WINRT_DISPLAY_PROPERTY(NativeOrientation),
                WINRT_DISPLAY_PROPERTY(AutoRotationPreferences));
        }
    }
#endif

    WINRT_ProcessWindowSizeChange();

#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
    // HACK: Make sure that orientation changes
    // lead to the Direct3D renderer's viewport getting updated:
    //
    // For some reason, this doesn't seem to need to be done on Windows 8.x,
    // even when going from Landscape to LandscapeFlipped.  It only seems to
    // be needed on Windows Phone, at least when I tested on my devices.
    // I'm not currently sure why this is, but it seems to work fine. -- David L.
    //
    // TODO, WinRT: do more extensive research into why orientation changes on Win 8.x don't need D3D changes, or if they might, in some cases
    SDL_Window * window = WINRT_GlobalSDLWindow;
    if (window) {
        SDL_WindowData * data = (SDL_WindowData *)window->driverdata;
        int w = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Width);
        int h = WINRT_DIPS_TO_PHYSICAL_PIXELS(data->coreWindow->Bounds.Height);
        SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_SIZE_CHANGED, w, h);
    }
#endif

}

void SDL_WinRTApp::SetWindow(CoreWindow^ window)
{
#if LOG_WINDOW_EVENTS==1
    SDL_Log("%s, current orientation=%d, native orientation=%d, auto rot. pref=%d, window bounds={%f, %f, %f,%f}\n",
        __FUNCTION__,
        WINRT_DISPLAY_PROPERTY(CurrentOrientation),
        WINRT_DISPLAY_PROPERTY(NativeOrientation),
        WINRT_DISPLAY_PROPERTY(AutoRotationPreferences),
        window->Bounds.X,
        window->Bounds.Y,
        window->Bounds.Width,
        window->Bounds.Height);
#endif

    window->SizeChanged += 
        ref new TypedEventHandler<CoreWindow^, WindowSizeChangedEventArgs^>(this, &SDL_WinRTApp::OnWindowSizeChanged);

    window->VisibilityChanged +=
        ref new TypedEventHandler<CoreWindow^, VisibilityChangedEventArgs^>(this, &SDL_WinRTApp::OnVisibilityChanged);

    window->Activated +=
        ref new TypedEventHandler<CoreWindow^, WindowActivatedEventArgs^>(this, &SDL_WinRTApp::OnWindowActivated);

    window->Closed += 
        ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &SDL_WinRTApp::OnWindowClosed);

#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
    window->PointerCursor = ref new CoreCursor(CoreCursorType::Arrow, 0);
#endif

    window->PointerPressed +=
        ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerPressed);

    window->PointerMoved +=
        ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerMoved);

    window->PointerReleased +=
        ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerReleased);

    window->PointerEntered +=
        ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerEntered);

    window->PointerExited +=
        ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerExited);

    window->PointerWheelChanged +=
        ref new TypedEventHandler<CoreWindow^, PointerEventArgs^>(this, &SDL_WinRTApp::OnPointerWheelChanged);

#if WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP
    // Retrieves relative-only mouse movements:
    Windows::Devices::Input::MouseDevice::GetForCurrentView()->MouseMoved +=
        ref new TypedEventHandler<MouseDevice^, MouseEventArgs^>(this, &SDL_WinRTApp::OnMouseMoved);
#endif

    window->KeyDown +=
        ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &SDL_WinRTApp::OnKeyDown);

    window->KeyUp +=
        ref new TypedEventHandler<CoreWindow^, KeyEventArgs^>(this, &SDL_WinRTApp::OnKeyUp);

    window->CharacterReceived +=
        ref new TypedEventHandler<CoreWindow^, CharacterReceivedEventArgs^>(this, &SDL_WinRTApp::OnCharacterReceived);

#if NTDDI_VERSION >= NTDDI_WIN10
    Windows::UI::Core::SystemNavigationManager::GetForCurrentView()->BackRequested +=
        ref new EventHandler<BackRequestedEventArgs^>(this, &SDL_WinRTApp::OnBackButtonPressed);
#elif WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
    HardwareButtons::BackPressed +=
        ref new EventHandler<BackPressedEventArgs^>(this, &SDL_WinRTApp::OnBackButtonPressed);
#endif

#if NTDDI_VERSION > NTDDI_WIN8
    DisplayInformation::GetForCurrentView()->OrientationChanged +=
        ref new TypedEventHandler<Windows::Graphics::Display::DisplayInformation^, Object^>(this, &SDL_WinRTApp::OnOrientationChanged);
#else
    DisplayProperties::OrientationChanged +=
        ref new DisplayPropertiesEventHandler(this, &SDL_WinRTApp::OnOrientationChanged);
#endif

    // Register the hint, SDL_HINT_ORIENTATIONS, with SDL.
    // TODO, WinRT: see if an app's default orientation can be found out via WinRT API(s), then set the initial value of SDL_HINT_ORIENTATIONS accordingly.
    SDL_AddHintCallback(SDL_HINT_ORIENTATIONS, WINRT_SetDisplayOrientationsPreference, NULL);

#if (WINAPI_FAMILY == WINAPI_FAMILY_APP) && (NTDDI_VERSION < NTDDI_WIN10)  // for Windows 8/8.1/RT apps... (and not Phone apps)
    // Make sure we know when a user has opened the app's settings pane.
    // This is needed in order to display a privacy policy, which needs
    // to be done for network-enabled apps, as per Windows Store requirements.
    using namespace Windows::UI::ApplicationSettings;
    SettingsPane::GetForCurrentView()->CommandsRequested +=
        ref new TypedEventHandler<SettingsPane^, SettingsPaneCommandsRequestedEventArgs^>
            (this, &SDL_WinRTApp::OnSettingsPaneCommandsRequested);
#endif
}

void SDL_WinRTApp::Load(Platform::String^ entryPoint)
{
}

void SDL_WinRTApp::Run()
{
    SDL_SetMainReady();
    if (WINRT_SDLAppEntryPoint)
    {
        // TODO, WinRT: pass the C-style main() a reasonably realistic
        // representation of command line arguments.
        int argc = 0;
        char **argv = NULL;
        WINRT_SDLAppEntryPoint(argc, argv);
    }
}

static bool IsSDLWindowEventPending(SDL_WindowEventID windowEventID)
{
    SDL_Event events[128];
    const int count = SDL_PeepEvents(events, sizeof(events)/sizeof(SDL_Event), SDL_PEEKEVENT, SDL_WINDOWEVENT, SDL_WINDOWEVENT);
    for (int i = 0; i < count; ++i) {
        if (events[i].window.event == windowEventID) {
            return true;
        }
    }
    return false;
}

bool SDL_WinRTApp::ShouldWaitForAppResumeEvents()
{
    /* Don't wait if the app is visible: */
    if (m_windowVisible) {
        return false;
    }
    
    /* Don't wait until the window-hide events finish processing.
     * Do note that if an app-suspend event is sent (as indicated
     * by SDL_APP_WILLENTERBACKGROUND and SDL_APP_DIDENTERBACKGROUND
     * events), then this code may be a moot point, as WinRT's
     * own event pump (aka ProcessEvents()) will pause regardless
     * of what we do here.  This happens on Windows Phone 8, to note.
     * Windows 8.x apps, on the other hand, may get a chance to run
     * these.
     */
    if (IsSDLWindowEventPending(SDL_WINDOWEVENT_HIDDEN)) {
        return false;
    } else if (IsSDLWindowEventPending(SDL_WINDOWEVENT_FOCUS_LOST)) {
        return false;
    } else if (IsSDLWindowEventPending(SDL_WINDOWEVENT_MINIMIZED)) {
        return false;
    }

    return true;
}

void SDL_WinRTApp::PumpEvents()
{
    if (!m_windowClosed) {
        if (!ShouldWaitForAppResumeEvents()) {
            /* This is the normal way in which events should be pumped.
             * 'ProcessAllIfPresent' will make ProcessEvents() process anywhere
             * from zero to N events, and will then return.
             */
            CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);
        } else {
            /* This style of event-pumping, with 'ProcessOneAndAllPending',
             * will cause anywhere from one to N events to be processed.  If
             * at least one event is processed, the call will return.  If
             * no events are pending, then the call will wait until one is
             * available, and will not return (to the caller) until this
             * happens!  This should only occur when the app is hidden.
             */
            CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
        }
    }
}

void SDL_WinRTApp::Uninitialize()
{
}

#if (WINAPI_FAMILY == WINAPI_FAMILY_APP) && (NTDDI_VERSION < NTDDI_WIN10)
void SDL_WinRTApp::OnSettingsPaneCommandsRequested(
    Windows::UI::ApplicationSettings::SettingsPane ^p,
    Windows::UI::ApplicationSettings::SettingsPaneCommandsRequestedEventArgs ^args)
{
    using namespace Platform;
    using namespace Windows::UI::ApplicationSettings;
    using namespace Windows::UI::Popups;

    String ^privacyPolicyURL = nullptr;     // a URL to an app's Privacy Policy
    String ^privacyPolicyLabel = nullptr;   // label/link text
    const char *tmpHintValue = NULL;        // SDL_GetHint-retrieved value, used immediately
    wchar_t *tmpStr = NULL;                 // used for UTF8 to UCS2 conversion

    // Setup a 'Privacy Policy' link, if one is available (via SDL_GetHint):
    tmpHintValue = SDL_GetHint(SDL_HINT_WINRT_PRIVACY_POLICY_URL);
    if (tmpHintValue && tmpHintValue[0] != '\0') {
        // Convert the privacy policy's URL to UCS2:
        tmpStr = WIN_UTF8ToString(tmpHintValue);
        privacyPolicyURL = ref new String(tmpStr);
        SDL_free(tmpStr);

        // Optionally retrieve custom label-text for the link.  If this isn't
        // available, a default value will be used instead.
        tmpHintValue = SDL_GetHint(SDL_HINT_WINRT_PRIVACY_POLICY_LABEL);
        if (tmpHintValue && tmpHintValue[0] != '\0') {
            tmpStr = WIN_UTF8ToString(tmpHintValue);
            privacyPolicyLabel = ref new String(tmpStr);
            SDL_free(tmpStr);
        } else {
            privacyPolicyLabel = ref new String(L"Privacy Policy");
        }

        // Register the link, along with a handler to be called if and when it is
        // clicked:
        auto cmd = ref new SettingsCommand(L"privacyPolicy", privacyPolicyLabel,
            ref new UICommandInvokedHandler([=](IUICommand ^) {
                Windows::System::Launcher::LaunchUriAsync(ref new Uri(privacyPolicyURL));
        }));
        args->Request->ApplicationCommands->Append(cmd);
    }
}
#endif // if (WINAPI_FAMILY == WINAPI_FAMILY_APP) && (NTDDI_VERSION < NTDDI_WIN10)

void SDL_WinRTApp::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args)
{
#if LOG_WINDOW_EVENTS==1
    SDL_Log("%s, size={%f,%f}, bounds={%f,%f,%f,%f}, current orientation=%d, native orientation=%d, auto rot. pref=%d, WINRT_GlobalSDLWindow?=%s\n",
        __FUNCTION__,
        args->Size.Width, args->Size.Height,
        sender->Bounds.X, sender->Bounds.Y, sender->Bounds.Width, sender->Bounds.Height,
        WINRT_DISPLAY_PROPERTY(CurrentOrientation),
        WINRT_DISPLAY_PROPERTY(NativeOrientation),
        WINRT_DISPLAY_PROPERTY(AutoRotationPreferences),
        (WINRT_GlobalSDLWindow ? "yes" : "no"));
#endif

    WINRT_ProcessWindowSizeChange();
}

void SDL_WinRTApp::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args)
{
#if LOG_WINDOW_EVENTS==1
    SDL_Log("%s, visible?=%s, bounds={%f,%f,%f,%f}, WINRT_GlobalSDLWindow?=%s\n",
        __FUNCTION__,
        (args->Visible ? "yes" : "no"),
        sender->Bounds.X, sender->Bounds.Y,
        sender->Bounds.Width, sender->Bounds.Height,
        (WINRT_GlobalSDLWindow ? "yes" : "no"));
#endif

    m_windowVisible = args->Visible;
    if (WINRT_GlobalSDLWindow) {
        SDL_bool wasSDLWindowSurfaceValid = WINRT_GlobalSDLWindow->surface_valid;
        Uint32 latestWindowFlags = WINRT_DetectWindowFlags(WINRT_GlobalSDLWindow);
        if (args->Visible) {
            SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_SHOWN, 0, 0);
            SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_FOCUS_GAINED, 0, 0);
            if (latestWindowFlags & SDL_WINDOW_MAXIMIZED) {
                SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_MAXIMIZED, 0, 0);
            } else {
                SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_RESTORED, 0, 0);
            }
        } else {
            SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_HIDDEN, 0, 0);
            SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_FOCUS_LOST, 0, 0);
            SDL_SendWindowEvent(WINRT_GlobalSDLWindow, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
        }

        // HACK: Prevent SDL's window-hide handling code, which currently
        // triggers a fake window resize (possibly erronously), from
        // marking the SDL window's surface as invalid.
        //
        // A better solution to this probably involves figuring out if the
        // fake window resize can be prevented.
        WINRT_GlobalSDLWindow->surface_valid = wasSDLWindowSurfaceValid;
    }
}

void SDL_WinRTApp::OnWindowActivated(CoreWindow^ sender, WindowActivatedEventArgs^ args)
{
#if LOG_WINDOW_EVENTS==1
    SDL_Log("%s, WINRT_GlobalSDLWindow?=%s\n\n",
        __FUNCTION__,
        (WINRT_GlobalSDLWindow ? "yes" : "no"));
#endif

    /* There's no property in Win 8.x to tell whether a window is active or
       not.  [De]activation events are, however, sent to the app.  We'll just
       record those, in case the CoreWindow gets wrapped by an SDL_Window at
       some future time.
    */
    sender->CustomProperties->Insert("SDLHelperWindowActivationState", args->WindowActivationState);

    SDL_Window * window = WINRT_GlobalSDLWindow;
    if (window) {
        if (args->WindowActivationState != CoreWindowActivationState::Deactivated) {
            SDL_SendWindowEvent(window, SDL_WINDOWEVENT_SHOWN, 0, 0);
            if (SDL_GetKeyboardFocus() != window) {
                SDL_SetKeyboardFocus(window);
            }
        
            /* Send a mouse-motion event as appropriate.
               This doesn't work when called from OnPointerEntered, at least
               not in WinRT CoreWindow apps (as OnPointerEntered doesn't
               appear to be called after window-reactivation, at least not
               in Windows 10, Build 10586.3 (November 2015 update, non-beta).

               Don't do it on WinPhone 8.0 though, as CoreWindow's 'PointerPosition'
               property isn't available.
             */
#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION >= NTDDI_WINBLUE)
            Point cursorPos = WINRT_TransformCursorPosition(window, sender->PointerPosition, TransformToSDLWindowSize);
            SDL_SendMouseMotion(window, 0, 0, (int)cursorPos.X, (int)cursorPos.Y);
#endif

            /* TODO, WinRT: see if the Win32 bugfix from https://hg.libsdl.org/SDL/rev/d278747da408 needs to be applied (on window activation) */
            //WIN_CheckAsyncMouseRelease(data);

            /* TODO, WinRT: implement clipboard support, if possible */
            ///*
            // * FIXME: Update keyboard state
            // */
            //WIN_CheckClipboardUpdate(data->videodata);

            // HACK: Resetting the mouse-cursor here seems to fix
            // https://bugzilla.libsdl.org/show_bug.cgi?id=3217, whereby a
            // WinRT app's mouse cursor may switch to Windows' 'wait' cursor,
            // after a user alt-tabs back into a full-screened SDL app.
            // This bug does not appear to reproduce 100% of the time.
            // It may be a bug in Windows itself (v.10.0.586.36, as tested,
            // and the most-recent as of this writing).
            SDL_SetCursor(NULL);
        } else {
            if (SDL_GetKeyboardFocus() == window) {
                SDL_SetKeyboardFocus(NULL);
            }
        }
    }
}

void SDL_WinRTApp::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args)
{
#if LOG_WINDOW_EVENTS==1
    SDL_Log("%s\n", __FUNCTION__);
#endif
    m_windowClosed = true;
}

void SDL_WinRTApp::OnAppActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args)
{
    CoreWindow::GetForCurrentThread()->Activate();
}

void SDL_WinRTApp::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args)
{
    // Save app state asynchronously after requesting a deferral. Holding a deferral
    // indicates that the application is busy performing suspending operations. Be
    // aware that a deferral may not be held indefinitely. After about five seconds,
    // the app will be forced to exit.

    // ... but first, let the app know it's about to go to the background.
    // The separation of events may be important, given that the deferral
    // runs in a separate thread.  This'll make SDL_APP_WILLENTERBACKGROUND
    // the only event among the two that runs in the main thread.  Given
    // that a few WinRT operations can only be done from the main thread
    // (things that access the WinRT CoreWindow are one example of this),
    // this could be important.
    SDL_SendAppEvent(SDL_APP_WILLENTERBACKGROUND);

    SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral();
    create_task([this, deferral]()
    {
        // Send an app did-enter-background event immediately to observers.
        // CoreDispatcher::ProcessEvents, which is the backbone on which
        // SDL_WinRTApp::PumpEvents is built, will not return to its caller
        // once it sends out a suspend event.  Any events posted to SDL's
        // event queue won't get received until the WinRT app is resumed.
        // SDL_AddEventWatch() may be used to receive app-suspend events on
        // WinRT.
        SDL_SendAppEvent(SDL_APP_DIDENTERBACKGROUND);

        // Let the Direct3D 11 renderer prepare for the app to be backgrounded.
        // This is necessary for Windows 8.1, possibly elsewhere in the future.
        // More details at: http://msdn.microsoft.com/en-us/library/windows/apps/Hh994929.aspx
#if SDL_VIDEO_RENDER_D3D11 && !SDL_RENDER_DISABLED
        if (WINRT_GlobalSDLWindow) {
            SDL_Renderer * renderer = SDL_GetRenderer(WINRT_GlobalSDLWindow);
            if (renderer && (SDL_strcmp(renderer->info.name, "direct3d11") == 0)) {
                D3D11_Trim(renderer);
            }
        }
#endif

        deferral->Complete();
    });
}

void SDL_WinRTApp::OnResuming(Platform::Object^ sender, Platform::Object^ args)
{
    // Restore any data or state that was unloaded on suspend. By default, data
    // and state are persisted when resuming from suspend. Note that these events
    // do not occur if the app was previously terminated.
    SDL_SendAppEvent(SDL_APP_WILLENTERFOREGROUND);
    SDL_SendAppEvent(SDL_APP_DIDENTERFOREGROUND);
}

void SDL_WinRTApp::OnExiting(Platform::Object^ sender, Platform::Object^ args)
{
    SDL_SendAppEvent(SDL_APP_TERMINATING);
}

static void
WINRT_LogPointerEvent(const char * header, Windows::UI::Core::PointerEventArgs ^ args, Windows::Foundation::Point transformedPoint)
{
    Windows::UI::Input::PointerPoint ^ pt = args->CurrentPoint;
    SDL_Log("%s: Position={%f,%f}, Transformed Pos={%f, %f}, MouseWheelDelta=%d, FrameId=%d, PointerId=%d, SDL button=%d\n",
        header,
        pt->Position.X, pt->Position.Y,
        transformedPoint.X, transformedPoint.Y,
        pt->Properties->MouseWheelDelta,
        pt->FrameId,
        pt->PointerId,
        WINRT_GetSDLButtonForPointerPoint(pt));
}

void SDL_WinRTApp::OnPointerPressed(CoreWindow^ sender, PointerEventArgs^ args)
{
#if LOG_POINTER_EVENTS
    WINRT_LogPointerEvent("pointer pressed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
#endif

    WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
}

void SDL_WinRTApp::OnPointerMoved(CoreWindow^ sender, PointerEventArgs^ args)
{
#if LOG_POINTER_EVENTS
    WINRT_LogPointerEvent("pointer moved", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
#endif

    WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
}

void SDL_WinRTApp::OnPointerReleased(CoreWindow^ sender, PointerEventArgs^ args)
{
#if LOG_POINTER_EVENTS
    WINRT_LogPointerEvent("pointer released", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
#endif
    
    WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
}

void SDL_WinRTApp::OnPointerEntered(CoreWindow^ sender, PointerEventArgs^ args)
{
#if LOG_POINTER_EVENTS
    WINRT_LogPointerEvent("pointer entered", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
#endif

    WINRT_ProcessPointerEnteredEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
}

void SDL_WinRTApp::OnPointerExited(CoreWindow^ sender, PointerEventArgs^ args)
{
#if LOG_POINTER_EVENTS
    WINRT_LogPointerEvent("pointer exited", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
#endif

    WINRT_ProcessPointerExitedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
}

void SDL_WinRTApp::OnPointerWheelChanged(CoreWindow^ sender, PointerEventArgs^ args)
{
#if LOG_POINTER_EVENTS
    WINRT_LogPointerEvent("pointer wheel changed", args, WINRT_TransformCursorPosition(WINRT_GlobalSDLWindow, args->CurrentPoint->Position, TransformToSDLWindowSize));
#endif

    WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->CurrentPoint);
}

void SDL_WinRTApp::OnMouseMoved(MouseDevice^ mouseDevice, MouseEventArgs^ args)
{
    WINRT_ProcessMouseMovedEvent(WINRT_GlobalSDLWindow, args);
}

void SDL_WinRTApp::OnKeyDown(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args)
{
    WINRT_ProcessKeyDownEvent(args);
}

void SDL_WinRTApp::OnKeyUp(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::KeyEventArgs^ args)
{
    WINRT_ProcessKeyUpEvent(args);
}

void SDL_WinRTApp::OnCharacterReceived(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CharacterReceivedEventArgs^ args)
{
    WINRT_ProcessCharacterReceivedEvent(args);
}

template <typename BackButtonEventArgs>
static void WINRT_OnBackButtonPressed(BackButtonEventArgs ^ args)
{
    SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_AC_BACK);
    SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_AC_BACK);

    if (SDL_GetHintBoolean(SDL_HINT_WINRT_HANDLE_BACK_BUTTON, SDL_FALSE)) {
        args->Handled = true;
    }
}

#if NTDDI_VERSION >= NTDDI_WIN10
void SDL_WinRTApp::OnBackButtonPressed(Platform::Object^ sender, Windows::UI::Core::BackRequestedEventArgs^ args)

{
    WINRT_OnBackButtonPressed(args);
}
#elif WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
void SDL_WinRTApp::OnBackButtonPressed(Platform::Object^ sender, Windows::Phone::UI::Input::BackPressedEventArgs^ args)

{
    WINRT_OnBackButtonPressed(args);
}
#endif

#if NTDDI_VERSION >= NTDDI_WIN10
void SDL_WinRTApp::OnGamepadAdded(Platform::Object ^sender, Windows::Gaming::Input::Gamepad ^gamepad)
{
    /* HACK ALERT: Nothing needs to be done here, as this method currently
       only exists to allow something to be registered with Win10's
       GamepadAdded event, an operation that seems to be necessary to get
       Xinput-based detection to work on Xbox One.
    */
}
#endif

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