
function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
}

function featureNotAvailable() {  // popup saying feature isn't available yet
    $('#popupBackground').show();  // grey out background
    $('.ds18b20Popup-body').empty();
    ds18b20Popup.style.display = "block";
    document.querySelector("body").style.overflow = 'hidden';
    $('.ds18b20PopupHeader').empty();
    
    $(".ds18b20PopupHeader").append("Feature Not Available Yet");
    $(".ds18b20Popup-body").append(
        '<div style="text-align: center;">\
            <p>&nbsp;</p>\
            <p>Sorry this feature isn\'t available yet, stay tuned...</p>\
            <div class="widgetButtonBox">\
                <button class="button _wide" type="button" onclick="closeDs18b20Popup()">Close</button>\
            </div></br>\
        </div>');
}

function longDate(date) {  // format yyyy-mm-dd to long date
    const months = ["January","February","March","April","May","June","July","August","September","October","November","December"];
    date = date.replace(/-/g, " ");  // replace - with space

    const d = new Date(date);
    let month = months[d.getMonth()];
    let day = d.getDate();
    let year = d.getFullYear();

    return month + " " + day + ", " + year;
}

function printDateTime() {  // this is coming from the backend
    // update time on website
    // if (window.innerWidth < 750) {
    //     if (timeFormat == 0) {currentTime = moment().format('MM/DD/YY, HH:mm:ss');}
    //     else if (timeFormat == 1) {currentTime = moment().format('MM/DD/YY, h:mm:ss a');}
    // }
    // else {
    //     if (timeFormat == 0) {currentTime = moment().format('dddd - MMMM Do YYYY, HH:mm:ss');}
    //     else if (timeFormat == 1) {currentTime = moment().format('dddd - MMMM Do YYYY, h:mm:ss a');}
    // }
    
    // console.log('currentMillisTime = ' + currentMillisTime);
    var date = new Date(parseInt(currentMillisTime));
    // var options = {
    //         weekday: 'long', year: 'numeric', month: 'long', day: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric',
    //     };

    var w = { weekday: 'long' };
    var m = { month: 'long' };
    var d = { day: 'numeric' };
    var y = { year: 'numeric', hour: 'numeric', minute:'numeric', second:'numeric' };
    
    var result = date.toLocaleDateString('en', w) + " - " + date.toLocaleDateString('en', m) + " " + addSuffixToNumber(date.toLocaleDateString('en', d)) + " " + date.toLocaleDateString('en', y); // 10/29/2013
    // console.log('result            = ' + result);


    var options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric', hour: 'numeric', minute: '2-digit', second: '2-digit' };
    if (timeFormat == 0) {options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric', hour: '2-digit', hourCycle: 'h23', minute: '2-digit', second: '2-digit' };}

    result = date.toLocaleString("en-US", options);

    var myElem = document.getElementById('headerDatetime');
    if (myElem != null) {document.getElementById("headerDatetime").innerHTML = result;}
}

function incomingBackend(command){  // NOT USING
    console.log('sendToBackend------- ' + command);
    $.ajax({
        method: "GET",
        url: "/php/socketClient.php",
        cache: false,
        dataType: "json",
        data: {'v':command},
        success: function(dataWindow) {
            console.log("incomingBackend Success");
            console.log(dataWindow);

            var incomingData = JSON.parse(dataWindow);
            // console.log(incomingData);
            
            var test = incomingData.ds18b20[0].id;
            stopSendingData = 0;
            // console.log(test);

            // for(var i in incomingData) {  // go through outlet states to see if icons need updating
            // for (var i=0;i<incomingData.length;i++) {
            //     // previousOutletStatus[i] = outletStatus[i];  // record previous state
            //     // outletStatus[i] = (incomingData[i].s);  // record new state
            //     console.log('incomingData[i] = ' + incomingData[i]);
            //     // if (previousOutletStatus[i] != outletStatus[i]) outletUpdateIcon[i] = 1;  // check if outlet state change, flag to update icon
            // }
        },
        error: function(dataWindow) {
            stopSendingData = 1;
            console.log(dataWindow);
            console.log('error - incomingBackend');
        }
    });
}

function addSuffixToNumber(n) {
    let ord = ["st", "nd", "rd"]
    let exceptions = [11, 12, 13]
    let nth = 
    ord[(n % 10) - 1] == undefined || exceptions.includes(n % 100) ? "th" : ord[(n % 10) - 1]
    return n + nth
}

var retryCount = 0;
function sendDoseRequestToBackend(command) {  // using to send dosing pump status to update UI, need to replace with web socket sending command to frontend without request
    // console.log('sendDoseRequestToBackend------- ' + command);
    $.ajax({
        method: "GET",
        url: "/php/socketClient.php",
        cache: false,
        dataType: "json",
        data: {'v':command},
        success: function(dataWindow) {
            if (stopSendingData != 100) stopSendingData = 0;
            // console.log("sendDoseRequestToBackend Success");
            // console.log(dataWindow);

            try {
                var incomingData = JSON.parse(dataWindow);
                // console.log(incomingData);

                var length = 0;
                retryCount = 0;

                // Dosing ports
                try {length = Object.keys(incomingData.do).length;}  // check how many objects in array
                catch (e) {length = 0;}                
                for (var i=0; i < length; i++) {updateDosingStatus(incomingData.do[i].id, incomingData.do[i].v, incomingData.do[i].d);}  // update dosing status


            } catch (e) {}
        },
        error: function(dataWindow) {
            // console.log('error - sendDoseRequestToBackend = ' + command);
            // console.log(dataWindow);
        }
    });
}

function sendToBackend(command){  // send command to backend c++ program
    // console.log('sendToBackend------- ' + command);
    $.ajax({
        method: "GET",
        url: "/php/socketClient.php",
        cache: false,
        dataType: "json",
        data: {'v':command},
        success: function(dataWindow) {
            if (stopSendingData != 100) stopSendingData = 0;
            // console.log("sendToBackend Success");
            // console.log(dataWindow);

            try {
                var incomingData = JSON.parse(dataWindow);
                // console.log(incomingData);

                var length = 0;
                retryCount = 0;

                // DS18B20
                try {length = Object.keys(incomingData.ds18b20).length;}  // check how many objects in array
                catch (e) {length = 0;}                
                for (var i=0; i < length; i++) {DS18B20incoming(incomingData.ds18b20[i].id, incomingData.ds18b20[i].t, 0, incomingData.ds18b20[i].l, incomingData.ds18b20[i].h);}  // update DS18B20
                
                // DHT22
                try {length = Object.keys(incomingData.dht).length;}  // check how many objects in array
                catch (e) {length = 0;}                
                for (var i=0; i < length; i++) {DS18B20incoming(incomingData.dht[i].id, incomingData.dht[i].t, incomingData.dht[i].a, incomingData.dht[i].l, incomingData.dht[i].h);}  // update DHT22
                
                // Probes
                try {length = Object.keys(incomingData.probes).length;}  // check how many objects in array
                catch (e) {length = 0;}                
                for (var i=0; i < length; i++) {probesIncoming(incomingData.probes[i].id, incomingData.probes[i].v, incomingData.probes[i].l, incomingData.probes[i].h);}  // update probes
                
                // AC outlets
                try {length = Object.keys(incomingData.ac).length;}  // check how many objects in array
                catch (e) {length = 0;}
                for (var i=0; i < length; i++) {updateOutletStatus(incomingData.ac[i].id, incomingData.ac[i].v);}  // update AC status

                // DC ports
                try {length = Object.keys(incomingData.dc).length;}  // check how many objects in array
                catch (e) {length = 0;}                
                for (var i=0; i < length; i++) {updateDcStatus(incomingData.dc[i].id, incomingData.dc[i].v);}  // update DC status

                // sensor ports
                try {length = Object.keys(incomingData.s).length;}  // check how many objects in array
                catch (e) {length = 0;}                
                for (var i=0; i < length; i++) {updateSensorStatus(incomingData.s[i].id, incomingData.s[i].v);}  // update sensor status

                // Dosing ports
                try {length = Object.keys(incomingData.do).length;}  // check how many objects in array
                catch (e) {length = 0;}                
                for (var i=0; i < length; i++) {updateDosingStatus(incomingData.do[i].id, incomingData.do[i].v, incomingData.do[i].d);}  // update dosing status

                // info
                try {length = Object.keys(incomingData.in).length;}  // check how many objects in array
                catch (e) {length = 0;}
                for (var i=0; i < length; i++)  // incoming health meter, update and currentMillisTime
                {
                    health = incomingData.in[i].h;
                    updateAvailable = incomingData.in[i].u;
                    currentMillisTime = incomingData.in[i].t;
                }

                // lights
                try {length = Object.keys(incomingData.li).length;}  // check how many objects in array
                catch (e) {length = 0;}
                for (var i=0; i < length; i++) {updateLightModes();}  // update light modes
                
                // Confirm schedule was added or updated
                try {length = Object.keys(incomingData.sc).length;}  // check how many objects in array
                catch (e) {length = 0;}
                for (var i=0; i < length; i++) {confirmSchedule();}  // comfirm schedule was added or edited
                
                // Confirm custom rule was added or updated
                try {length = Object.keys(incomingData.r).length;}  // check how many objects in array
                catch (e) {length = 0;}
                for (var i=0; i < length; i++) {confirmRule();}  // comfirm schedule was added or edited


                // var date = new Date(parseInt(currentMillisTime));
                // console.log('date              = ' + date);

                // console.log('health = ' + health);
                checkForUpdate();
                updateHealthMeter();
                
                // transform:rotate(60deg);

            } catch (e) {}
        },
        error: function(dataWindow) {
            // console.log('error - sendToBackend = ' + command);
            if (command == 998) {  // reset and try again
                updateReady = 0;
                updateAvailable = 0;
                stopSendingData = 0;
                retryCount++;
                if (retryCount > 2) {
                    document.getElementById('needle').style.background = "#FF0000";
                    document.getElementById('needle').style.transform = "rotate(-90deg)";
                    document.getElementById("connectedIcon").src = "images/icons/disconn.png";
                }
            }
            else if (stopSendingData != 100) {sendToBackend(command);}  // if communication
            // console.log(dataWindow);
        }
    });
}

function tConvert (time) {  // convert time to 12 hour format
    if (timeFormat == 1) {
        // Check correct time format and split into components
        time = time.toString ().match (/^([01]\d|2[0-3])(:)([0-5]\d)(:[0-5]\d)?$/) || [time];

        if (time.length > 1) { // If time format correct
        time = time.slice (1);  // Remove full string match value
        time[5] = +time[0] < 12 ? ' AM' : ' PM'; // Set AM/PM
        time[0] = +time[0] % 12 || 12; // Adjust hours
        }
        return time.join (''); // return adjusted time or original string
    }
    else {
        return time; // return adjusted time or original string
    }
}

// function isThisANumber(n) { return !isNaN(parseFloat(n)) && !isNaN(n - 0) }  // check if variable is a number
function isThisANumber(n) {  // check if variable is a number
     let isnum = /^\d+$/.test(n); 
     return isnum;
}

function round(value, precision) {  
    if (Number.isInteger(precision)) {
      var shift = Math.pow(10, precision);
      // Limited preventing decimal issue
      return (Math.round( value * shift + 0.00000000000001 ) / shift);
    } else {
      return Math.round(value);
    }
} 

function updateHealthMeter(){  // update health meter
    document.getElementById("connectedIcon").src = "images/icons/conn.png";

    var healthNeedle = -90;
    healthNeedle = (health - 00) * 0.45;
    // console.log('healthNeedle = ' + healthNeedle);
    // console.log('health = ' + health);
    // 20 health during light fade

    if (healthNeedle < -50) {document.getElementById('needle').style.background = "#FF0000";}
    else {document.getElementById('needle').style.background = "#00ff00";}

    if (healthNeedle < -90) {healthNeedle = -90;}
    else if (healthNeedle > 90) {healthNeedle = 90;}
    
    if (health < 5) {healthNeedle = -85;}

    document.getElementById('needle').style.transform = "rotate(" + healthNeedle + "deg)";
    health = 0;
}

function secondsToTimeSplit(seconds){  // send command to backend c++ program
    
    var hours = Math.floor(seconds / (60 * 60));

    var divisor_for_minutes = seconds % (60 * 60);
    var minutes = Math.floor(divisor_for_minutes / 60);

    var divisor_for_seconds = divisor_for_minutes % 60;
    var seconds = Math.ceil(divisor_for_seconds);
    
    var nextMode = "";
    if (hours > 1) {nextMode = hours + "hrs, " + minutes + "mins, " + seconds + "secs";}
    console.log("" + hours + ":" + minutes + ":" + seconds);
    return nextMode;
}

function secondsToTime(seconds){  // send command to backend c++ program
    // console.log('seconds    = ' + seconds);
    if (seconds != undefined) {
        var date = new Date(null);
        date.setSeconds(seconds); // specify value for SECONDS here
        // console.log('date    = ' + date);
        var time = date.toISOString().substr(11, 8);
        // console.log('time  = ' + time);
        return time;
    }
}

function secondsFromTime(time) {
    // var hms = '02:04:33';   // your input string.
    var a = time.split(':'); // split it at the colons

    // minutes are worth 60 seconds. Hours are worth 60 minutes.
    var seconds = (+a[0]) * 60 * 60 + (+a[1]) * 60 + (+a[2]); 
    // alert(seconds);
    return seconds;


    // var hoursMinutes = time.split(/[.:]/);
    // var hours = parseInt(hoursMinutes[0], 10);
    // var minutes = hoursMinutes[1] ? parseInt(hoursMinutes[1], 10) : 0;
    // var seconds = hoursMinutes[2] ? parseInt(hoursMinutes[2], 10) : 0;
    // alert(hours + minutes / seconds);
    // return hours + minutes / 60;



}

function getWindowSize() {
    var myWidth = 0, myHeight = 0;
    if( typeof( window.innerWidth ) == 'number' ) {
        //Non-IE
        myWidth = window.innerWidth;
        myHeight = window.innerHeight;
    } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
        //IE 6+ in 'standards compliant mode'
        myWidth = document.documentElement.clientWidth;
        myHeight = document.documentElement.clientHeight;
    } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
        //IE 4 compatible
        myWidth = document.body.clientWidth;
        myHeight = document.body.clientHeight;
    }
    windowWidth = myWidth;
    windowHeight = myHeight;
    
    if (displayScreen == 1) {settingsDrivers();}  // redraw drivers settings page
    
    var divExists = document.getElementById("headerTitle");  // check if div ID is drawn
    if(divExists){
        if (windowWidth < 480) {document.getElementById('headerTitle').innerHTML = "";}
    }

    // console.log('windowWidth   = ' + windowWidth);
    // console.log('windowHeight  = ' + windowHeight);
}

function restartControllerConfirm() {  // open confirmation window to restart controller
    $('#popupBackground').show();  // grey out background
    $('.ds18b20Popup-body').empty();
    ds18b20Popup.style.display = "block";
    document.querySelector("body").style.overflow = 'hidden';
    $('.ds18b20PopupHeader').empty();

    $(".ds18b20PopupHeader").append("Restart Robo-Tank");
    $(".ds18b20Popup-body").append(
        '<div style="text-align: center;">\
            <p>&nbsp;</p>\
            <p>Would you like to restart Robo-Tank?</p>\
            <div class="widgetButtonBox" id="widgetButtonBox">\
                <button class="button _wide" type="button" onclick="restartController()">Yes</button>\
                <button class="button _wide" type="button" onclick="closeDs18b20Popup()">No</button>\
            </div></br>\
        </div>');
}

function restartController() {  // display message telling user controller is restarting
    $('.ds18b20PopupHeader').empty();
    $('.ds18b20Popup-body').empty();

    $(".ds18b20PopupHeader").append("Restarting Robo-Tank");
    $(".ds18b20Popup-body").append(
        '<div style="text-align: center;">\
            <p>&nbsp;</p>\
            <p style="font-weight:bold">Restarting Robo-Tank...</p>\
            <p>When the controller comes back online this message will disappear.</p>\
            <div class="updateRoller"><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div></div>\
            <p>&nbsp;</p>\
        </div>');

    var command = "999";
    sendToBackend(command);  // send command to backend
}
  