#include "fDigitsSegtPin2.h"

class StopWatch : public fDigitsSegtPin
{
  public:
  StopWatch(u8 vPf1, u8 vPf2, u8 vPf3, u8 vPf4, u8 vPf5, u8 vPf6, u8 vPf7, u8 vPf8, u8 vPf9, u8 vPf10, u8 vPf11, u8 vPf12) : 
fDigitsSegtPin(vPf1, vPf2, vPf3, vPf4, vPf5, vPf6, vPf7, vPf8, vPf9, vPf10, vPf11, vPf12)
  {
    _working = false;
    _curTime = 0;
    _startTime = 0;
    _deltaStopTime = 0;
  }

  void print()
  {
    if(_working)
    {
      int addTime = millis() - _startTime;
      if(addTime >= 1000)
      {
        _startTime = _startTime + 1000;//в миллисекундах
        _curTime = _curTime + 0.01;
        if(_curTime - (int)(_curTime) > 0.59)
        {
          _curTime = _curTime + 1 - 0.60;          
        }
        if(_curTime > 59)
        {
          _curTime -= 60;
        }
        
      }
      fDigitsSegtPin::print(_curTime + 0.001);//1 секунда = 0.01 на циферблате
      //поправка 0.001 введена из-за погрешности float      
    }
    else
    {
      fDigitsSegtPin::print(_curTime + 0.001);//1 секунда = 0.01 на циферблате
      //поправка 0.001 введена из-за погрешности float
    }    
  }

  void startStop()
  {
    if(_working)
    {
      _deltaStopTime = millis() - _startTime;
      _working = false;
    }
    else
    {
      _startTime = millis() - _deltaStopTime;
      _working = true;      
    }
  }

  void reset()
  {
    if(!_working)
    {
    _curTime = 0;
    _deltaStopTime = 0;
    }
  }

  private:
    bool _working;
    float _curTime;
    unsigned long _startTime;
    int _deltaStopTime;
};

template<typename T>
class Button
{
public:
  Button(T* indicator, void (T::*action)(void), int pinB)
  {
    _indicator = indicator;
    _action =action;
    _lastButton = LOW;
    _curButton = LOW;
    _pinButton = pinB;
    pinMode(pinB, INPUT_PULLUP);
  }

  ~Button() = default;

  void process()
  {
    _curButton = debounce();
    if (_lastButton == HIGH && _curButton == LOW)
    {
      (_indicator->*_action)();
    }
    _lastButton = _curButton;
  }

private:
  T* _indicator;
  void (T::*_action)(void);
  int _lastButton;
  int _curButton;
  int _pinButton;

  int debounce ()
  {
    int current = digitalRead(_pinButton);
    if(_lastButton != current)
    {
      delay(5);
      current = digitalRead(_pinButton);
    }
    return current;
  }
};

StopWatch stopWatch(4, 3, 7, 2, 6, 11, 7, 10, 9, 5, 0, 8);
Button<StopWatch> startStopButton(&stopWatch, &StopWatch::startStop, 12);
Button<StopWatch> resetButton(&stopWatch, &StopWatch::reset, 13);


void setup() {
  stopWatch.doPrint_firstZero = 1;
  stopWatch.begin();
}  
  

void loop() 
{  
  startStopButton.process();
  resetButton.process();
  stopWatch.print();  
}
uno:A5.2
uno:A4.2
uno:AREF
uno:GND.1
uno:13
uno:12
uno:11
uno:10
uno:9
uno:8
uno:7
uno:6
uno:5
uno:4
uno:3
uno:2
uno:1
uno:0
uno:IOREF
uno:RESET
uno:3.3V
uno:5V
uno:GND.2
uno:GND.3
uno:VIN
uno:A0
uno:A1
uno:A2
uno:A3
uno:A4
uno:A5
r1:1
r1:2
r2:1
r2:2
r3:1
r3:2
r4:1
r4:2
r5:1
r5:2
r6:1
r6:2
r7:1
r7:2
sevseg1:A
sevseg1:B
sevseg1:C
sevseg1:D
sevseg1:E
sevseg1:F
sevseg1:G
sevseg1:DP
sevseg1:DIG1
sevseg1:DIG2
sevseg1:DIG3
sevseg1:DIG4
sevseg1:COM
sevseg1:CLN
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r
btn2:1.l
btn2:2.l
btn2:1.r
btn2:2.r