/*
  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"

/* This is the sensor API for Simple DirectMedia Layer */

#include "SDL.h"
#include "SDL_atomic.h"
#include "SDL_events.h"
#include "SDL_syssensor.h"
#include "SDL_assert.h"

#if !SDL_EVENTS_DISABLED
#include "../events/SDL_events_c.h"
#endif

static SDL_SensorDriver *SDL_sensor_drivers[] = {
#ifdef SDL_SENSOR_ANDROID
    &SDL_ANDROID_SensorDriver,
#endif
#ifdef SDL_SENSOR_COREMOTION
    &SDL_COREMOTION_SensorDriver,
#endif
#ifdef SDL_SENSOR_WINDOWS
	&SDL_WINDOWS_SensorDriver,
#endif
#if defined(SDL_SENSOR_DUMMY) || defined(SDL_SENSOR_DISABLED)
    &SDL_DUMMY_SensorDriver
#endif
};
static SDL_Sensor *SDL_sensors = NULL;
static SDL_bool SDL_updating_sensor = SDL_FALSE;
static SDL_mutex *SDL_sensor_lock = NULL; /* This needs to support recursive locks */
static SDL_atomic_t SDL_next_sensor_instance_id;

void
SDL_LockSensors(void)
{
    if (SDL_sensor_lock) {
        SDL_LockMutex(SDL_sensor_lock);
    }
}

void
SDL_UnlockSensors(void)
{
    if (SDL_sensor_lock) {
        SDL_UnlockMutex(SDL_sensor_lock);
    }
}


int
SDL_SensorInit(void)
{
    int i, status;

    /* Create the sensor list lock */
    if (!SDL_sensor_lock) {
        SDL_sensor_lock = SDL_CreateMutex();
    }

#if !SDL_EVENTS_DISABLED
    if (SDL_InitSubSystem(SDL_INIT_EVENTS) < 0) {
        return -1;
    }
#endif /* !SDL_EVENTS_DISABLED */

    status = -1;
    for (i = 0; i < SDL_arraysize(SDL_sensor_drivers); ++i) {
        if (SDL_sensor_drivers[i]->Init() >= 0) {
            status = 0;
        }
    }
    return status;
}

/*
 * Count the number of sensors attached to the system
 */
int
SDL_NumSensors(void)
{
    int i, total_sensors = 0;
    SDL_LockSensors();
    for (i = 0; i < SDL_arraysize(SDL_sensor_drivers); ++i) {
        total_sensors += SDL_sensor_drivers[i]->GetCount();
    }
    SDL_UnlockSensors();
    return total_sensors;
}

/*
 * Return the next available sensor instance ID
 * This may be called by drivers from multiple threads, unprotected by any locks
 */
SDL_SensorID SDL_GetNextSensorInstanceID()
{
    return SDL_AtomicIncRef(&SDL_next_sensor_instance_id);
}

/*
 * Get the driver and device index for an API device index
 * This should be called while the sensor lock is held, to prevent another thread from updating the list
 */
static SDL_bool
SDL_GetDriverAndSensorIndex(int device_index, SDL_SensorDriver **driver, int *driver_index)
{
    int i, num_sensors, total_sensors = 0;

    if (device_index >= 0) {
        for (i = 0; i < SDL_arraysize(SDL_sensor_drivers); ++i) {
            num_sensors = SDL_sensor_drivers[i]->GetCount();
            if (device_index < num_sensors) {
                *driver = SDL_sensor_drivers[i];
                *driver_index = device_index;
                return SDL_TRUE;
            }
            device_index -= num_sensors;
            total_sensors += num_sensors;
        }
    }

    SDL_SetError("There are %d sensors available", total_sensors);
    return SDL_FALSE;
}

/*
 * Get the implementation dependent name of a sensor
 */
const char *
SDL_SensorGetDeviceName(int device_index)
{
    SDL_SensorDriver *driver;
    const char *name = NULL;

    SDL_LockSensors();
    if (SDL_GetDriverAndSensorIndex(device_index, &driver, &device_index)) {
        name = driver->GetDeviceName(device_index);
    }
    SDL_UnlockSensors();

    /* FIXME: Really we should reference count this name so it doesn't go away after unlock */
    return name;
}

SDL_SensorType
SDL_SensorGetDeviceType(int device_index)
{
    SDL_SensorDriver *driver;
    SDL_SensorType type = SDL_SENSOR_INVALID;

    SDL_LockSensors();
    if (SDL_GetDriverAndSensorIndex(device_index, &driver, &device_index)) {
        type = driver->GetDeviceType(device_index);
    }
    SDL_UnlockSensors();

    return type;
}

SDL_SensorType
SDL_SensorGetDeviceNonPortableType(int device_index)
{
    SDL_SensorDriver *driver;
    int type = -1;

    SDL_LockSensors();
    if (SDL_GetDriverAndSensorIndex(device_index, &driver, &device_index)) {
        type = driver->GetDeviceNonPortableType(device_index);
    }
    SDL_UnlockSensors();

    return type;
}

SDL_SensorID
SDL_SensorGetDeviceInstanceID(int device_index)
{
    SDL_SensorDriver *driver;
    SDL_SensorID instance_id = -1;

    SDL_LockSensors();
    if (SDL_GetDriverAndSensorIndex(device_index, &driver, &device_index)) {
        instance_id = driver->GetDeviceInstanceID(device_index);
    }
    SDL_UnlockSensors();

    return instance_id;
}

/*
 * Open a sensor for use - the index passed as an argument refers to
 * the N'th sensor on the system.  This index is the value which will
 * identify this sensor in future sensor events.
 *
 * This function returns a sensor identifier, or NULL if an error occurred.
 */
SDL_Sensor *
SDL_SensorOpen(int device_index)
{
    SDL_SensorDriver *driver;
    SDL_SensorID instance_id;
    SDL_Sensor *sensor;
    SDL_Sensor *sensorlist;
    const char *sensorname = NULL;

    SDL_LockSensors();

    if (!SDL_GetDriverAndSensorIndex(device_index, &driver, &device_index)) {
        SDL_UnlockSensors();
        return NULL;
    }

    sensorlist = SDL_sensors;
    /* If the sensor is already open, return it
     * it is important that we have a single sensor * for each instance id
     */
    instance_id = driver->GetDeviceInstanceID(device_index);
    while (sensorlist) {
        if (instance_id == sensorlist->instance_id) {
                sensor = sensorlist;
                ++sensor->ref_count;
                SDL_UnlockSensors();
                return sensor;
        }
        sensorlist = sensorlist->next;
    }

    /* Create and initialize the sensor */
    sensor = (SDL_Sensor *) SDL_calloc(sizeof(*sensor), 1);
    if (sensor == NULL) {
        SDL_OutOfMemory();
        SDL_UnlockSensors();
        return NULL;
    }
    sensor->driver = driver;
    sensor->instance_id = instance_id;
    sensor->type = driver->GetDeviceType(device_index);
    sensor->non_portable_type = driver->GetDeviceNonPortableType(device_index);

    if (driver->Open(sensor, device_index) < 0) {
        SDL_free(sensor);
        SDL_UnlockSensors();
        return NULL;
    }

    sensorname = driver->GetDeviceName(device_index);
    if (sensorname) {
        sensor->name = SDL_strdup(sensorname);
    } else {
        sensor->name = NULL;
    }

    /* Add sensor to list */
    ++sensor->ref_count;
    /* Link the sensor in the list */
    sensor->next = SDL_sensors;
    SDL_sensors = sensor;

    SDL_UnlockSensors();

    driver->Update(sensor);

    return sensor;
}

/*
 * Find the SDL_Sensor that owns this instance id
 */
SDL_Sensor *
SDL_SensorFromInstanceID(SDL_SensorID instance_id)
{
    SDL_Sensor *sensor;

    SDL_LockSensors();
    for (sensor = SDL_sensors; sensor; sensor = sensor->next) {
        if (sensor->instance_id == instance_id) {
            break;
        }
    }
    SDL_UnlockSensors();
    return sensor;
}

/*
 * Checks to make sure the sensor is valid.
 */
static int
SDL_PrivateSensorValid(SDL_Sensor * sensor)
{
    int valid;

    if (sensor == NULL) {
        SDL_SetError("Sensor hasn't been opened yet");
        valid = 0;
    } else {
        valid = 1;
    }

    return valid;
}

/*
 * Get the friendly name of this sensor
 */
const char *
SDL_SensorGetName(SDL_Sensor * sensor)
{
    if (!SDL_PrivateSensorValid(sensor)) {
        return NULL;
    }

    return sensor->name;
}

/*
 * Get the type of this sensor
 */
SDL_SensorType
SDL_SensorGetType(SDL_Sensor * sensor)
{
    if (!SDL_PrivateSensorValid(sensor)) {
        return SDL_SENSOR_INVALID;
    }

    return sensor->type;
}

/*
 * Get the platform dependent type of this sensor
 */
int
SDL_SensorGetNonPortableType(SDL_Sensor * sensor)
{
    if (!SDL_PrivateSensorValid(sensor)) {
        return -1;
    }

    return sensor->non_portable_type;
}

/*
 * Get the instance id for this opened sensor
 */
SDL_SensorID
SDL_SensorGetInstanceID(SDL_Sensor * sensor)
{
    if (!SDL_PrivateSensorValid(sensor)) {
        return -1;
    }

    return sensor->instance_id;
}

/*
 * Get the current state of this sensor
 */
int
SDL_SensorGetData(SDL_Sensor * sensor, float *data, int num_values)
{
    if (!SDL_PrivateSensorValid(sensor)) {
        return -1;
    }

    num_values = SDL_min(num_values, SDL_arraysize(sensor->data));
    SDL_memcpy(data, sensor->data, num_values*sizeof(*data));
    return 0;
}

/*
 * Close a sensor previously opened with SDL_SensorOpen()
 */
void
SDL_SensorClose(SDL_Sensor * sensor)
{
    SDL_Sensor *sensorlist;
    SDL_Sensor *sensorlistprev;

    if (!SDL_PrivateSensorValid(sensor)) {
        return;
    }

    SDL_LockSensors();

    /* First decrement ref count */
    if (--sensor->ref_count > 0) {
        SDL_UnlockSensors();
        return;
    }

    if (SDL_updating_sensor) {
        SDL_UnlockSensors();
        return;
    }

    sensor->driver->Close(sensor);
    sensor->hwdata = NULL;

    sensorlist = SDL_sensors;
    sensorlistprev = NULL;
    while (sensorlist) {
        if (sensor == sensorlist) {
            if (sensorlistprev) {
                /* unlink this entry */
                sensorlistprev->next = sensorlist->next;
            } else {
                SDL_sensors = sensor->next;
            }
            break;
        }
        sensorlistprev = sensorlist;
        sensorlist = sensorlist->next;
    }

    SDL_free(sensor->name);

    /* Free the data associated with this sensor */
    SDL_free(sensor);

    SDL_UnlockSensors();
}

void
SDL_SensorQuit(void)
{
    int i;

    /* Make sure we're not getting called in the middle of updating sensors */
    SDL_assert(!SDL_updating_sensor);

    SDL_LockSensors();

    /* Stop the event polling */
    while (SDL_sensors) {
        SDL_sensors->ref_count = 1;
        SDL_SensorClose(SDL_sensors);
    }

    /* Quit the sensor setup */
    for (i = 0; i < SDL_arraysize(SDL_sensor_drivers); ++i) {
       SDL_sensor_drivers[i]->Quit();
    }

    SDL_UnlockSensors();

#if !SDL_EVENTS_DISABLED
    SDL_QuitSubSystem(SDL_INIT_EVENTS);
#endif

    if (SDL_sensor_lock) {
        SDL_DestroyMutex(SDL_sensor_lock);
        SDL_sensor_lock = NULL;
    }
}


/* These are global for SDL_syssensor.c and SDL_events.c */

int
SDL_PrivateSensorUpdate(SDL_Sensor *sensor, float *data, int num_values)
{
    int posted;

    /* Allow duplicate events, for things like steps and heartbeats */

    /* Update internal sensor state */
    num_values = SDL_min(num_values, SDL_arraysize(sensor->data));
    SDL_memcpy(sensor->data, data, num_values*sizeof(*data));

    /* Post the event, if desired */
    posted = 0;
#if !SDL_EVENTS_DISABLED
    if (SDL_GetEventState(SDL_SENSORUPDATE) == SDL_ENABLE) {
        SDL_Event event;
        event.type = SDL_SENSORUPDATE;
        event.sensor.which = sensor->instance_id;
        num_values = SDL_min(num_values, SDL_arraysize(event.sensor.data));
        SDL_memset(event.sensor.data, 0, sizeof(event.sensor.data));
        SDL_memcpy(event.sensor.data, data, num_values*sizeof(*data));
        posted = SDL_PushEvent(&event) == 1;
    }
#endif /* !SDL_EVENTS_DISABLED */
    return posted;
}

void
SDL_SensorUpdate(void)
{
    int i;
    SDL_Sensor *sensor, *next;

    if (!SDL_WasInit(SDL_INIT_SENSOR)) {
        return;
    }

    SDL_LockSensors();

    if (SDL_updating_sensor) {
        /* The sensors are already being updated */
        SDL_UnlockSensors();
        return;
    }

    SDL_updating_sensor = SDL_TRUE;

    /* Make sure the list is unlocked while dispatching events to prevent application deadlocks */
    SDL_UnlockSensors();

    for (sensor = SDL_sensors; sensor; sensor = sensor->next) {
        sensor->driver->Update(sensor);
    }

    SDL_LockSensors();

    SDL_updating_sensor = SDL_FALSE;

    /* If any sensors were closed while updating, free them here */
    for (sensor = SDL_sensors; sensor; sensor = next) {
        next = sensor->next;
        if (sensor->ref_count <= 0) {
            SDL_SensorClose(sensor);
        }
    }

    /* this needs to happen AFTER walking the sensor list above, so that any
       dangling hardware data from removed devices can be free'd
     */
    for (i = 0; i < SDL_arraysize(SDL_sensor_drivers); ++i) {
        SDL_sensor_drivers[i]->Detect();
    }

    SDL_UnlockSensors();
}

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