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

/* SDL includes */
#include "SDL_winrtevents_c.h"
#include "SDL_winrtmouse_c.h"
#include "SDL_winrtvideo_cpp.h"
#include "SDL_assert.h"
#include "SDL_system.h"

extern "C" {
#include "../SDL_sysvideo.h"
#include "../../events/SDL_events_c.h"
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_touch_c.h"
}

/* File-specific globals: */
static SDL_TouchID WINRT_TouchID = 1;
static unsigned int WINRT_LeftFingerDown = 0;


void
WINRT_InitTouch(_THIS)
{
    SDL_AddTouch(WINRT_TouchID, SDL_TOUCH_DEVICE_DIRECT, "");
}


//
// Applies necessary geometric transformations to raw cursor positions:
//
Windows::Foundation::Point
WINRT_TransformCursorPosition(SDL_Window * window,
                              Windows::Foundation::Point rawPosition,
                              WINRT_CursorNormalizationType normalization)
{
    using namespace Windows::UI::Core;
    using namespace Windows::Graphics::Display;

    if (!window) {
        return rawPosition;
    }

    SDL_WindowData * windowData = (SDL_WindowData *) window->driverdata;
    if (windowData->coreWindow == nullptr) {
        // For some reason, the window isn't associated with a CoreWindow.
        // This might end up being the case as XAML support is extended.
        // For now, if there's no CoreWindow attached to the SDL_Window,
        // don't do any transforms.

        // TODO, WinRT: make sure touch input coordinate ranges are correct when using XAML support
        return rawPosition;
    }

    // The CoreWindow can only be accessed on certain thread(s).
    SDL_assert(CoreWindow::GetForCurrentThread() != nullptr);

    CoreWindow ^ nativeWindow = windowData->coreWindow.Get();
    Windows::Foundation::Point outputPosition;

    // Compute coordinates normalized from 0..1.
    // If the coordinates need to be sized to the SDL window,
    // we'll do that after.
#if (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP) || (NTDDI_VERSION > NTDDI_WIN8)
    outputPosition.X = rawPosition.X / nativeWindow->Bounds.Width;
    outputPosition.Y = rawPosition.Y / nativeWindow->Bounds.Height;
#else
    switch (WINRT_DISPLAY_PROPERTY(CurrentOrientation))
    {
        case DisplayOrientations::Portrait:
            outputPosition.X = rawPosition.X / nativeWindow->Bounds.Width;
            outputPosition.Y = rawPosition.Y / nativeWindow->Bounds.Height;
            break;
        case DisplayOrientations::PortraitFlipped:
            outputPosition.X = 1.0f - (rawPosition.X / nativeWindow->Bounds.Width);
            outputPosition.Y = 1.0f - (rawPosition.Y / nativeWindow->Bounds.Height);
            break;
        case DisplayOrientations::Landscape:
            outputPosition.X = rawPosition.Y / nativeWindow->Bounds.Height;
            outputPosition.Y = 1.0f - (rawPosition.X / nativeWindow->Bounds.Width);
            break;
        case DisplayOrientations::LandscapeFlipped:
            outputPosition.X = 1.0f - (rawPosition.Y / nativeWindow->Bounds.Height);
            outputPosition.Y = rawPosition.X / nativeWindow->Bounds.Width;
            break;
        default:
            break;
    }
#endif

    if (normalization == TransformToSDLWindowSize) {
        outputPosition.X *= ((float32) window->w);
        outputPosition.Y *= ((float32) window->h);
    }

    return outputPosition;
}

static inline int
_lround(float arg)
{
    if (arg >= 0.0f) {
        return (int)floor(arg + 0.5f);
    } else {
        return (int)ceil(arg - 0.5f);
    }
}

Uint8
WINRT_GetSDLButtonForPointerPoint(Windows::UI::Input::PointerPoint ^pt)
{
    using namespace Windows::UI::Input;

#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
    return SDL_BUTTON_LEFT;
#else
    switch (pt->Properties->PointerUpdateKind)
    {
        case PointerUpdateKind::LeftButtonPressed:
        case PointerUpdateKind::LeftButtonReleased:
            return SDL_BUTTON_LEFT;

        case PointerUpdateKind::RightButtonPressed:
        case PointerUpdateKind::RightButtonReleased:
            return SDL_BUTTON_RIGHT;

        case PointerUpdateKind::MiddleButtonPressed:
        case PointerUpdateKind::MiddleButtonReleased:
            return SDL_BUTTON_MIDDLE;

        case PointerUpdateKind::XButton1Pressed:
        case PointerUpdateKind::XButton1Released:
            return SDL_BUTTON_X1;

        case PointerUpdateKind::XButton2Pressed:
        case PointerUpdateKind::XButton2Released:
            return SDL_BUTTON_X2;

        default:
            break;
    }
#endif

    return 0;
}

//const char *
//WINRT_ConvertPointerUpdateKindToString(Windows::UI::Input::PointerUpdateKind kind)
//{
//    using namespace Windows::UI::Input;
//
//    switch (kind)
//    {
//        case PointerUpdateKind::Other:
//            return "Other";
//        case PointerUpdateKind::LeftButtonPressed:
//            return "LeftButtonPressed";
//        case PointerUpdateKind::LeftButtonReleased:
//            return "LeftButtonReleased";
//        case PointerUpdateKind::RightButtonPressed:
//            return "RightButtonPressed";
//        case PointerUpdateKind::RightButtonReleased:
//            return "RightButtonReleased";
//        case PointerUpdateKind::MiddleButtonPressed:
//            return "MiddleButtonPressed";
//        case PointerUpdateKind::MiddleButtonReleased:
//            return "MiddleButtonReleased";
//        case PointerUpdateKind::XButton1Pressed:
//            return "XButton1Pressed";
//        case PointerUpdateKind::XButton1Released:
//            return "XButton1Released";
//        case PointerUpdateKind::XButton2Pressed:
//            return "XButton2Pressed";
//        case PointerUpdateKind::XButton2Released:
//            return "XButton2Released";
//    }
//
//    return "";
//}

static bool
WINRT_IsTouchEvent(Windows::UI::Input::PointerPoint ^pointerPoint)
{
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
    return true;
#else
    using namespace Windows::Devices::Input;
    switch (pointerPoint->PointerDevice->PointerDeviceType) {
        case PointerDeviceType::Touch:
        case PointerDeviceType::Pen:
            return true;
        default:
            return false;
    }
#endif
}

void WINRT_ProcessPointerPressedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
{
    if (!window) {
        return;
    }

    Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint);

    if ( ! WINRT_IsTouchEvent(pointerPoint)) {
        SDL_SendMouseButton(window, 0, SDL_PRESSED, button);
    } else {
        Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne);
        Windows::Foundation::Point windowPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, TransformToSDLWindowSize);

        if (!WINRT_LeftFingerDown) {
            if (button) {
                SDL_SendMouseMotion(window, SDL_TOUCH_MOUSEID, 0, (int)windowPoint.X, (int)windowPoint.Y);
                SDL_SendMouseButton(window, SDL_TOUCH_MOUSEID, SDL_PRESSED, button);
            }

            WINRT_LeftFingerDown = pointerPoint->PointerId;
        }

        SDL_SendTouch(
            WINRT_TouchID,
            (SDL_FingerID) pointerPoint->PointerId,
            SDL_TRUE,
            normalizedPoint.X,
            normalizedPoint.Y,
            pointerPoint->Properties->Pressure);
    }
}

void
WINRT_ProcessPointerMovedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
{
    if (!window || WINRT_UsingRelativeMouseMode) {
        return;
    }

    Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne);
    Windows::Foundation::Point windowPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, TransformToSDLWindowSize);

    if ( ! WINRT_IsTouchEvent(pointerPoint)) {
        SDL_SendMouseMotion(window, 0, 0, (int)windowPoint.X, (int)windowPoint.Y);
    } else {
        if (pointerPoint->PointerId == WINRT_LeftFingerDown) {
            SDL_SendMouseMotion(window, SDL_TOUCH_MOUSEID, 0, (int)windowPoint.X, (int)windowPoint.Y);
        }

        SDL_SendTouchMotion(
            WINRT_TouchID,
            (SDL_FingerID) pointerPoint->PointerId,
            normalizedPoint.X,
            normalizedPoint.Y,
            pointerPoint->Properties->Pressure);
    }
}

void WINRT_ProcessPointerReleasedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
{
    if (!window) {
        return;
    }

    Uint8 button = WINRT_GetSDLButtonForPointerPoint(pointerPoint);

    if (!WINRT_IsTouchEvent(pointerPoint)) {
        SDL_SendMouseButton(window, 0, SDL_RELEASED, button);
    } else {
        Windows::Foundation::Point normalizedPoint = WINRT_TransformCursorPosition(window, pointerPoint->Position, NormalizeZeroToOne);

        if (WINRT_LeftFingerDown == pointerPoint->PointerId) {
            if (button) {
                SDL_SendMouseButton(window, SDL_TOUCH_MOUSEID, SDL_RELEASED, button);
            }
            WINRT_LeftFingerDown = 0;
        }

        SDL_SendTouch(
            WINRT_TouchID,
            (SDL_FingerID) pointerPoint->PointerId,
            SDL_FALSE,
            normalizedPoint.X,
            normalizedPoint.Y,
            pointerPoint->Properties->Pressure);
    }
}

void WINRT_ProcessPointerEnteredEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
{
    if (!window) {
        return;
    }

    if (!WINRT_IsTouchEvent(pointerPoint)) {
        SDL_SetMouseFocus(window);
    }
}

void WINRT_ProcessPointerExitedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
{
    if (!window) {
        return;
    }

    if (!WINRT_IsTouchEvent(pointerPoint)) {
        SDL_SetMouseFocus(NULL);
    }
}

void
WINRT_ProcessPointerWheelChangedEvent(SDL_Window *window, Windows::UI::Input::PointerPoint ^pointerPoint)
{
    if (!window) {
        return;
    }

    float motion = (float) pointerPoint->Properties->MouseWheelDelta / WHEEL_DELTA;
    SDL_SendMouseWheel(window, 0, 0, (float) motion, SDL_MOUSEWHEEL_NORMAL);
}

void
WINRT_ProcessMouseMovedEvent(SDL_Window * window, Windows::Devices::Input::MouseEventArgs ^args)
{
    if (!window || !WINRT_UsingRelativeMouseMode) {
        return;
    }

    // DLudwig, 2012-12-28: On some systems, namely Visual Studio's Windows
    // Simulator, as well as Windows 8 in a Parallels 8 VM, MouseEventArgs'
    // MouseDelta field often reports very large values.  More information
    // on this can be found at the following pages on MSDN:
    //  - http://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/a3c789fa-f1c5-49c4-9c0a-7db88d0f90f8
    //  - https://connect.microsoft.com/VisualStudio/Feedback/details/756515
    //
    // The values do not appear to be as large when running on some systems,
    // most notably a Surface RT.  Furthermore, the values returned by
    // CoreWindow's PointerMoved event, and sent to this class' OnPointerMoved
    // method, do not ever appear to be large, even when MouseEventArgs'
    // MouseDelta is reporting to the contrary.
    //
    // On systems with the large-values behavior, it appears that the values
    // get reported as if the screen's size is 65536 units in both the X and Y
    // dimensions.  This can be viewed by using Windows' now-private, "Raw Input"
    // APIs.  (GetRawInputData, RegisterRawInputDevices, WM_INPUT, etc.)
    //
    // MSDN's documentation on MouseEventArgs' MouseDelta field (at
    // http://msdn.microsoft.com/en-us/library/windows/apps/windows.devices.input.mouseeventargs.mousedelta ),
    // does not seem to indicate (to me) that its values should be so large.  It
    // says that its values should be a "change in screen location".  I could
    // be misinterpreting this, however a post on MSDN from a Microsoft engineer (see:
    // http://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/09a9868e-95bb-4858-ba1a-cb4d2c298d62 ),
    // indicates that these values are in DIPs, which is the same unit used
    // by CoreWindow's PointerMoved events (via the Position field in its CurrentPoint
    // property.  See http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.input.pointerpoint.position.aspx
    // for details.)
    //
    // To note, PointerMoved events are sent a 'RawPosition' value (via the
    // CurrentPoint property in MouseEventArgs), however these do not seem
    // to exhibit the same large-value behavior.
    //
    // The values passed via PointerMoved events can't always be used for relative
    // mouse motion, unfortunately.  Its values are bound to the cursor's position,
    // which stops when it hits one of the screen's edges.  This can be a problem in
    // first person shooters, whereby it is normal for mouse motion to travel far
    // along any one axis for a period of time.  MouseMoved events do not have the
    // screen-bounding limitation, and can be used regardless of where the system's
    // cursor is.
    //
    // One possible workaround would be to programmatically set the cursor's
    // position to the screen's center (when SDL's relative mouse mode is enabled),
    // however WinRT does not yet seem to have the ability to set the cursor's
    // position via a public API.  Win32 did this via an API call, SetCursorPos,
    // however WinRT makes this function be private.  Apps that use it won't get
    // approved for distribution in the Windows Store.  I've yet to be able to find
    // a suitable, store-friendly counterpart for WinRT.
    //
    // There may be some room for a workaround whereby OnPointerMoved's values
    // are compared to the values from OnMouseMoved in order to detect
    // when this bug is active.  A suitable transformation could then be made to
    // OnMouseMoved's values.  For now, however, the system-reported values are sent
    // to SDL with minimal transformation: from native screen coordinates (in DIPs)
    // to SDL window coordinates.
    //
    const Windows::Foundation::Point mouseDeltaInDIPs((float)args->MouseDelta.X, (float)args->MouseDelta.Y);
    const Windows::Foundation::Point mouseDeltaInSDLWindowCoords = WINRT_TransformCursorPosition(window, mouseDeltaInDIPs, TransformToSDLWindowSize);
    SDL_SendMouseMotion(
        window,
        0,
        1,
        _lround(mouseDeltaInSDLWindowCoords.X),
        _lround(mouseDeltaInSDLWindowCoords.Y));
}

#endif // SDL_VIDEO_DRIVER_WINRT
