/**
 * @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_DATASENSOREVENT_H
#define __IWSENS_DATASENSOREVENT_H

#ifndef __IWEAR_EVENTBASE_H
#include <iwear/eventbase.h>
#endif

#ifndef __IWEAR_FUNCTOR_H
#include <iwear/functor.h>
#endif

#include <climits>
#include <limits>
#include <cfloat>
using namespace std;

namespace iwear
{
    namespace sensor
    {
typedef DualFunctor<double,bool> DSEFunctor;

/**
 * This is the primary base class for events to be delivered in sensor handling stuff. 
 * @todo Think about threading. Usually, this should only be handled within the
 * service that checks sensor data. Everyone else should only check for the
 * triggered flag *without* setting a new value. So it should be pretty thread
 * save. In case it isnt, nothing will crash since we use doubles only, and
 * some bools... 
 */
class DataSensorEvent : public Event<DSEFunctor>
{
friend class SensorHandler;
private:
protected:
    double event_value;

    double lower_bound;
    double upper_bound;

    /**
     * True if the last state asked for was "triggered". Means entered to be
     * monitored interval. In case its false, the monitored interval was
     * leaved.
     */
    bool last_state : 1;
    bool need_dispatch : 1;
    mutable bool need_deliver : 1;
    
public:
    virtual ~DataSensorEvent();
    virtual void dispatch( void );

    /**
     * This returns true if we need to deliver the event. It will reset the
     * flag internally so it can be only asked for once, and if its true then,
     * it should be passed to the eventdispatcher.
     */
    inline bool deliver_needed( void ) const { bool ret = need_deliver;
						need_deliver = false; return ret; }

    virtual bool is_triggered( void );

    virtual bool is_triggered( double val, bool override = false );

    /**
     * Possible Intervals :
     *
     * - [x,y]
     * - [x,y[    
     * - ]x,y]
     * - ]x,y[
     * - ]INF,y]
     * - ]INF,y[
     * - [x,INF[    
     * - ]x,INF[
     *
     * But e.g. if you want to have ]10 you can put 9.999999 since sensor data
     * will never be as accurate as this
     *
     * Per default the bounds are ] -INF, INF [
     */
    DataSensorEvent( DSEFunctor&, 
	    double low = - numeric_limits<double>::max(), double up = numeric_limits<double>::max() );
};

}
}
#endif
