/*
 * Copyright (C) 2010 Apple Inc. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#import "config.h"
#import "WebCoreMotionManager.h"

#if PLATFORM(IOS_FAMILY) && ENABLE(DEVICE_ORIENTATION)

#import "DeviceMotionClientIOS.h"
#import "MotionManagerClient.h"
#import "WebCoreObjCExtras.h"
#import "WebCoreThreadRun.h"
#import <CoreLocation/CoreLocation.h>
#import <objc/objc-runtime.h>
#import <pal/spi/cocoa/CoreMotionSPI.h>
#import <wtf/MathExtras.h>
#import <wtf/SoftLinking.h>

// Get CoreLocation classes
SOFT_LINK_FRAMEWORK(CoreLocation)

SOFT_LINK_CLASS(CoreLocation, CLLocationManager)
SOFT_LINK_CLASS(CoreLocation, CLHeading)

// Get CoreMotion classes
SOFT_LINK_FRAMEWORK(CoreMotion)

SOFT_LINK_CLASS(CoreMotion, CMMotionManager)
SOFT_LINK_CLASS(CoreMotion, CMAccelerometerData)
SOFT_LINK_CLASS(CoreMotion, CMDeviceMotion)

static const double kGravity = 9.80665;

@interface WebCoreMotionManager(Private)

- (void)initializeOnMainThread;
- (void)checkClientStatus;
- (void)update;
- (void)sendAccelerometerData:(CMAccelerometerData *)newAcceleration;
- (void)sendMotionData:(CMDeviceMotion *)newMotion withHeading:(CLHeading *)newHeading;

@end

@implementation WebCoreMotionManager

+ (WebCoreMotionManager *)sharedManager
{
    static WebCoreMotionManager *sharedMotionManager = [[WebCoreMotionManager alloc] init];
    return sharedMotionManager;
}

- (id)init
{
    self = [super init];
    if (self)
        [self performSelectorOnMainThread:@selector(initializeOnMainThread) withObject:nil waitUntilDone:NO];

    return self;
}

- (void)dealloc
{
    if (WebCoreObjCScheduleDeallocateOnMainThread([WebCoreMotionManager class], self))
        return;

    ASSERT(!m_updateTimer);

    if (m_headingAvailable)
        [m_locationManager stopUpdatingHeading];

    if (m_gyroAvailable)
        [m_motionManager stopDeviceMotionUpdates];
    else
        [m_motionManager stopAccelerometerUpdates];

    [super dealloc];
}

- (void)addMotionClient:(WebCore::MotionManagerClient *)client
{
    m_deviceMotionClients.add(*client);
    if (m_initialized)
        [self checkClientStatus];
}

- (void)removeMotionClient:(WebCore::MotionManagerClient *)client
{
    m_deviceMotionClients.remove(*client);
    if (m_initialized)
        [self checkClientStatus];
}

- (void)addOrientationClient:(WebCore::MotionManagerClient *)client
{
    m_deviceOrientationClients.add(*client);
    if (m_initialized)
        [self checkClientStatus];
}

- (void)removeOrientationClient:(WebCore::MotionManagerClient *)client
{
    m_deviceOrientationClients.remove(*client);
    if (m_initialized)
        [self checkClientStatus];
}

- (BOOL)gyroAvailable
{
    return m_gyroAvailable;
}

- (BOOL)headingAvailable
{
    return m_headingAvailable;
}

- (void)initializeOnMainThread
{
    ASSERT(!WebThreadIsCurrent());

    m_motionManager = adoptNS([allocCMMotionManagerInstance() init]);

    m_gyroAvailable = m_motionManager.get().deviceMotionAvailable;

    if (m_gyroAvailable)
        [m_motionManager setDeviceMotionUpdateInterval:kMotionUpdateInterval];
    else
        [m_motionManager setAccelerometerUpdateInterval:kMotionUpdateInterval];

    m_locationManager = adoptNS([allocCLLocationManagerInstance() init]);
    m_headingAvailable = [getCLLocationManagerClass() headingAvailable];

    m_initialized = YES;

    [self checkClientStatus];
}

- (void)checkClientStatus
{
    if (!pthread_main_np()) {
        [self performSelectorOnMainThread:_cmd withObject:nil waitUntilDone:NO];
        return;
    }

    // Since this method executes on the main thread, it should always be called
    // after the initializeOnMainThread method has run, and hence there should
    // be no chance that m_motionManager has not been created.
    ASSERT(m_motionManager);

    if (m_deviceMotionClients.computeSize() || m_deviceOrientationClients.computeSize()) {
        if (m_gyroAvailable)
            [m_motionManager startDeviceMotionUpdates];
        else
            [m_motionManager startAccelerometerUpdates];

        if (m_headingAvailable)
            [m_locationManager startUpdatingHeading];

        if (!m_updateTimer)
            m_updateTimer = [NSTimer scheduledTimerWithTimeInterval:kMotionUpdateInterval target:self selector:@selector(update) userInfo:nil repeats:YES];
    } else {
        [m_updateTimer invalidate];
        m_updateTimer = nil;

        if (m_gyroAvailable)
            [m_motionManager stopDeviceMotionUpdates];
        else
            [m_motionManager stopAccelerometerUpdates];

        if (m_headingAvailable)
            [m_locationManager stopUpdatingHeading];
    }
}

- (void)update
{
    // It's extremely unlikely that an update happens without an active
    // motion or location manager, but we should guard for this case just in case.
    if (!m_motionManager || !m_locationManager)
        return;
    
    // We should, however, guard for the case where the managers return nil data.
    CMDeviceMotion *deviceMotion = [m_motionManager deviceMotion];
    if (m_gyroAvailable && deviceMotion)
        [self sendMotionData:deviceMotion withHeading:[m_locationManager heading]];
    else {
        if (CMAccelerometerData *accelerometerData = [m_motionManager accelerometerData])
            [self sendAccelerometerData:accelerometerData];
    }
}

- (void)sendAccelerometerData:(CMAccelerometerData *)newAcceleration
{
    WebThreadRun(^{
        CMAcceleration accel = newAcceleration.acceleration;

        Vector<WeakPtr<WebCore::MotionManagerClient>> motionClients;
        motionClients.reserveInitialCapacity(m_deviceMotionClients.computeSize());
        for (auto& client : m_deviceMotionClients)
            motionClients.uncheckedAppend(client);

        for (auto& client : motionClients) {
            if (client)
                client->motionChanged(0, 0, 0, accel.x * kGravity, accel.y * kGravity, accel.z * kGravity, std::nullopt, std::nullopt, std::nullopt);
        }
    });
}

- (void)sendMotionData:(CMDeviceMotion *)newMotion withHeading:(CLHeading *)newHeading
{
    WebThreadRun(^{
        // Acceleration is user + gravity
        CMAcceleration userAccel = newMotion.userAcceleration;
        CMAcceleration gravity = newMotion.gravity;
        CMAcceleration totalAccel;
        totalAccel.x = userAccel.x + gravity.x;
        totalAccel.y = userAccel.y + gravity.y;
        totalAccel.z = userAccel.z + gravity.z;

        CMRotationRate rotationRate = newMotion.rotationRate;

        Vector<WeakPtr<WebCore::MotionManagerClient>> motionClients;
        motionClients.reserveInitialCapacity(m_deviceMotionClients.computeSize());
        for (auto& client : m_deviceMotionClients)
            motionClients.uncheckedAppend(client);
        
        for (auto& client : motionClients) {
            if (client)
                client->motionChanged(userAccel.x * kGravity, userAccel.y * kGravity, userAccel.z * kGravity, totalAccel.x * kGravity, totalAccel.y * kGravity, totalAccel.z * kGravity, rad2deg(rotationRate.x), rad2deg(rotationRate.y), rad2deg(rotationRate.z));
        }

        CMAttitude* attitude = newMotion.attitude;

        Vector<WeakPtr<WebCore::MotionManagerClient>> orientationClients;
        orientationClients.reserveInitialCapacity(m_deviceOrientationClients.computeSize());
        for (auto& client : m_deviceOrientationClients)
            orientationClients.uncheckedAppend(client);
        
        // Compose the raw motion data to an intermediate ZXY-based 3x3 rotation
        // matrix (R) where [z=attitude.yaw, x=attitude.pitch, y=attitude.roll]
        // in the form:
        //
        //   /  R[0]   R[1]   R[2]  \
        //   |  R[3]   R[4]   R[5]  |
        //   \  R[6]   R[7]   R[8]  /

        double cX = cos(attitude.pitch);
        double cY = cos(attitude.roll);
        double cZ = cos(attitude.yaw);
        double sX = sin(attitude.pitch);
        double sY = sin(attitude.roll);
        double sZ = sin(attitude.yaw);

        double R[] = {
            cZ * cY - sZ * sX * sY,
            - cX * sZ,
            cY * sZ * sX + cZ * sY,
            cY * sZ + cZ * sX * sY,
            cZ * cX,
            sZ * sY - cZ * cY * sX,
            - cX * sY,
            sX,
            cX * cY
        };

        // Compute correct, normalized values for DeviceOrientation from
        // rotation matrix (R) according to the angle conventions defined in the
        // W3C DeviceOrientation specification.

        double zRot;
        double xRot;
        double yRot;

        if (R[8] > 0) {
            zRot = atan2(-R[1], R[4]);
            xRot = asin(R[7]);
            yRot = atan2(-R[6], R[8]);
        } else if (R[8] < 0) {
            zRot = atan2(R[1], -R[4]);
            xRot = -asin(R[7]);
            xRot += (xRot >= 0) ? -M_PI : M_PI;
            yRot = atan2(R[6], -R[8]);
        } else {
            if (R[6] > 0) {
                zRot = atan2(-R[1], R[4]);
                xRot = asin(R[7]);
                yRot = -M_PI_2;
            } else if (R[6] < 0) {
                zRot = atan2(R[1], -R[4]);
                xRot = -asin(R[7]);
                xRot += (xRot >= 0) ? -M_PI : M_PI;
                yRot = -M_PI_2;
            } else {
                zRot = atan2(R[3], R[0]);
                xRot = (R[7] > 0) ? M_PI_2 : -M_PI_2;
                yRot = 0;
            }
        }

        // Rotation around the Z axis (pointing up. normalized to [0, 360] deg).
        double alpha = rad2deg(zRot > 0 ? zRot : (M_PI * 2 + zRot));
        // Rotation around the X axis (top to bottom).
        double beta  = rad2deg(xRot);
        // Rotation around the Y axis (side to side).
        double gamma = rad2deg(yRot);

        double heading = (m_headingAvailable && newHeading) ? newHeading.magneticHeading : 0;
        double headingAccuracy = (m_headingAvailable && newHeading) ? newHeading.headingAccuracy : -1;

        for (size_t i = 0; i < orientationClients.size(); ++i) {
            if (orientationClients[i])
                orientationClients[i]->orientationChanged(alpha, beta, gamma, heading, headingAccuracy);
        }
    });
}

@end

#endif
