#ifndef PERSWIFIMANAGER_H
#define PERSWIFIMANAGER_H

#if defined(ESP8266)
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#elif defined(ESP32)
#include <WiFi.h>
#include <WebServer.h>
#else
#error "Unknown board class"
#endif
#include <DNSServer.h>

// CONFIGURATION
//##define WIFI_HTM_PROGMEM
//#define WIFI_HTM_PATH "/wifi.htm"
//#define DEBUG
//#define DEBUG_2
// values in seconds - 0 to disable function
#define WIFI_CONNECT_TIMEOUT_STARTAP 45 //s
#define WIFI_CONNECT_TIMEOUT 30 //s
#define WIFI_AP_TIMEOUT 5 //min
#define WIFI_CONNCHECK_INTERVAL 20 //s
#define WIFI_REBOOT_ON_NO_CONNECT_AFTER 0  //min
#define WIFI_FORCE_RETRY_WIFI1_INTERVAL 30 //min
//
#define SETWIFI_CONNECT_TRIES 1
// -------------

class PersWiFiManager {

  public:

    typedef std::function<void(void)> WiFiChangeHandlerFunction;

#if defined(ESP8266)
    PersWiFiManager(ESP8266WebServer& s, DNSServer& d);
#elif defined(ESP32)
    PersWiFiManager(WebServer& s, DNSServer& d);
#endif

    bool attemptConnection(const String& ssid = "", const String& pass = "");

    void setupWiFiHandlers();

    bool begin(const String& ssid = "", const String& pass = "");

    void resetSettings();

    String getApSsid();

    String getSsid();

    void setApCredentials(const String& apSsid, const String& apPass = "");
    void setApTimeout(int t);
    void setApStartAfter(int t);
    void setConnCheckInterval(int t);
    void setForceRetryWifi1Interval(int t);
    void setRebootOnNoConnect(int t);

    void setWifi1Credentials(const String& wSsid, const String& wPass = "");
    void setWifi2Credentials(const String& wSsid, const String& wPass = "");

    void setHttpCredentials(const String& user = "", const String& pass = "");

    void setConnectNonBlock(bool b);

    void setApModeAutostart(bool m);

    void handleWiFi();

    void startApMode();

    void stopApMode();

    void onConnect(WiFiChangeHandlerFunction fn);

    void onAp(WiFiChangeHandlerFunction fn);
    void onApOff(WiFiChangeHandlerFunction fn);

    int getActiveWiFiNum();

  private:
#if defined(ESP8266)
    ESP8266WebServer * _server;
#elif defined(ESP32)
    WebServer * _server;
#endif
    DNSServer * _dnsServer;
    String _apSsid, _apPass;
    String _w1Ssid, _w1Pass;
    String _w2Ssid, _w2Pass;
    String _httpUser, _httpPass;

    bool _connectNonBlock;
    unsigned long _connectStartTime;
    unsigned long _apStartTime;
    bool _freshConnectionAttempt;

    bool _useSetWifi1Credentials;
    bool _useSetWifi2Credentials;

    unsigned int _wifi1ConnectAttempts; // count connect attempts
    unsigned int _wifi2ConnectAttempts; // count connect attempts
    unsigned int _connectSetWifi; // stores which set Wifi (via setWifi[1|2]Credentials) was tried/connected latest
    unsigned long _lastSuccessfulConnect;
    bool _apModeFinished;

    unsigned int _apTimeout;
    unsigned int _apStartAfter;
    unsigned int _connCheckInterval;
    unsigned int _rebootOnNoConnectAfter;
    unsigned int _forceRetryWifi1Interval;

    unsigned long _lastRunHandleWifi;
    unsigned long _lastConnectionCheckOK;
    int _wifiLastState;
    int _wifiDisconnectedCounter;

    unsigned long _forceRetryWifi1LastTime;

    bool _apModeEnabled;
    bool _httpAuth;

    WiFiChangeHandlerFunction _connectHandler;
    WiFiChangeHandlerFunction _apHandler;
    WiFiChangeHandlerFunction _apOffHandler;

};//class

#endif
