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

/* Windows includes */
#include <agile.h>
#include <Windows.h>

#if WINAPI_FAMILY == WINAPI_FAMILY_APP
#include <windows.ui.xaml.media.dxinterop.h>
#endif


/* SDL includes */
#include "../../SDL_internal.h"
#include "SDL.h"
#include "../../video/winrt/SDL_winrtevents_c.h"
#include "../../video/winrt/SDL_winrtvideo_cpp.h"
#include "SDL_winrtapp_common.h"
#include "SDL_winrtapp_xaml.h"



/* SDL-internal globals: */
SDL_bool WINRT_XAMLWasEnabled = SDL_FALSE;

#if WINAPI_FAMILY == WINAPI_FAMILY_APP
extern "C"
ISwapChainBackgroundPanelNative * WINRT_GlobalSwapChainBackgroundPanelNative = NULL;
static Windows::Foundation::EventRegistrationToken	WINRT_XAMLAppEventToken;
#endif


/*
 * Input event handlers (XAML)
 */
#if WINAPI_FAMILY == WINAPI_FAMILY_APP

static void
WINRT_OnPointerPressedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args)
{
    WINRT_ProcessPointerPressedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr));
}

static void
WINRT_OnPointerMovedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args)
{
    WINRT_ProcessPointerMovedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr));
}

static void
WINRT_OnPointerReleasedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args)
{
    WINRT_ProcessPointerReleasedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr));
}

static void
WINRT_OnPointerWheelChangedViaXAML(Platform::Object^ sender, Windows::UI::Xaml::Input::PointerRoutedEventArgs^ args)
{
    WINRT_ProcessPointerWheelChangedEvent(WINRT_GlobalSDLWindow, args->GetCurrentPoint(nullptr));
}

#endif // WINAPI_FAMILY == WINAPI_FAMILY_APP


/*
 * XAML-to-SDL Rendering Callback
 */
#if WINAPI_FAMILY == WINAPI_FAMILY_APP

static void
WINRT_OnRenderViaXAML(_In_ Platform::Object^ sender, _In_ Platform::Object^ args)
{
    WINRT_CycleXAMLThread();
}

#endif // WINAPI_FAMILY == WINAPI_FAMILY_APP


/*
 * SDL + XAML Initialization
 */

int
SDL_WinRTInitXAMLApp(int (*mainFunction)(int, char **), void * backgroundPanelAsIInspectable)
{
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
    return SDL_SetError("XAML support is not yet available in Windows Phone.");
#else
    // Declare C++/CX namespaces:
    using namespace Platform;
    using namespace Windows::Foundation;
    using namespace Windows::UI::Core;
    using namespace Windows::UI::Xaml;
    using namespace Windows::UI::Xaml::Controls;
    using namespace Windows::UI::Xaml::Input;
    using namespace Windows::UI::Xaml::Media;

    // Make sure we have a valid XAML element (to draw onto):
    if ( ! backgroundPanelAsIInspectable) {
        return SDL_SetError("'backgroundPanelAsIInspectable' can't be NULL");
    }

    Platform::Object ^ backgroundPanel = reinterpret_cast<Object ^>((IInspectable *) backgroundPanelAsIInspectable);
    SwapChainBackgroundPanel ^swapChainBackgroundPanel = dynamic_cast<SwapChainBackgroundPanel ^>(backgroundPanel);
    if ( ! swapChainBackgroundPanel) {
        return SDL_SetError("An unknown or unsupported type of XAML control was specified.");
    }

    // Setup event handlers:
    swapChainBackgroundPanel->PointerPressed += ref new PointerEventHandler(WINRT_OnPointerPressedViaXAML);
    swapChainBackgroundPanel->PointerReleased += ref new PointerEventHandler(WINRT_OnPointerReleasedViaXAML);
    swapChainBackgroundPanel->PointerWheelChanged += ref new PointerEventHandler(WINRT_OnPointerWheelChangedViaXAML);
    swapChainBackgroundPanel->PointerMoved += ref new PointerEventHandler(WINRT_OnPointerMovedViaXAML);

    // Setup for rendering:
    IInspectable *panelInspectable = (IInspectable*) reinterpret_cast<IInspectable*>(swapChainBackgroundPanel);
    panelInspectable->QueryInterface(__uuidof(ISwapChainBackgroundPanelNative), (void **)&WINRT_GlobalSwapChainBackgroundPanelNative);

    WINRT_XAMLAppEventToken = CompositionTarget::Rendering::add(ref new EventHandler<Object^>(WINRT_OnRenderViaXAML));

    // Make sure the app is ready to call the SDL-centric main() function:
    WINRT_SDLAppEntryPoint = mainFunction;
    SDL_SetMainReady();

    // Make sure video-init knows that we're initializing XAML:
    SDL_bool oldXAMLWasEnabledValue = WINRT_XAMLWasEnabled;
    WINRT_XAMLWasEnabled = SDL_TRUE;

    // Make sure video modes are detected now, while we still have access to the WinRT
    // CoreWindow.  WinRT will not allow the app's CoreWindow to be accessed via the
    // SDL/WinRT thread.
    if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
        // SDL_InitSubSystem will, on error, set the SDL error.  Let that propogate to
        // the caller to here:
        WINRT_XAMLWasEnabled = oldXAMLWasEnabledValue;
        return -1;
    }

    // All done, for now.
    return 0;
#endif // WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP  /  else
}
