#pragma once

#include <Automaton.h>
#include <TeensyStep.h>
// #include <AccelStepper.h>
class Atm_TeensyStep: public Machine {

 public:
  enum { IDLE, READY, RUNNING, STOPPING }; // STATES
  enum { EVT_IDLE_TIMER, EVT_ON_TARGET, EVT_GOTO, ELSE }; // EVENTS
  Atm_TeensyStep( void ) : Machine()  {};
  Atm_TeensyStep& begin( Stepper & motorRef , StepControl & stepControlRef ) ;

  Atm_TeensyStep& trace( Stream & stream );
  Atm_TeensyStep& trigger( int event );
  int state( void );
  Atm_TeensyStep& onOnchange( Machine& machine, int event = 0 );
  Atm_TeensyStep& onOnchange( atm_cb_push_t callback, int idx = 0 );
  int enable_timeout; //in idle mode, how long before sleep (stepper disabled
  Atm_TeensyStep& setLimitType( int limitType = 0);
  Atm_TeensyStep& setLimitPins( int limitPinLow);
  Atm_TeensyStep& setLimitPins( int limitPinLow, int limitPinHigh);
  Atm_TeensyStep& limitReversed( bool reversed );
  Atm_TeensyStep& limitThresholds( int limitThreshold0, int limitThreshold1,
                                  int limitThreshold2, int limitThreshold3);
  Atm_TeensyStep& setEnablePin( int enablePin );
  Atm_TeensyStep& enableReversed( bool reverse );
  bool enabled ;
  Atm_TeensyStep& enable( bool enable );
  Atm_TeensyStep& home( bool limit ); // 0(default) for home, 1 for max value
  Atm_TeensyStep& move( long int stepRel );
  Atm_TeensyStep& moveTo( long int stepAbs );
  Atm_TeensyStep& stop();
  Atm_TeensyStep& emergencyStop();
  Stepper * motor;
  StepControl * controller;

  bool limitState[2] ; // up to two limits, at least one for homing
  bool homed; //stepper has been homed
  long int maxStep ;

 private:
  // AccelStepper _motor;
  // Stepper *_motor;       // STEP pin: 2, DIR pin: 3
  // StepControl _controller;

  enum { ENT_IDLE, EXT_IDLE, ENT_READY, ENT_RUNNING, LP_RUNNING,
          ENT_STOPPING, EXT_STOPPING }; // ACTIONS
  enum { ON_ONCHANGE, CONN_MAX }; // CONNECTORS
  atm_connector connectors[CONN_MAX];
  int event( int id );
  void action( int id );

  long int _currentStep ;
  long int _targetStep ;

  int _enablePin;
  bool _enableReversed ;



  int _limitPin[2];
  enum { NONE, DIGITAL_1, DIGITAL_2, ANALOG_1 };
  int _limitType; //type of limit switch, from list over
  bool _limitReversed ; //invert logic of limit switches
  int _limitThresholds[4] ; //analog value  range for two analog limits
  void updateLimitSwitch();
  bool _isHoming;
};

/*
Automaton::ATML::begin - Automaton Markup Language

<?xml version="1.0" encoding="UTF-8"?>
<machines>
  <machine name="Atm_stepper">
    <states>
      <IDLE index="0" on_enter="ENT_IDLE">
        <EVT_GOTO>RUNNING</EVT_GOTO>
      </IDLE>
      <READY index="1" on_enter="ENT_READY">
        <EVT_IDLE_TIMER>IDLE</EVT_IDLE_TIMER>
        <EVT_GOTO>RUNNING</EVT_GOTO>
      </READY>
      <RUNNING index="2" on_enter="ENT_RUNNING" on_loop="LP_RUNNING">
        <EVT_ON_TARGET>STOPPING</EVT_ON_TARGET>
        <EVT_GOTO>RUNNING</EVT_GOTO>
      </RUNNING>
      <STOPPING index="3" on_enter="ENT_STOPPING" on_exit="EXT_STOPPING">
        <EVT_ON_TARGET>READY</EVT_ON_TARGET>
      </STOPPING>
    </states>
    <events>
      <EVT_IDLE_TIMER index="0" access="PRIVATE"/>
      <EVT_ON_TARGET index="1" access="PRIVATE"/>
      <EVT_GOTO index="2" access="PUBLIC"/>
    </events>
    <connectors>
      <ONCHANGE autostore="0" broadcast="0" dir="PUSH" slots="1"/>
    </connectors>
    <methods>
    </methods>
  </machine>
</machines>

Automaton::ATML::end
*/
