/*
  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 <Windows.h>
using namespace Windows::UI::Core;
using Windows::UI::Core::CoreCursor;

/*
 * SDL includes:
 */
#include "SDL_winrtevents_c.h"
#include "../../core/winrt/SDL_winrtapp_common.h"
#include "../../core/winrt/SDL_winrtapp_direct3d.h"
#include "../../core/winrt/SDL_winrtapp_xaml.h"
#include "SDL_assert.h"
#include "SDL_system.h"

extern "C" {
#include "../../thread/SDL_systhread.h"
#include "../SDL_sysvideo.h"
#include "../../events/SDL_events_c.h"
}


/* Forward declarations */
static void WINRT_YieldXAMLThread();


/* Global event management */

void
WINRT_PumpEvents(_THIS)
{
    if (SDL_WinRTGlobalApp) {
        SDL_WinRTGlobalApp->PumpEvents();
    } else if (WINRT_XAMLWasEnabled) {
        WINRT_YieldXAMLThread();
    }
}


/* XAML Thread management */

enum SDL_XAMLAppThreadState
{
    ThreadState_NotLaunched = 0,
    ThreadState_Running,
    ThreadState_Yielding
};

static SDL_XAMLAppThreadState _threadState = ThreadState_NotLaunched;
static SDL_Thread * _XAMLThread = nullptr;
static SDL_mutex * _mutex = nullptr;
static SDL_cond * _cond = nullptr;

static void
WINRT_YieldXAMLThread()
{
    SDL_LockMutex(_mutex);
    SDL_assert(_threadState == ThreadState_Running);
    _threadState = ThreadState_Yielding;
    SDL_UnlockMutex(_mutex);

    SDL_CondSignal(_cond);

    SDL_LockMutex(_mutex);
    while (_threadState != ThreadState_Running) {
        SDL_CondWait(_cond, _mutex);
    }
    SDL_UnlockMutex(_mutex);
}

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

void
WINRT_CycleXAMLThread()
{
    switch (_threadState) {
        case ThreadState_NotLaunched:
        {
            _cond = SDL_CreateCond();

            _mutex = SDL_CreateMutex();
            _threadState = ThreadState_Running;
            _XAMLThread = SDL_CreateThreadInternal(WINRT_XAMLThreadMain, "SDL/XAML App Thread", 0, nullptr);

            SDL_LockMutex(_mutex);
            while (_threadState != ThreadState_Yielding) {
                SDL_CondWait(_cond, _mutex);
            }
            SDL_UnlockMutex(_mutex);

            break;
        }

        case ThreadState_Running:
        {
            SDL_assert(false);
            break;
        }

        case ThreadState_Yielding:
        {
            SDL_LockMutex(_mutex);
            SDL_assert(_threadState == ThreadState_Yielding);
            _threadState = ThreadState_Running;
            SDL_UnlockMutex(_mutex);

            SDL_CondSignal(_cond);

            SDL_LockMutex(_mutex);
            while (_threadState != ThreadState_Yielding) {
                SDL_CondWait(_cond, _mutex);
            }
            SDL_UnlockMutex(_mutex);
        }
    }
}

#endif /* SDL_VIDEO_DRIVER_WINRT */

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