#ifndef LIGHTSENSOR_H
#define LIGHTSENSOR_H

#ifndef __SERSENSOR_H
#include <iwear-ser_sensor/sersensor.h>
#endif

#ifndef __SENSORHANDLER_H
#include <iwsens/sensorhandler.h>
#endif

#ifndef __CONSTANTS_H
#include <iwear/constants.h>
#endif

#ifndef __DATASENSOR_H
#include <iwsens/datasensor.h>
#endif

#ifndef __SENSOR_ENUM_H
#include <iwsens/sensor_enum.h>
#endif

#define VERBOSE_LIGHTSENSOR false
#define DUMMY_LIGHTSENSOR false

#define LIGHTSENSOR_STD_SCALE_UNIT LUX
#define LIGHTSENSOR_STD_PRIORITY 0

#ifndef ERROR_VALUE
#define ERROR_VALUE -1000000.0
#endif

#ifndef FALSE_VALUE
#define FALSE_VALUE -99999.0
#endif

#ifndef FOLD_STRING
#define FOLD_OPEN "{{{"
#define FOLD_CLOSE "}}}"
#endif

namespace iwear
{
    namespace sensor
    {
class SensorHandler;

/**
   * This class offers methods to get measure data of light sensor which
   * is connected at the ser_sensor serial sensor device. There's the
   * possibility of select the scale unit to which the measure data should
   * be calculated at. The commonness of the inquiry of this sensor can be
   * adjusted by priorizations compared with other sensors attached at this
   * equipment. With an additional method it could be tested if this sensor
   * is also connected at the serial sensor device.
   * @author Daniel Dahme, Uwe Krüger, Falko Buttler
   */
  class LightSensor: public DataSensor, public ser_sensor::SerSensor {

private:
    units unit;
    FilterMode filtermode;
    double filter_param;
    double actValue;
protected:
public:
     /**
     * Constructor to get an instance of the LightSensor class
     * @param myfilter_param Parameter for the used filter. On FILTER_LINEAR it
     * is the strength of the allowed fluctuation. On FILTER_HISTORY it is  the
     * size of the used history).
     */
    LightSensor( SensorHandler*, units myunit,
                                     FilterMode mymode = FILTER_LINEAR,
                                     double myfilter_param = 0,
                                     char* device = "/dev/ttyS0" );

    /**
     * Destructor to destroy an instance of the TemperatureSensor class
     */
    virtual ~LightSensor();

    /**
     * Returns the actual temperature of this sensor in an given unit
     */
    virtual double get_value( void ) const;

    /**
     * Returns the last valid temperature together with the timestamp of the value
     */
    virtual std::pair<double,timeval> get_valuetime( void ) const;

    /**
     * TemperatureSensor is measured in a given unit
     */
    virtual units get_unit( void ) const { return unit; }

    /**
     * We know about the time so we tell it.
     */
    virtual datasensor_type get_datasensor_type( void ) const { return brightness; }

    /**
     * Module requires us to implement this. But we dont have one so just
     * return succes.
     */
    virtual uint32_t activate_power_state( power_state ) { return 0; }

    /**
     * Check if this Sensor is connected at the serial sensor device.
     * @return true, if the sensor is connected at one of the six
     * sensor ports of the serial sensor device, false otherwise.
     */
    bool sensor_connected() const;

    /**
     * Select the unit, in which measured values are to be returned.
     * Measured values will be converted according to the unit.
     * @param new_scale_unit The unit, in which a measured value is
     * to be returned.
     */
    void set_scale_unit(units new_scale_unit);

    /**
     * Set the priority for this sensor. This method adjusts, how
     * often the sensor is to be queried for a new measured value.
     * The last finite frequency of the inquiries arises as a result of the
     * priorities of all sensors. The priority gradates only the sensor
     * thereupon in, how quickly measured values could change.
     * @param new_priority The priority of this sensor. The bigger this value,
     * the rarer the inqueries.
     */
    void set_priority(int new_priority) const;

    /**
     * Get the measured data of this sensor
     * @return The measure data of this sensor, calculated at the selected
     * scale unit; ERROR_VALUE if the sensor isn't connected at the device or
     * if there's still no buffered data of this sensor, because it has been
     * just connected.
     */
    double get_measured_data() const;

  private:

    /**
     * Calculate the measure data from the digital data the serial sensor
     * device provides.
     * @param digital The digital interpretation of the measure data,
     * normally a value between 0 and 1023.
     * @return The measure value at the selected scale unit
     */
    double calc_measure_data(int digital) const;

    /**
     * The selected scale unit of the measure data
     */
    units scale_unit;

    /**
     * The selected priority of this sensor
     */
    mutable int priority;

    /**
     * The last valid value of this sensor
     */
    mutable std::pair<double,timeval> last_valid_value;
};

} // namespace sensor
} // namespace iwear

#endif /*LIGHTSENSOR_H*/

