#ifndef VRPN_SPACEBALL_H
#define VRPN_SPACEBALL_H

#include "vrpn_Analog.h"                // for vrpn_Serial_Analog
#include "vrpn_Button.h"                // for vrpn_Button_Filter
#include "vrpn_Configure.h"             // for VRPN_API
#include "vrpn_Connection.h"            // for vrpn_CONNECTION_LOW_LATENCY, etc
#include "vrpn_Shared.h"                // for timeval
#include "vrpn_Types.h"                 // for vrpn_uint32

class VRPN_API vrpn_Spaceball: public vrpn_Serial_Analog
			,public vrpn_Button_Filter
{
  public:
	vrpn_Spaceball (const char * name, vrpn_Connection * c,
			const char * port, int baud);

	~vrpn_Spaceball () {};

	/// Called once through each main loop iteration to handle updates.
	virtual void mainloop ();

	virtual int reset(void);  ///< Set device back to starting config

  protected:
	int _numbuttons;          ///< How many buttons to open
	int _numchannels;         ///< How many analog channels to open
	unsigned char buf[512];	  ///< Buffer of characters in report,
	int bufpos;               ///< Current char pos in buffer 
        int packtype;             ///< What kind of packet we are decoding
        int packlen;              ///< Expected packet length
        int escapedchar;          ///< We're processing an escaped char
        int erroroccured;         ///< A device error has occurred
        int resetoccured;         ///< A reset event has occurred
        int spaceball4000;        ///< We found a Spaceball 4000
        int leftymode4000;        ///< Spaceball 4000 is in lefty mode
	int null_radius;          ///< range where no motion should be reported
	struct timeval timestamp; ///< Time of the last report from the device

	virtual	void clear_values(void); ///< Set all buttons, analogs and encoders back to 0

	/// Try to read reports from the device.  Returns 1 if a complete 
        /// report received, 0 otherwise.  Sets status to current mode.
	virtual	int get_report(void);

	/// send report iff changed
        virtual void report_changes
                   (vrpn_uint32 class_of_service
                    = vrpn_CONNECTION_LOW_LATENCY);

        /// send report whether or not changed
        virtual void report
                   (vrpn_uint32 class_of_service
                    = vrpn_CONNECTION_LOW_LATENCY);

        // NOTE:  class_of_service is only applied to vrpn_Analog
        //  values, not vrpn_Button, which are always vrpn_RELIABLE
};

#endif
