/**
 * @file
 * $Id$
 * $Revision$
 * $Author$
 * $Date$
 *
 * This file is part of The iWear Framework.
 *
 * The iWear Framework is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by the
 * Free Software Foundation as in version 2 of the License.

 *
 * The iWear Framework is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * The iWear Framework; if not, write to the Free Software Foundation, Inc., 59
 * Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef __IWSENS_DATASENSOR_H
#define __IWSENS_DATASENSOR_H

#ifndef __IWSENS_SENSOR_H
#include <iwsens/sensor.h>
#endif

#include <deque>
using std::deque;
using std::make_pair;

extern "C" {
#include <sys/time.h>
}

namespace iwear
{
namespace sensor
{
class SensorHandler;

enum FilterMode {
    FILTER_LINEAR,
    FILTER_HISTORY,
    num_FilterMode
};
/**
 * The Sensor itself is a base class for all modules that should be handled by
 * the SensorHandler. The Sensors can give back values, whose interpretation
 * depends on the sensor type.
 */
class DataSensor : public Sensor
{
    friend class SensorHandler;
private:
    mutable double val_old;
    mutable deque<double> history;
protected:
    SensorHandler* SensHan;
public:
    DataSensor( SensorHandler* senshan );
    virtual ~DataSensor();

    virtual DataSensor* get_subsensor( uint32_t sb );

    virtual const DataSensor* get_subsensor( uint32_t sb ) const;

    virtual double get_subvalue( uint32_t sb ) const;

    /**
     * We are a DataSensor so we tell it.
     */
    virtual sensor_type get_sensor_type( void ) const { return data_sensor; }

    /**
     * There are several DataSensors so they return what they are, for
     * temperature, brightness etc.
     */
    virtual datasensor_type get_datasensor_type( void ) const = 0;

    /**
     * filter measure data against noise (linear)
     */
    virtual double filter_value( double value, double strength ) const;

    /**
     * filter measure data against noise (with history of N last values)
     * @deprecated
     */
    virtual double filter_value_historyOfN( double value, double historysize ) const;

    /**
     * Every of this DataSensors returns a value. We use only double here,
     * since a uint32_t also fits perfectly into a double.
     */
    virtual double get_value( void ) const = 0;

    /**
     * Gets a value with timestamp. The timestamp is per default now, but can
     * also be overridden by an implementing class, e.g. if it updates on a
     * regular base, like every second.
     */
    virtual std::pair<double,timeval> get_valuetime( void ) const
    {
        timeval now;
        gettimeofday(&now,NULL);
        return make_pair(get_value(),now);
    }

    virtual std::pair<double,timeval> get_subvaluetime( uint32_t ) const;

    /**
     * This returns a unit from iwear core library utility.h enums. Somewhere
     * in the iwear core there is a unit conversion function that
     * enable you to globally convert stuff to other values.
     */
    virtual units get_unit( void ) const = 0;

    virtual units get_subunit( uint32_t ) const;
};
} // namespace sensor
} // namespace iwear
#endif
