/*
 * Copyright (C) 2010 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 <stdint.h>
#include <sys/types.h>

#include <utils/Errors.h>
#include <utils/String8.h>
#include <utils/Flattenable.h>

#include <hardware/sensors.h>

#include <gui/Sensor.h>

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

Sensor::Sensor()
    : mHandle(0), mType(0),
      mMinValue(0), mMaxValue(0), mResolution(0),
      mPower(0), mMinDelay(0)
{
}

Sensor::Sensor(struct sensor_t const* hwSensor)
{
    mName = hwSensor->name;
    mVendor = hwSensor->vendor;
    mHandle = hwSensor->handle;
    mType = hwSensor->type;
    mMinValue = 0;                      // FIXME: minValue
    mMaxValue = hwSensor->maxRange;     // FIXME: maxValue
    mResolution = hwSensor->resolution;
    mPower = hwSensor->power;
    mMinDelay = hwSensor->minDelay;
}

Sensor::~Sensor()
{
}

const String8& Sensor::getName() const {
    return mName;
}

const String8& Sensor::getVendor() const {
    return mVendor;
}

int32_t Sensor::getHandle() const {
    return mHandle;
}

int32_t Sensor::getType() const {
    return mType;
}

float Sensor::getMinValue() const {
    return mMinValue;
}

float Sensor::getMaxValue() const {
    return mMaxValue;
}

float Sensor::getResolution() const {
    return mResolution;
}

float Sensor::getPowerUsage() const {
    return mPower;
}

int32_t Sensor::getMinDelay() const {
    return mMinDelay;
}

nsecs_t Sensor::getMinDelayNs() const {
    return getMinDelay() * 1000;
}

int32_t Sensor::getVersion() const {
    return mVersion;
}

size_t Sensor::getFlattenedSize() const
{
    return  sizeof(int32_t) + ((mName.length() + 3) & ~3) +
            sizeof(int32_t) + ((mVendor.length() + 3) & ~3) +
            sizeof(int32_t) * 2 +
            sizeof(float) * 4 +
            sizeof(int32_t);
}

size_t Sensor::getFdCount() const
{
    return 0;
}

static inline
size_t write(void* buffer, size_t offset, const String8& value) {
    memcpy(static_cast<char*>(buffer) + offset, value.string(), value.length());
    return (value.length() + 3) & ~3;
}

static inline
size_t write(void* buffer, size_t offset, float value) {
    *reinterpret_cast<float*>(static_cast<char*>(buffer) + offset) = value;
    return sizeof(float);
}

static inline
size_t write(void* buffer, size_t offset, int32_t value) {
    *reinterpret_cast<int32_t*>(static_cast<char*>(buffer) + offset) = value;
    return sizeof(int32_t);
}

status_t Sensor::flatten(void* buffer, size_t size,
        int fds[], size_t count) const
{
    if (size < Sensor::getFlattenedSize())
        return -ENOMEM;

    size_t offset = 0;
    offset += write(buffer, offset, int32_t(mName.length()));
    offset += write(buffer, offset, mName);
    offset += write(buffer, offset, int32_t(mVendor.length()));
    offset += write(buffer, offset, mVendor);
    offset += write(buffer, offset, mHandle);
    offset += write(buffer, offset, mType);
    offset += write(buffer, offset, mMinValue);
    offset += write(buffer, offset, mMaxValue);
    offset += write(buffer, offset, mResolution);
    offset += write(buffer, offset, mPower);
    offset += write(buffer, offset, mMinDelay);

    return NO_ERROR;
}

static inline
size_t read(void const* buffer, size_t offset, String8* value, int32_t len) {
    value->setTo(static_cast<char const*>(buffer) + offset, len);
    return (len + 3) & ~3;
}

static inline
size_t read(void const* buffer, size_t offset, float* value) {
    *value = *reinterpret_cast<float const*>(static_cast<char const*>(buffer) + offset);
    return sizeof(float);
}

static inline
size_t read(void const* buffer, size_t offset, int32_t* value) {
    *value = *reinterpret_cast<int32_t const*>(static_cast<char const*>(buffer) + offset);
    return sizeof(int32_t);
}

status_t Sensor::unflatten(void const* buffer, size_t size,
        int fds[], size_t count)
{
    int32_t len;
    size_t offset = 0;
    offset += read(buffer, offset, &len);
    offset += read(buffer, offset, &mName, len);
    offset += read(buffer, offset, &len);
    offset += read(buffer, offset, &mVendor, len);
    offset += read(buffer, offset, &mHandle);
    offset += read(buffer, offset, &mType);
    offset += read(buffer, offset, &mMinValue);
    offset += read(buffer, offset, &mMaxValue);
    offset += read(buffer, offset, &mResolution);
    offset += read(buffer, offset, &mPower);
    offset += read(buffer, offset, &mMinDelay);

    return NO_ERROR;
}

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