/// \file PinballGame/PinballSensor.h

/// \brief Process inputs from a single-channel analog pinball sensor such as a photoreflective pair.

/// \copyright No copyright, 2016, Garth Zeglin.  This file is explicitly placed in the public domain.

/// \details This file contains support code for implementing input processing
/// for the Arduino pinball machine demo.

/****************************************************************/

class PinballSensor {

private:
  /// Number of the analog pin to use for input.  The hardware is assumed to be
  /// active-low, i.e., idling at a high voltage, and pulled low during an
  /// 'event'.
  int input_pin;

  /// Input sampling interval, in microseconds.
  long sampling_interval;
  
  /// Countdown to the next input measurement, in microseconds.
  long sample_timer;

  /// Most recent raw measurement.  The units are the 10-bit (0-1023) integer ADC value.
  int raw_input;

  /// Analog input threshold defining the trigger level for an 'event', in ADC units.
  int lower_threshold;

  /// Analog input threshold defining the trigger level for resetting.  The
  /// difference between upper_threshold and lower_threshold defines the
  /// 'deadband' of 'hysteresis' of the event detector.  Specified in ADC units.
  int upper_threshold;

  /// The current Boolean state of the input detector.
  bool active;

  /// A Boolean flag which has a true value only during the polling cycle in
  /// which an event begins.  This supports event-driven programming in which
  /// the sensor input causes another event to begin.
  bool triggered;

  /// Count of the total number of events observed.
  long event_count;

  /// Count of the total number of samples measured.
  long sample_count;
  
public:

  /// Constructor to initialize an instance of the class.
  PinballSensor(int pin);

  /// Update function to be called as frequently as possible to sample the pin
  /// and process the data.  It requires the number of microseconds elapsed
  /// since the last update.
  void update(unsigned long interval);

  /// Debugging function to print a representation of the current state to the serial port.
  void send_debug(void);

  /// Access function to return the current state.
  bool isTriggered(void) { return triggered; }
};

/****************************************************************/
