/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "SensorDevice.h"
#include "SensorFusion.h"
#include "SensorService.h"

#include <android/util/ProtoOutputStream.h>
#include <cutils/properties.h>
#include <frameworks/base/core/proto/android/service/sensor_service.proto.h>

namespace android {
// ---------------------------------------------------------------------------

ANDROID_SINGLETON_STATIC_INSTANCE(SensorFusion)

SensorFusion::SensorFusion()
    : mSensorDevice(SensorDevice::getInstance()),
      mAttitude(mAttitudes[FUSION_9AXIS]),
      mGyroTime(0), mAccTime(0)
{
    sensor_t const* list;
    Sensor uncalibratedGyro;
    ssize_t count = mSensorDevice.getSensorList(&list);

    mEnabled[FUSION_9AXIS] = false;
    mEnabled[FUSION_NOMAG] = false;
    mEnabled[FUSION_NOGYRO] = false;

    if (count > 0) {
        for (size_t i=0 ; i<size_t(count) ; i++) {
            // Only use non-wakeup sensors
            if ((list[i].flags & SENSOR_FLAG_WAKE_UP) == 0) {
                if (list[i].type == SENSOR_TYPE_ACCELEROMETER) {
                    mAcc = Sensor(list + i);
                }
                if (list[i].type == SENSOR_TYPE_MAGNETIC_FIELD) {
                    mMag = Sensor(list + i);
                }
                if (list[i].type == SENSOR_TYPE_GYROSCOPE) {
                    mGyro = Sensor(list + i);
                }
                if (list[i].type == SENSOR_TYPE_GYROSCOPE_UNCALIBRATED) {
                    uncalibratedGyro = Sensor(list + i);
                }
            }
        }

        // Use the uncalibrated gyroscope for sensor fusion when available
        if (uncalibratedGyro.getType() == SENSOR_TYPE_GYROSCOPE_UNCALIBRATED) {
            mGyro = uncalibratedGyro;
        }

        // Wearable devices will want to tune this parameter
        // to 100 (Hz) in device.mk to save some power.
        int32_t value = property_get_int32(
            "sensors.aosp_low_power_sensor_fusion.maximum_rate", 200);
        mEstimatedGyroRate = static_cast<float>(value);
        mTargetDelayNs = 1000000000LL / mEstimatedGyroRate;

        for (int i = 0; i<NUM_FUSION_MODE; ++i) {
            mFusions[i].init(i);
        }
    }
}

void SensorFusion::process(const sensors_event_t& event) {

    if (event.type == mGyro.getType()) {
        float dT;
        if ( event.timestamp - mGyroTime> 0 &&
             event.timestamp - mGyroTime< (int64_t)(5e7) ) { //0.05sec

            dT = (event.timestamp - mGyroTime) / 1000000000.0f;
            // here we estimate the gyro rate (useful for debugging)
            const float freq = 1 / dT;
            if (freq >= 100 && freq<1000) { // filter values obviously wrong
                const float alpha = 1 / (1 + dT); // 1s time-constant
                mEstimatedGyroRate = freq + (mEstimatedGyroRate - freq)*alpha;
            }

            const vec3_t gyro(event.data);
            for (int i = 0; i<NUM_FUSION_MODE; ++i) {
                if (mEnabled[i]) {
                    // fusion in no gyro mode will ignore
                    mFusions[i].handleGyro(gyro, dT);
                }
            }
        }
        mGyroTime = event.timestamp;
    } else if (event.type == SENSOR_TYPE_MAGNETIC_FIELD) {
        const vec3_t mag(event.data);
        for (int i = 0; i<NUM_FUSION_MODE; ++i) {
            if (mEnabled[i]) {
                mFusions[i].handleMag(mag);// fusion in no mag mode will ignore
            }
        }
    } else if (event.type == SENSOR_TYPE_ACCELEROMETER) {
        float dT;
        if ( event.timestamp - mAccTime> 0 &&
             event.timestamp - mAccTime< (int64_t)(1e8) ) { //0.1sec
            dT = (event.timestamp - mAccTime) / 1000000000.0f;

            const vec3_t acc(event.data);
            for (int i = 0; i<NUM_FUSION_MODE; ++i) {
                if (mEnabled[i]) {
                    mFusions[i].handleAcc(acc, dT);
                    mAttitudes[i] = mFusions[i].getAttitude();
                }
            }
        }
        mAccTime = event.timestamp;
    }
}

template <typename T> inline T min(T a, T b) { return a<b ? a : b; }
template <typename T> inline T max(T a, T b) { return a>b ? a : b; }

status_t SensorFusion::activate(int mode, void* ident, bool enabled) {

    ALOGD_IF(DEBUG_CONNECTIONS,
            "SensorFusion::activate(mode=%d, ident=%p, enabled=%d)",
            mode, ident, enabled);

    const ssize_t idx = mClients[mode].indexOf(ident);
    if (enabled) {
        if (idx < 0) {
            mClients[mode].add(ident);
        }
    } else {
        if (idx >= 0) {
            mClients[mode].removeItemsAt(idx);
        }
    }

    const bool newState = mClients[mode].size() != 0;
    if (newState != mEnabled[mode]) {
        mEnabled[mode] = newState;
        if (newState) {
            mFusions[mode].init(mode);
        }
    }

    mSensorDevice.activate(ident, mAcc.getHandle(), enabled);
    if (mode != FUSION_NOMAG) {
        mSensorDevice.activate(ident, mMag.getHandle(), enabled);
    }
    if (mode != FUSION_NOGYRO) {
        mSensorDevice.activate(ident, mGyro.getHandle(), enabled);
    }

    return NO_ERROR;
}

status_t SensorFusion::setDelay(int mode, void* ident, int64_t ns) {
    // Call batch with timeout zero instead of setDelay().
    if (ns > (int64_t)5e7) {
        ns = (int64_t)(5e7);
    }
    mSensorDevice.batch(ident, mAcc.getHandle(), 0, ns, 0);
    if (mode != FUSION_NOMAG) {
        mSensorDevice.batch(ident, mMag.getHandle(), 0, ms2ns(10), 0);
    }
    if (mode != FUSION_NOGYRO) {
        mSensorDevice.batch(ident, mGyro.getHandle(), 0, mTargetDelayNs, 0);
    }
    return NO_ERROR;
}


float SensorFusion::getPowerUsage(int mode) const {
    float power =   mAcc.getPowerUsage() +
                    ((mode != FUSION_NOMAG) ? mMag.getPowerUsage() : 0) +
                    ((mode != FUSION_NOGYRO) ? mGyro.getPowerUsage() : 0);
    return power;
}

int32_t SensorFusion::getMinDelay() const {
    return mAcc.getMinDelay();
}

void SensorFusion::dump(String8& result) const {
    const Fusion& fusion_9axis(mFusions[FUSION_9AXIS]);
    result.appendFormat("9-axis fusion %s (%zd clients), gyro-rate=%7.2fHz, "
            "q=< %g, %g, %g, %g > (%g), "
            "b=< %g, %g, %g >\n",
            mEnabled[FUSION_9AXIS] ? "enabled" : "disabled",
            mClients[FUSION_9AXIS].size(),
            mEstimatedGyroRate,
            fusion_9axis.getAttitude().x,
            fusion_9axis.getAttitude().y,
            fusion_9axis.getAttitude().z,
            fusion_9axis.getAttitude().w,
            length(fusion_9axis.getAttitude()),
            fusion_9axis.getBias().x,
            fusion_9axis.getBias().y,
            fusion_9axis.getBias().z);

    const Fusion& fusion_nomag(mFusions[FUSION_NOMAG]);
    result.appendFormat("game fusion(no mag) %s (%zd clients), "
            "gyro-rate=%7.2fHz, "
            "q=< %g, %g, %g, %g > (%g), "
            "b=< %g, %g, %g >\n",
            mEnabled[FUSION_NOMAG] ? "enabled" : "disabled",
            mClients[FUSION_NOMAG].size(),
            mEstimatedGyroRate,
            fusion_nomag.getAttitude().x,
            fusion_nomag.getAttitude().y,
            fusion_nomag.getAttitude().z,
            fusion_nomag.getAttitude().w,
            length(fusion_nomag.getAttitude()),
            fusion_nomag.getBias().x,
            fusion_nomag.getBias().y,
            fusion_nomag.getBias().z);

    const Fusion& fusion_nogyro(mFusions[FUSION_NOGYRO]);
    result.appendFormat("geomag fusion (no gyro) %s (%zd clients), "
            "gyro-rate=%7.2fHz, "
            "q=< %g, %g, %g, %g > (%g), "
            "b=< %g, %g, %g >\n",
            mEnabled[FUSION_NOGYRO] ? "enabled" : "disabled",
            mClients[FUSION_NOGYRO].size(),
            mEstimatedGyroRate,
            fusion_nogyro.getAttitude().x,
            fusion_nogyro.getAttitude().y,
            fusion_nogyro.getAttitude().z,
            fusion_nogyro.getAttitude().w,
            length(fusion_nogyro.getAttitude()),
            fusion_nogyro.getBias().x,
            fusion_nogyro.getBias().y,
            fusion_nogyro.getBias().z);
}

void SensorFusion::dumpFusion(FUSION_MODE mode, util::ProtoOutputStream* proto) const {
    using namespace service::SensorFusionProto::FusionProto;
    const Fusion& fusion(mFusions[mode]);
    proto->write(ENABLED, mEnabled[mode]);
    proto->write(NUM_CLIENTS, (int)mClients[mode].size());
    proto->write(ESTIMATED_GYRO_RATE, mEstimatedGyroRate);
    proto->write(ATTITUDE_X, fusion.getAttitude().x);
    proto->write(ATTITUDE_Y, fusion.getAttitude().y);
    proto->write(ATTITUDE_Z, fusion.getAttitude().z);
    proto->write(ATTITUDE_W, fusion.getAttitude().w);
    proto->write(ATTITUDE_LENGTH, length(fusion.getAttitude()));
    proto->write(BIAS_X, fusion.getBias().x);
    proto->write(BIAS_Y, fusion.getBias().y);
    proto->write(BIAS_Z, fusion.getBias().z);
}

/**
 * Dump debugging information as android.service.SensorFusionProto protobuf message using
 * ProtoOutputStream.
 *
 * See proto definition and some notes about ProtoOutputStream in
 * frameworks/base/core/proto/android/service/sensor_service.proto
 */
void SensorFusion::dump(util::ProtoOutputStream* proto) const {
    uint64_t token = proto->start(service::SensorFusionProto::FUSION_9AXIS);
    dumpFusion(FUSION_9AXIS, proto);
    proto->end(token);

    token = proto->start(service::SensorFusionProto::FUSION_NOMAG);
    dumpFusion(FUSION_NOMAG, proto);
    proto->end(token);

    token = proto->start(service::SensorFusionProto::FUSION_NOGYRO);
    dumpFusion(FUSION_NOGYRO, proto);
    proto->end(token);
}

// ---------------------------------------------------------------------------
}; // namespace android
