
using namespace std;

class sensors
{
    public:
        sensors();
        void startupSensors();  // run at startup
        void readSensors();  // continually read state of sensors
        short getStatus(short pinID);  // get status of sensor
        bool checkIf1wire(short gpio);  // check if sensor port is 1wire - used to manage DS18B20 1wire buses
        void compileSensorJson();  // compile data to be sent to front end
    private:
        short sensorPinID[30] = {};  // unique  
        short sensorPin[30] = {};  // pin number
        short sensorDriver[30] = {};  // driverID
        short sensorPinTypeID[30] = {};  // pinTypeID
        short sensorStatus[30] = {};  // outlet status
        short sensorInvert[30] = {};  // track if logic is inverted
        short sensorTotal = 0;  // total sensors found
};
sensors::sensors(){}

void sensors::compileSensorJson() {  // compile data to be sent to front end
    for(short a=0; a < sensorTotal; a++) {  // get pinID and status of each outlet
        outgoingDataString += "{\"id\":\"";
        outgoingDataString += to_string(sensorPinID[a]);
        outgoingDataString += "\",\"v\":\"";
        
        outgoingDataString += to_string(sensorStatus[a]);
        outgoingDataString += "\"}";
        if (a < sensorTotal - 1) outgoingDataString += ",";  // add comma if another sensor is coming
    }
}

bool sensors::checkIf1wire(short gpio) {  // check if sensor port is 1wire - used to manage DS18B20 1wire buses
    // short arrayID = 0;
    // for(short a=0; a < sensorTotal; a++) {  //
    //     if (sensorPin[a] == gpio) {arrayID = a; break;}
    // }
    // return sensorPinTypeID[arrayID];

    bool f = 0;  // used to check if sensor port is 1wire
    short p = 0;  // pinTypeID

    MYSQL_RES *res;
    MYSQL_ROW row;
    
    connectMysql();
    std::string query = "SELECT pinTypeID FROM pinsAvailable WHERE gpio = '" + to_string(gpio) + "'";  // construct query string

    mysql_query(conn, query.c_str());  // run query

    res = mysql_use_result(conn);
    while ((row = mysql_fetch_row(res)) != NULL)
    {
        p = atoi(row[0]);
    }
    mysql_disconnect(); 
    mysql_free_result(res);
    
    if (p == 5) {return 1;}
    else {return 0;}
}

short sensors::getStatus(short pinID) {  // get calRunning status
    short arrayID = 0;
    for(short a=0; a < sensorTotal; a++) {  //
        if (sensorPinID[a] == pinID) {arrayID = a; break;}
    }
    return sensorStatus[arrayID];
}

void sensors::readSensors() {  // continually read state of sensors
    for(short a=0; a < sensorTotal; a++) {  // read all sensors
        if (sensorDriver[a] == 2) {
            sensorStatus[a] = digitalRead(sensorPin[a]);
            // delay(10);
            if (sensorInvert[a] == 1) {
                if (sensorStatus[a] == 0) {sensorStatus[a] = 1;}
                else {sensorStatus[a] = 0;}
            }
        }
    }
    // std::cout << "sensorStatus     - " << sensorStatus[0] << std::endl;
    // delay(1000);
}

void sensors::startupSensors() {  // run at startup
	if (startupComplete == 0) {
        std::cout << " " << std::endl;
        std::cout << "startupSensors------------------------------" << std::endl;
    }

    std::fill_n(sensorPinID, 30, 0);  // reset array
    std::fill_n(sensorDriver, 30, 0);  // reset array
    std::fill_n(sensorPin, 30, 0);  // reset array
    std::fill_n(sensorStatus, 30, 0);  // reset array
    std::fill_n(sensorInvert, 30, 0);  // reset array

    MYSQL_RES *res;
    MYSQL_ROW row;
    
    // Sensors
    connectMysql();
    std::string query = "SELECT pinID, driverID, gpio, pinTypeID, invert FROM pinsAvailable\
        WHERE pinTypeID = '6' AND assigned = '1'\
        OR pinTypeID = '7' AND assigned = '1'\
        OR pinTypeID = '8' AND assigned = '1'\
        OR pinTypeID = '9' AND assigned = '1'\
        OR pinTypeID = '14' AND assigned = '1'";  // construct query string

    mysql_query(conn, query.c_str());  // run query

    res = mysql_use_result(conn);
    sensorTotal = 0;
    while ((row = mysql_fetch_row(res)) != NULL)
    {
        sensorPinID[sensorTotal] = atoi(row[0]);
        sensorDriver[sensorTotal] = atoi(row[1]);
        sensorPin[sensorTotal] = atoi(row[2]);
        sensorPinTypeID[sensorTotal] = atoi(row[3]);
        sensorInvert[sensorTotal] = atoi(row[4]);
        pinMode(sensorPin[sensorTotal],INPUT);
        if (sensorDriver[sensorTotal] == 2) {sensorStatus[sensorTotal] = digitalRead(sensorPin[sensorTotal]);}
		if (startupComplete == 0) {
            std::cout << "gpio input     - " << sensorPinID[sensorTotal] << " - " << sensorDriver[sensorTotal] << " - " << sensorPin[sensorTotal] << " - " << sensorPinTypeID[sensorTotal] << std::endl;
        }
        sensorTotal++;
    }
    mysql_disconnect(); 
    mysql_free_result(res);
    
	if (startupComplete == 0) {
        std::cout << "sensorTotal        - " << sensorTotal << std::endl;
        std::cout << "----------------------------------------" << std::endl;
    }

}

sensors sensors;