
var editingArrayID = 0;

function printDosingPumpsWidget(){  // dashboard section
    // calibrateDoser(1);
    // return;

    $('#dashboardDoseContainer').empty();  // clear dosing pumps widget     
    
    for (var i=0; i < doseID.length; i++)  // draw a reservoir for each dosing pump
    {
        
        document.getElementById('dashboardDoseContainer').innerHTML +=
        '<div class="doseSettingsBox2">\
            <div class="doseNameDiv">' + doseName[i] + '</div>\
            <div class="doseSettingsTubeDiv" id="doseTubeDiv_' + i + '">\
                <span id="doseRemainingDiv_' + i + '">' + round(doseReservoirRemain[i], 1) + '</span></br>\
                <div id="doseClickColor_' + i + '"></div>\
                <img class="reservoirImage" height="130px;" src="images/icons/doseReservoir_White.png">\
            </div>\
        </div>';
    }

    for (var i=0; i < doseID.length; i++)  // calculate reservoir amount and fill
    {
        $('#doseTubeDiv_' + [i]).css('background','linear-gradient(90deg, ' + doseReservoirColor[i] + ' 100%, white 00%)');
        $('#doseTubeDiv_' + [i]).css('background-repeat', 'no-repeat');
        doseFillReservoirSettings(i);
    }
}

function dosingSettings() {  // main dosing screen
    // console.log('dosingSettings =============== ');
    printHeaderTitle("DOSING PUMPS", "schedules3.png", "#8a5d23");  // name and file
    removeFooter();
    displayScreen = 10;

    document.getElementById('content').innerHTML +=
        '<div class="cleanScreen" id="cleanScreen">\
            <div class="dosingPumpsBoxContainer" id="dosingPumpsBoxContainer"></div>\
            <div class="dosingPumpDetailsContainer" id="dosingPumpDetailsContainer"></div>\
        </div>';
        
    for (var i=0; i < doseID.length; i++)  // draw a reservoir for each dosing pump
    {
        document.getElementById('dosingPumpsBoxContainer').innerHTML +=
        '<div class="doseSettingsBox" id="doseContainer_' + i + '">\
            <div class="doseSettingsName" id="doseSettingsName_' + i + '">\
                ' + doseName[i] + '<i class="bi bi-pencil-fill editPencil" onclick="changeDosingName(' + i + ')"></i>\
            </div>\
            <div class="doseSettingsBox3">\
                <div style="margin-top:5px;" class="doseSettingsTubeDiv" id="doseTubeDiv_' + i + '">\
                    <span id="doseRemainingDiv_' + i + '" class="dosesRemaining">' + round(doseReservoirRemain[i], 1) + ' mL\'s Remaining</span></br>\
                    <div data-jscolor="{value:`' + doseReservoirColor[i] + '`, onInput:`changeReservoirColor(this,' + i + ')`, onChange:`saveReservoirColor(this,' + i + ')`}" id="doseClickColor_' + i + '" class="jscolor_' + i + ' jscolorBackground"></div>\
                    <img class="reservoirImage" id="reservoirImage_' + i + '" height="130px;" src="images/icons/doseReservoir_White.png">\
                    <div style="float:right">\
                        <div class="doseSettingsButton buttonHover" onclick="refillDoseReservoirConfirm(' + i + ')">Refill</div>\
                        <div class="doseSettingsButton buttonHover" onclick="manualDoseConfirm(' + i + ')">Manual Dose</div>\
                        <div class="doseSettingsButton buttonHover" id="doseDetailsButton_' + i + '" onclick="dosingSettingsDetails(' + i + ')">View Details</div>\
                    </div>\
                </div>\
            </div>\
        </div>';
    }

    document.getElementById('cleanScreen').innerHTML +=
        '<div class="widgetButtonBox" id="widgetButtonBox">\
            <button class="button _48 back_48" style="" type="button" onclick="viewSettingsMenu()"></button>\
            <button class="button _48 home_48" style="" type="button" onclick="loadLayout()"></button>\
        </div>';

    for (var i=0; i < doseID.length; i++)  // calculate reservoir amount and fill
    {
        jscolor.install(); // recognizes new inputs and installs jscolor on them
        $('#doseTubeDiv_' + [i]).css('background','linear-gradient(90deg, ' + doseReservoirColor[i] + ' 100%, white 00%)');
        $('#doseTubeDiv_' + [i]).css('background-repeat', 'no-repeat');

        doseFillReservoirSettings(i);
    }

    if (prevDisplayScreen == 10) {dosingSettingsDetails(viewingDosingPumpScheduleID); prevDisplayScreen = 0;}  // load pump details if returning from another screen
}

function dosingSettingsDetails(i) {  // extended settings screen - default shows schedules
    // console.log('dosingSettingsDetails =============== ' + i); 
    viewingDosingPumpScheduleID = i;  // this is used to track which pump is viewed so we can redraw table when we sort using schedule functions
    schedulePrevExpanded = null;
    document.getElementById('widgetButtonBox').innerHTML =
        '<button class="button _48 back_48" style="" type="button" onclick="viewSettingsMenu()"></button>\
        <button class="button _48 home_48" style="" type="button" onclick="loadLayout()"></button>';

    document.getElementById('dosingPumpDetailsContainer').style.display = "block";  // show details container on page

    const element = document.getElementById("dosingPumpsBoxContainer");  // get all pumps in main container
    
    for (var a=0; a < doseID.length; a++)  // hide each dosing pump
    {
        document.getElementById('doseContainer_' + a).style.display = "none";
    }
    
    document.getElementById('doseContainer_' + i).style.display = "block";  // show pump that belongs to the details
    document.getElementById('doseContainer_' + i).style.borderBottom = "solid 1px #000000";  // change bottom board color of dosing pump box
    document.getElementById('doseDetailsButton_' + i).innerHTML = "Close Details";  // change button text
    document.getElementById('doseDetailsButton_' + i).onclick = dosingSettings;  // change button on click event
    document.getElementById('doseDetailsButton_' + i).style = 'background-color:#FF0000; color:#000000; font-weight: bold;';

    document.getElementById('dosingPumpDetailsContainer').innerHTML =  // draw details
        `<div class="doseDetailButtonsBox" id="doseDetailButtonsBox">
            <div class="doseDetailButtons buttonHover" id="doseAddScheduleButton_` + i + `" onclick="dosingAddSchedule(` + i + `)">Add Single Schedule</div>
            <div class="doseDetailButtons buttonHover" id="doseAddGroupScheduleButton_` + i + `" onclick="dosingAddGroupSchedule(` + i + `)">Add Group Schedule</div>
            <div class="doseDetailButtons buttonHover" id="doseStirrerButton_` + i + `" onclick="dosingStirrerSettings(` + i + `)">Stirrer</div>
            <div class="doseDetailButtons buttonHover" id="doseCalibrateButton_` + i + `" onclick="dosingCalibrate(` + i + `)">Calibrate</div>
            <div class="doseDetailButtons buttonHover" id="doseSettingsButton_` + i + `" onclick="dosingSettingsAdvanced(` + i + `)">Settings</div>
        </div>
        
        <div class="doseScheduleTable" id="doseScheduleTable">\
            <table class="logTable" style="margin-top:10px;">
                <thead class="logTableHeader" id="logTableHeader">
                    <tr>
                        <th></th>
                        <th class="typeSort" id="typeSort" onclick="schedulesSort(1)"><div id="typeSortIcon" class="sortIcon bi bi-arrow-down-up"></div>Type</th>
                        <th class="equipSort" id="equipSort" onclick="schedulesSort(15)"><div id="equipSortIcon" class="sortIcon bi bi-arrow-down-up"></div>Equipment</th>
                        <th class="descrSort" id="descrSort" onclick="schedulesSort(2)"><div id="descrSortIcon" class="sortIcon bi bi-arrow-down-up"></div>Description</th>
                        <th id="startSort" onclick="schedulesSort(3)"><div id="startSortIcon" class="sortIcon bi-sort-numeric-down"></div>Runs At</th>
                        <th class="mlSort" id="mlSort" style="padding-top:4px;" onclick="schedulesSort(16)"><div id="mlSortIcon" class="sortIcon bi-sort-numeric-down"></div>mL</th>
                        <th class="onOffSort" onclick="schedulesSort(4)"><div id="offOnSortIcon" class="sortIcon bi bi-arrow-down-up"></div></th>
                        <th class="emailSort" onclick="schedulesSort(13)"><div id="emailSortIcon" class="sortIcon bi bi-arrow-down-up"></div></th>
                        <th class="alertSort" onclick="schedulesSort(14)"><div id="alertSortIcon" class="sortIcon bi bi-arrow-down-up"></div></th>
                        <th class="monS" id="monS" onclick="schedulesSort(5)"><div id="monIcon" class="sortIcon"></div>M</th>
                        <th class="tueS" id="tueS" onclick="schedulesSort(6)"><div id="tueIcon" class="sortIcon"></div>T</th>
                        <th class="wedS" id="wedS" onclick="schedulesSort(7)"><div id="wedIcon" class="sortIcon"></div>W</th>
                        <th class="thuS" id="thuS" onclick="schedulesSort(8)"><div id="thuIcon" class="sortIcon"></div>T</th>
                        <th class="friS" id="friS" onclick="schedulesSort(9)"><div id="friIcon" class="sortIcon"></div>F</th>
                        <th class="satS" id="satS" onclick="schedulesSort(10)"><div id="satIcon" class="sortIcon"></div>S</th>
                        <th class="sunS" id="sunS" onclick="schedulesSort(11)"><div id="sunIcon" class="sortIcon"></div>S</th>
                        <th onclick="schedulesSort(12)"><div id="enableSortIcon" class="sortIcon bi bi-arrow-down-up"></div></th>
                        <th><div id="timeSortIcon" class="sortIcon"></div></th>
                        <th><div id="timeSortIcon" class="sortIcon"></div></th>
                    </tr>
                </thead>
                <tbody class="logList" id="schedulesList"></tbody>
            </table>
            <div class="paginationBox">
                <span class="pagination2 bi bi-caret-left-fill" onclick="schedulePreviousPage(3)"></span>\
                <span class="pagination" id="pagination">Page ` + (schedulePageNumber + 1) + ` of ` + totalPages + `</span>\
                <span class="pagination2 bi bi-caret-right-fill" onclick="scheduleNextPage(3)"></span>\
            </div>
        </div>`;
    
    document.getElementById('logTableHeader').style = 'background-color:#8a5d23';
    printSchedulesTableData(3,dosePinID[i]);

    var elements = document.getElementsByClassName('typeSort'); // get all temp elements
    for(var i = 0; i < elements.length; i++){
        elements[i].style.display = "none";
    }

    var elements = document.getElementsByClassName('equipSort'); // get all temp elements
    for(var i = 0; i < elements.length; i++){
        elements[i].style.display = "none";
    }

    var elements = document.getElementsByClassName('onOffSort'); // get all temp elements
    for(var i = 0; i < elements.length; i++){
        elements[i].style.display = "none";
    }

    var elements = document.getElementsByClassName('mlSort'); // get all temp elements
    for(var i = 0; i < elements.length; i++){
        elements[i].style.display = "block";
    }

    document.getElementById('pagination').innerHTML = "Page " + (schedulePageNumber + 1) + " of " + totalPages; // update page number
}

function dosingSettingsAdvanced(i) {  // advanced settings
    // console.log('dosingSettingsAdvanced =============== ' + i);
    document.getElementById('widgetButtonBox').innerHTML = '';
    document.getElementById('doseDetailButtonsBox').innerHTML = "";

    document.getElementById('doseScheduleTable').innerHTML =
        '<div class="dosingPumpsBoxContainer" id="doseContainer_' + i + '">\
            <div class="doseSettingsBox4">\
                <div class="doseSettingsAmountBox" style="margin-top:-10px;">\
                    <div class="doseSettingsAmountLabel">Reservoir</br>Capacity</div>\
                    <div class="doseSettingsAmount" id="doseReservoirSize_' + i + '">' + doseReservoirSize[i] +  ' mL</div>\
                </div>\
                <div class="parameterButtonBox">\
                    <button id="changeReservoirCapacityUp_' + i + '" onmousedown="changeReservoirCapacity(0,' + i + ')" class="doseUpDownButton bi bi-arrow-up-short"></button></br>\
                    <button id="changeReservoirCapacityDown_' + i + '" onmousedown="changeReservoirCapacity(1,' + i + ')" class="doseUpDownButton bi bi-arrow-down-short"></button>\
                </div>\
            </div>\
            <div class="doseSettingsBox4">\
                <div class="doseSettingsAmountBox" style="margin-top:-10px;">\
                    <div class="doseSettingsAmountLabel">Minimum Delay</br>Between Doses</div>\
                    <div class="doseSettingsAmount" id="doseInterval_' + i + '" style="line-height: 1.1;">' + doseInterval[i] +  ' <span style="font-size:18px;">Minutes</span></div>\
                </div>\
                <div class="parameterButtonBox">\
                    <button id="changeDoseIntervalUp_' + i + '" onmousedown="changeDoseInterval(0,' + i + ')" class="doseUpDownButton bi bi-arrow-up-short"></button></br>\
                    <button id="changeDoseIntervalDown_' + i + '" onmousedown="changeDoseInterval(1,' + i + ')" class="doseUpDownButton bi bi-arrow-down-short"></button>\
                </div>\
            </div>\
            <div class="doseSettingsBox4">\
                <div class="doseStirrerEnableBox" style="margin-top: 5px;">\
                    <p>Reservoir</p>\
                    <input type="checkbox" id="doseDisableRes_' + i + '" onclick="doseDisableReser(' + i + ')">\
                    <label style="color: #8a5d23;" id="doseDisableResLabel_' + i + '" for="doseDisableRes_' + i + '"></label>\
                    <p class="resEnabled" id="resEnabled"></p>\
                </div>\
            </div>\
            <div class="doseSettingsBox4">\
                <div class="doseSettingsAmountBox" style="margin-top:-10px;">\
                    <div class="doseSettingsAmountLabel">Reservoir Alert Level</div>\
                    <div class="doseSettingsAmount" id="doseResAlertML_' + i + '">' + doseResAlertML[i] +  ' mL</div>\
                </div>\
                <div class="parameterButtonBox">\
                    <button id="changeResAlertMLup_' + i + '" onmousedown="changeResAlertML(0,' + i + ')" class="doseUpDownButton bi bi-arrow-up-short"></button></br>\
                    <button id="changeResAlertMLdown_' + i + '" onmousedown="changeResAlertML(1,' + i + ')" class="doseUpDownButton bi bi-arrow-down-short"></button>\
                </div>\
            </div>\
            <div class="doseSettingsBox4">\
                <div class="doseGroupBox">\
                    <p style="font-weight: bold;">Alert when reservoir is low</p>\
                    <div class="doseResAlertsBox" >\
                        <div class="doseResAlerts"><i class="doseResAlerts bi bi-envelope-fill" id="resEmail"></i></div>\
                        <div style="width:100%" id="resEmailLabel">Email</div>\
                    </div>\
                    <div class="doseResAlertsBox" >\
                        <div class="doseResAlerts"><i class="doseResAlerts bi bi-exclamation-triangle-fill" id="resAlert"></i></div>\
                        <div style="width:100%" id="resAlertLabel">Dashboard Alert</div>\
                    </div>\
                </div>\
            </div>\
        </div>\
        <div class="fieldError" id="fieldError1"></div>\
        <div class="widgetButtonBox">\
            <button class="button _wide" style="" type="button" onclick="dosingSettingsDetails(' + i + ')">Done</button>\
        </div>';

    if (doseDisableRes[i] == 0) {
        document.getElementById('doseDisableRes_' + i).checked = true;
        document.getElementById('doseDisableResLabel_' + i).innerHTML = "Reservoir Enabled";
        document.getElementById('resEnabled').innerHTML = "dosing pump will not</br>run when reservoir is empty";
    }
    else {
        document.getElementById('doseDisableRes_' + i).checked = false;
        document.getElementById('doseDisableResLabel_' + i).innerHTML = "Reservoir Disabled";
        document.getElementById('resEnabled').innerHTML = "dosing pump will run</br>when reservoir is empty";
    }

    if (doseResAlert[i] == 0) {document.getElementById('resAlert').style.color = "#686767";}
    else {document.getElementById('resAlert').style.color = "#00b610";}

    if (doseResEmail[i] == 0) {document.getElementById('resEmail').style.color = "#686767";}
    else {document.getElementById('resEmail').style.color = "#00b610";}

    var timeout;  // timer to track when button is held up or down
    var count = 0;
    var adjusted = 0;
    
    document.getElementById("resEmail").addEventListener("click", function(){enableResEmail(i)});
    document.getElementById("resEmailLabel").addEventListener("click", function(){enableResEmail(i)});
    document.getElementById("resAlert").addEventListener("click", function(){enableResAlert(i)});
    document.getElementById("resAlertLabel").addEventListener("click", function(){enableResAlert(i)});
    
    $('#changeDoseIntervalUp_' + i).mousedown(function () {  // action to take when mouse is down every 150ms
        timeout = setInterval(function () {
            adjusted = 1;
            changeDoseInterval(0, editingArrayID);
            count++;  // count each cycle while mouse button is down
            if (count > 10) {  // after 10 cycles increase cycle speed to 50ms
                clearInterval(timeout); 
                timeout = setInterval(function () {
                    changeDoseInterval(0, editingArrayID);
                    count++;
                    if (count > 60) {  // after 60 cycles increase cycle speed to 1ms
                        clearInterval(timeout);
                        timeout = setInterval(function () {
                            changeDoseInterval(0, editingArrayID);
                        }, 1);
                    }
                }, 50);
            }
        }, 150);
    }).mouseup(function () {  // stop action when mouse is up
        count = 0;
        adjusted = 0;
        saveDoseInterval();
        clearInterval(timeout);
    }).mouseout(function () {  // stop action when mouse moves off up/down button
        count = 0;
        if (adjusted == 1) {saveDoseInterval();}
        adjusted = 0;
        clearInterval(timeout);
    });
    
    $('#changeDoseIntervalDown_' + i).mousedown(function () {  // action to take when mouse is down every 150ms
        timeout = setInterval(function () {
            adjusted = 1;
            changeDoseInterval(1, editingArrayID);
            count++;  // count each cycle while mouse button is down
            if (count > 10) {  // after 10 cycles increase cycle speed to 50ms
                clearInterval(timeout); 
                timeout = setInterval(function () {
                    changeDoseInterval(1, editingArrayID);
                    count++;
                    if (count > 60) {  // after 60 cycles increase cycle speed to 1ms
                        clearInterval(timeout);
                        timeout = setInterval(function () {
                            changeDoseInterval(1, editingArrayID);
                        }, 1);
                    }
                }, 50);
            }
        }, 150);
    }).mouseup(function () {  // stop action when mouse is up
        count = 0;
        adjusted = 0;
        saveDoseInterval();
        clearInterval(timeout);
    }).mouseout(function () {  // stop action when mouse moves off up/down button
        count = 0;
        if (adjusted == 1) {saveDoseInterval();}
        adjusted = 0;
        clearInterval(timeout);
    });

    $('#changeReservoirCapacityUp_' + i).mousedown(function () {  // action to take when mouse is down every 150ms
        timeout = setInterval(function () {
            adjusted = 1;
            changeReservoirCapacity(0, editingArrayID);
            count++;  // count each cycle while mouse button is down
            if (count > 10) {  // after 10 cycles increase cycle speed to 50ms
                clearInterval(timeout); 
                timeout = setInterval(function () {
                    changeReservoirCapacity(0, editingArrayID);
                    count++;
                    if (count > 60) {  // after 60 cycles increase cycle speed to 1ms
                        clearInterval(timeout);
                        timeout = setInterval(function () {
                            changeReservoirCapacity(0, editingArrayID);
                        }, 1);
                    }
                }, 50);
            }
        }, 150);
    }).mouseup(function () {  // stop action when mouse is up
        count = 0;
        adjusted = 0;
        saveReservoirCapacity();
        clearInterval(timeout);
    }).mouseout(function () {  // stop action when mouse moves off up/down button
        count = 0;
        if (adjusted == 1) {saveReservoirCapacity();}
        adjusted = 0;
        clearInterval(timeout);
    });
    
    $('#changeReservoirCapacityDown_' + i).mousedown(function () {  // action to take when mouse is down every 150ms
        timeout = setInterval(function () {
            adjusted = 1;
            changeReservoirCapacity(1, editingArrayID);
            count++;  // count each cycle while mouse button is down
            if (count > 10) {  // after 10 cycles increase cycle speed to 50ms
                clearInterval(timeout); 
                timeout = setInterval(function () {
                    changeReservoirCapacity(1, editingArrayID);
                    count++;
                    if (count > 60) {  // after 60 cycles increase cycle speed to 1ms
                        clearInterval(timeout);
                        timeout = setInterval(function () {
                            changeReservoirCapacity(1, editingArrayID);
                        }, 1);
                    }
                }, 50);
            }
        }, 150);
    }).mouseup(function () {  // stop action when mouse is up
        count = 0;
        adjusted = 0;
        saveReservoirCapacity();
        clearInterval(timeout);
    }).mouseout(function () {  // stop action when mouse moves off up/down button
        count = 0;
        if (adjusted == 1) {saveReservoirCapacity();}
        adjusted = 0;
        clearInterval(timeout);
    });

    $('#changeResAlertMLup_' + i).mousedown(function () {  // action to take when mouse is down every 150ms
        timeout = setInterval(function () {
            adjusted = 1;
            changeResAlertML(0, editingArrayID);
            count++;  // count each cycle while mouse button is down
            if (count > 10) {  // after 10 cycles increase cycle speed to 50ms
                clearInterval(timeout); 
                timeout = setInterval(function () {
                    changeResAlertML(0, editingArrayID);
                    count++;
                    if (count > 60) {  // after 60 cycles increase cycle speed to 1ms
                        clearInterval(timeout);
                        timeout = setInterval(function () {
                            changeResAlertML(0, editingArrayID);
                        }, 1);
                    }
                }, 50);
            }
        }, 150);
    }).mouseup(function () {  // stop action when mouse is up
        count = 0;
        adjusted = 0;
        saveResAlertLevel();
        clearInterval(timeout);
    }).mouseout(function () {  // stop action when mouse moves off up/down button
        count = 0;
        if (adjusted == 1) {saveResAlertLevel();}
        adjusted = 0;
        clearInterval(timeout);
    });
    
    $('#changeResAlertMLdown_' + i).mousedown(function () {  // action to take when mouse is down every 150ms
        timeout = setInterval(function () {
            adjusted = 1;
            changeResAlertML(1, editingArrayID);
            count++;  // count each cycle while mouse button is down
            if (count > 10) {  // after 10 cycles increase cycle speed to 50ms
                clearInterval(timeout); 
                timeout = setInterval(function () {
                    changeResAlertML(1, editingArrayID);
                    count++;
                    if (count > 60) {  // after 60 cycles increase cycle speed to 1ms
                        clearInterval(timeout);
                        timeout = setInterval(function () {
                            changeResAlertML(1, editingArrayID);
                        }, 1);
                    }
                }, 50);
            }
        }, 150);
    }).mouseup(function () {  // stop action when mouse is up
        count = 0;
        adjusted = 0;
        saveResAlertLevel();
        clearInterval(timeout);
    }).mouseout(function () {  // stop action when mouse moves off up/down button
        count = 0;
        if (adjusted == 1) {saveResAlertLevel();}
        adjusted = 0;
        clearInterval(timeout);
    });
}

function saveStirrerPort(i) {  // update what stirrer port is being used on dosing pump
    // console.log('saveStirrerPort =============== ' + i);
    var stirID = document.getElementById('stirrerPortSelect').value;  // get stirrerID from dropdown

    if (doseStirrer[i] == 1) {  // validate if stirrer is enabled
        if (stirID == "empty") {  // no stirrer selected
            document.getElementById('fieldError1').style.width = "auto";
            document.getElementById('fieldError1').style.paddingLeft = "10px";
            document.getElementById('fieldError1').style.display = "inline-block";  // show error
            document.getElementById('fieldError1').innerHTML = "You need to select a port!";
            document.getElementById('stirrerPortSelect').style.border = "2px solid rgb(255, 0, 0)";
            document.getElementById('stirrerPortSelect').focus();
            return;
        }
        else {
            document.getElementById('fieldError1').style.display = "none";  // hide error
            document.getElementById('stirrerPortSelect').style.border = "";
        }
    }
    doseStirrerID[i] = stirID;
    var command = "98, " + doseStirrerID[i] + "," + dosePinID[i];
    sendToBackend(command);  // 
}

function dosingStirrerSettings(i) {  // advanced settings
    // console.log('dosingStirrerSettings =============== ' + i);
    document.getElementById('widgetButtonBox').innerHTML = '';
    document.getElementById('doseDetailButtonsBox').innerHTML = "";

    document.getElementById('doseScheduleTable').innerHTML =
        '<div class="dosingPumpsBoxContainer" id="doseContainer_' + i + '">\
            <div class="doseSettingsBox4">\
                <div class="doseStirrerEnableBox" style="margin-top: 2px;">\
                    <input type="checkbox" id="doseStirrer_' + i + '" onclick="enableDoseStirrer(' + i + ')">\
                    <label id="doseStirrerLabel_' + i + '" for="doseStirrer_' + i + '">Stirrer Enabled</label>\
                    <div class="driversControllerEditBox" id="stirrerBox">\
                        <div class="driverControllerName" style="flex: 0 0 auto; padding-left:10px;">Port</div>\
                        <select class="field" id="stirrerPortSelect" onchange="saveStirrerPort(' + i + ')">\
                            <option value="empty"></option>\
                        </select>\
                    </div>\
                    <p class="resEnabled">stirrers not assigned show</p>\
                    <div class="fieldError" id="fieldError1"></div>\
                </div>\
            </div>\
            <div class="doseSettingsBox4">\
                    <div style="font-weight:bold; text-align:center; margin-left:5px; width:100%;">\
                        Stirrer Speed\
                        <input class="nonFunctioningTextBox" type="text" id="dosePumpSpeedValue" value="" disabled="disabled">\
                    </div>\
                    <input type="range" min="0" max="100" oninput="moveStirrerSpeedSlider(' + i + ')" onmouseup="stopStirrerSpeedSlider(' + i + ')" value="" class="dosePumpSpeedSlider" style="width:180px; margin-left:9px;" id="dosePumpSpeedSlider_' + i + '">\
                    <p class="resEnabled">adjusting will activate stirrer</p>\
            </div>\
            <div class="doseSettingsBox4">\
                <div class="doseSettingsAmountBox" style="margin-top:-10px;">\
                    <div class="doseSettingsAmountLabel">Stirrer Runtime</div>\
                    <div class="doseSettingsAmount" id="stirrerRuntime_' + i + '">' + stirrerRuntime[i] +  ' seconds</div>\
                </div>\
                <div class="parameterButtonBox">\
                    <button id="changeStirrerRuntimeUp_' + i + '" onmousedown="changeStirrerRuntime(0,' + i + ')" class="doseUpDownButton bi bi-arrow-up-short"></button></br>\
                    <button id="changeStirrerRuntimeDown_' + i + '" onmousedown="changeStirrerRuntime(1,' + i + ')" class="doseUpDownButton bi bi-arrow-down-short"></button>\
                </div>\
            </div>\
            <div class="doseSettingsBox4">\
                <div class="doseSettingsAmountBox" style="margin-top:-10px;">\
                    <div class="doseSettingsAmountLabel">Settling Runtime</div>\
                    <div class="doseSettingsAmount" id="settlingRuntime_' + i + '">' + settlingRuntime[i] +  ' seconds</div>\
                </div>\
                <div class="parameterButtonBox">\
                    <button id="changeSettlingRuntimeUp_' + i + '" onmousedown="changeSettlingRuntime(0,' + i + ')" class="doseUpDownButton bi bi-arrow-up-short"></button></br>\
                    <button id="changeSettlingRuntimeDown_' + i + '" onmousedown="changeSettlingRuntime(1,' + i + ')" class="doseUpDownButton bi bi-arrow-down-short"></button>\
                </div>\
            </div>\
        </div>\
        <div class="fieldError" id="fieldError1"></div>\
        <div class="widgetButtonBox">\
            <button class="button _wide" style="" type="button" onclick="closeStirrerSettings(' + i + ')">Done</button>\
        </div>';

    if (doseStirrer[i] == 0) {
        document.getElementById('doseStirrer_' + i).checked = false; 
        document.getElementById('doseStirrerLabel_' + i).innerHTML = "Stirrer Disabled";
        $('#stirrerBox').hide();  // hide dropdown
    }
    else if (doseStirrer[i] == 1) {
        document.getElementById('doseStirrer_' + i).checked = true;
        document.getElementById('doseStirrerLabel_' + i).innerHTML = "Stirrer Enabled";
        $('#stirrerBox').show();  // show dropdown
    }

    var pass = 0;
    for (var j=0; j < stirrerID.length; j++)  // add ports to dropdown list
    {
        for (var k=0; k < doseStirrerID.length; k++)  // search through ports to see if it's already being used
        {
            if (stirrerID[j] == doseStirrerID[i]) {pass = 1; break;}  // port belongs to dosing pump stirrer being edited - add to dropdown
            if (stirrerID[j] == doseStirrerID[k]) {pass = 0; break;}  // port is already assigned to another stirrer - skip
            else {pass = 1;}  // port not being used anywere - add to dropdown
        }

        if (pass == 1) {  // add port to dropdown
            document.getElementById('stirrerPortSelect').innerHTML +=  // 
                '<option value="' + stirrerID[j] + '">' + stirrerName[j] + '</option>';
        }
        else {  // hide port on dropdown
            document.getElementById('stirrerPortSelect').innerHTML +=  // 
                '<option hidden value="' + stirrerID[j] + '">' + stirrerName[j] + '</option>';
        }
    }

    for (var j=0; j < stirrerID.length; j++)  // search for port already assigned so it's selected in dropdown when page loads
    {
        if (stirrerID[j] == doseStirrerID[i]) {  // found
            document.getElementById("stirrerPortSelect").selectedIndex = (j+1);
            break;
        }
    }

    document.getElementById("dosePumpSpeedValue").value = stirrerSpeed[i] + "%";
    document.getElementById("dosePumpSpeedSlider_" + i).value = stirrerSpeed[i];
    
    var timeout;  // timer to track when button is held up or down
    var count = 0;
    var adjusted = 0;
        
    $('#changeStirrerRuntimeUp_' + i).mousedown(function () {  // action to take when mouse is down every 150ms
        timeout = setInterval(function () {
            adjusted = 1;
            changeStirrerRuntime(0, editingArrayID);
            count++;  // count each cycle while mouse button is down
            if (count > 10) {  // after 10 cycles increase cycle speed to 50ms
                clearInterval(timeout); 
                timeout = setInterval(function () {
                    changeStirrerRuntime(0, editingArrayID);
                    count++;
                    if (count > 60) {  // after 60 cycles increase cycle speed to 1ms
                        clearInterval(timeout);
                        timeout = setInterval(function () {
                            changeStirrerRuntime(0, editingArrayID);
                        }, 1);
                    }
                }, 50);
            }
        }, 150);
    }).mouseup(function () {  // stop action when mouse is up
        count = 0;
        adjusted = 0;
        saveStirrerRuntime();
        clearInterval(timeout);
    }).mouseout(function () {  // stop action when mouse moves off up/down button
        count = 0;
        if (adjusted == 1) {saveStirrerRuntime();}
        adjusted = 0;
        clearInterval(timeout);
    });
    
    $('#changeStirrerRuntimeDown_' + i).mousedown(function () {  // action to take when mouse is down every 150ms
        timeout = setInterval(function () {
            adjusted = 1;
            changeStirrerRuntime(1, editingArrayID);
            count++;  // count each cycle while mouse button is down
            if (count > 10) {  // after 10 cycles increase cycle speed to 50ms
                clearInterval(timeout); 
                timeout = setInterval(function () {
                    changeStirrerRuntime(1, editingArrayID);
                    count++;
                    if (count > 60) {  // after 60 cycles increase cycle speed to 1ms
                        clearInterval(timeout);
                        timeout = setInterval(function () {
                            changeStirrerRuntime(1, editingArrayID);
                        }, 1);
                    }
                }, 50);
            }
        }, 150);
    }).mouseup(function () {  // stop action when mouse is up
        count = 0;
        adjusted = 0;
        saveStirrerRuntime();
        clearInterval(timeout);
    }).mouseout(function () {  // stop action when mouse moves off up/down button
        count = 0;
        if (adjusted == 1) {saveStirrerRuntime();}
        adjusted = 0;
        clearInterval(timeout);
    });
    
    $('#changeSettlingRuntimeUp_' + i).mousedown(function () {  // action to take when mouse is down every 150ms
        timeout = setInterval(function () {
            adjusted = 1;
            changeSettlingRuntime(0, editingArrayID);
            count++;  // count each cycle while mouse button is down
            if (count > 10) {  // after 10 cycles increase cycle speed to 50ms
                clearInterval(timeout); 
                timeout = setInterval(function () {
                    changeSettlingRuntime(0, editingArrayID);
                    count++;
                    if (count > 60) {  // after 60 cycles increase cycle speed to 1ms
                        clearInterval(timeout);
                        timeout = setInterval(function () {
                            changeSettlingRuntime(0, editingArrayID);
                        }, 1);
                    }
                }, 50);
            }
        }, 150);
    }).mouseup(function () {  // stop action when mouse is up
        count = 0;
        adjusted = 0;
        saveSettlingRuntime();
        clearInterval(timeout);
    }).mouseout(function () {  // stop action when mouse moves off up/down button
        count = 0;
        if (adjusted == 1) {saveSettlingRuntime();}
        adjusted = 0;
        clearInterval(timeout);
    });
    
    $('#changeSettlingRuntimeDown_' + i).mousedown(function () {  // action to take when mouse is down every 150ms
        timeout = setInterval(function () {
            adjusted = 1;
            changeSettlingRuntime(1, editingArrayID);
            count++;  // count each cycle while mouse button is down
            if (count > 10) {  // after 10 cycles increase cycle speed to 50ms
                clearInterval(timeout); 
                timeout = setInterval(function () {
                    changeSettlingRuntime(1, editingArrayID);
                    count++;
                    if (count > 60) {  // after 60 cycles increase cycle speed to 1ms
                        clearInterval(timeout);
                        timeout = setInterval(function () {
                            changeSettlingRuntime(1, editingArrayID);
                        }, 1);
                    }
                }, 50);
            }
        }, 150);
    }).mouseup(function () {  // stop action when mouse is up
        count = 0;
        adjusted = 0;
        saveSettlingRuntime();
        clearInterval(timeout);
    }).mouseout(function () {  // stop action when mouse moves off up/down button
        count = 0;
        if (adjusted == 1) {saveSettlingRuntime();}
        adjusted = 0;
        clearInterval(timeout);
    });
}

function closeStirrerSettings(arrayID) {  // close stirrer settings
    // console.log('changeStirrerRuntime =============== ' + arrayID); 
    var d = document.getElementById('stirrerPortSelect').value;  // get stirrerID from dropdown
    if ((doseStirrer[arrayID] == 1) && ((d == "empty") || (d == 0))) {  // no stirrer selected, flag user
        document.getElementById('fieldError1').style.width = "auto";
        document.getElementById('fieldError1').style.paddingLeft = "10px";
        document.getElementById('fieldError1').style.display = "inline-block";  // show error
        document.getElementById('fieldError1').innerHTML = "You need to select a port!";
        document.getElementById('stirrerPortSelect').style.border = "2px solid rgb(255, 0, 0)";
        document.getElementById('stirrerPortSelect').focus();
    }
    else {  // close settings
        dosingSettingsDetails(arrayID);
    }
}

function changeStirrerRuntime(direction, arrayID) {  // change stirrer runtime
    // console.log('changeStirrerRuntime =============== ' + arrayID); 
    editingArrayID = arrayID;  // capature arrayID being adjusted so we can use to hold button down to increase/decrease value

    if (direction == 0) {  // up
        stirrerRuntime[arrayID]++;
        if (stirrerRuntime[arrayID] >= 10000) {stirrerRuntime[arrayID] = 1;}
    }
    else if (direction == 1) {  // down
        stirrerRuntime[arrayID]--;
        if (stirrerRuntime[arrayID] <= 0) {stirrerRuntime[arrayID] = 9999;}
    }
    document.getElementById('stirrerRuntime_' + arrayID).innerHTML = stirrerRuntime[arrayID] + " seconds";
}

function saveStirrerRuntime()  // save stirrer runtime
{
    console.log('saveStirrerRuntime =============== ' + editingArrayID);    
    var command = "96, " + dosePinID[editingArrayID] + "," + stirrerRuntime[editingArrayID];
    sendToBackend(command);  // 
}

function changeSettlingRuntime(direction, arrayID) {  // change settling runtime
    // console.log('changeSettlingRuntime =============== ' + arrayID); 
    editingArrayID = arrayID;  // capature arrayID being adjusted so we can use to hold button down to increase/decrease value

    if (direction == 0) {  // up
        settlingRuntime[arrayID]++;
        if (settlingRuntime[arrayID] >= 10000) {settlingRuntime[arrayID] = 1;}
    }
    else if (direction == 1) {  // down
        settlingRuntime[arrayID]--;
        if (settlingRuntime[arrayID] <= 0) {settlingRuntime[arrayID] = 9999;}
    }
    document.getElementById('settlingRuntime_' + arrayID).innerHTML = settlingRuntime[arrayID] + " seconds";
}

function saveSettlingRuntime()  // save settling runtime
{
    // console.log('saveSettlingRuntime =============== ' + editingArrayID);
    var command = "97, " + dosePinID[editingArrayID] + "," + settlingRuntime[editingArrayID];
    sendToBackend(command);  // 
}

function enableResEmail(arrayID) {  // 
    // console.log('enableResEmail =============== ' + arrayID); 
    if (doseResEmail[arrayID] == 0) {
        doseResEmail[arrayID] = 1;
        document.getElementById('resEmail').style.color = "#00b610";
    }
    else {
        doseResEmail[arrayID] = 0;
        document.getElementById('resEmail').style.color = "#686767";
    } 

    var command = "93, " + dosePinID[arrayID] + "," + doseResEmail[arrayID];
    sendToBackend(command);  // 
}

function enableResAlert(arrayID) {  // 
    // console.log('enableResAlert =============== ' + arrayID); 
    if (doseResAlert[arrayID] == 0) {
        doseResAlert[arrayID] = 1;
        document.getElementById('resAlert').style.color = "#00b610";
    }
    else {
        doseResAlert[arrayID] = 0;
        document.getElementById('resAlert').style.color = "#686767";
    } 

    var command = "94, " + dosePinID[arrayID] + "," + doseResAlert[arrayID];
    sendToBackend(command);  // 
}

function dosingAddSchedule(i) {  // add single schedule
    // console.log('dosingAddSchedule =============== ' + i); 
    prevDisplayScreen = 10;
    scheduleNew[0] = 3;
    addSchedule3(i);
}

function dosingAddGroupSchedule(i) {  // add group schedule
    // console.log('dosingAddGroupSchedule =============== ' + i); 
    prevDisplayScreen = 10;
    validationFail = 0;  // track which field failed validation check
    scheduleNew[0] = 0;  // total milliliters
    scheduleNew[1] = 0;  // start time
    scheduleNew[2] = 0;  // finish time
    scheduleNew[3] = 0;  // milliliters per dose
    scheduleNew[4] = 0;  // number of doses during time frame
    scheduleNew[5] = 0;  // repeat enabled - only used on UI, don't need to send to backend
    scheduleNew[6] = 0;  // repeat number of days
    scheduleNew[7] = 0;  // Monday
    scheduleNew[8] = 0;  // Tuesday
    scheduleNew[9] = 0;  // Wednesday
    scheduleNew[10] = 0;  // Thursday
    scheduleNew[11] = 0;  // Friday
    scheduleNew[12] = 0;  // Saturday
    scheduleNew[13] = 0;  // Sunday
    scheduleNew[14] = 0;  // description
    scheduleNew[15] = 0;  // email
    scheduleNew[16] = 0;  // alert

    document.getElementById('widgetButtonBox').innerHTML = '';
    document.getElementById('doseDetailButtonsBox').innerHTML = "";
    
    document.getElementById('doseScheduleTable').innerHTML = 
        `<div class="doseGroupBox">
            <div class="doseGroupContainer">
                <div class="doseGroupLabel">Description</div>
                <input style="width:300px;" class="doseGroupField" type="text" id="schDescription" onchange="validateDoseGroupSch(` + i + `,0)" onkeydown="validateDoseGroupSch(` + i + `,0)" autocomplete="off">
                <div class="fieldError" id="fieldError7"></div>
            </div></br></br>
            <div class="doseGroupContainer">
                <div class="doseGroupLabel">Dose</div>
                <input class="doseGroupField" type="number" id="totalML" onchange="validateDoseGroupSch(` + i + `,0)" onkeydown="validateDoseGroupSch(` + i + `,0)" onfocusout="validateDoseGroupSch(` + i + `,0)" autocomplete="off">
                <div class="doseGroupLabel">Milliliters Total</div></br>
                <div class="fieldError" id="fieldError1"></div>
            </div>
            <hr style="width:80%; height:1px; color:#505050; background-color:#505050;">
            <div style="width:250px; text-align:right;" class="doseGroupContainer">
                <div class="doseGroupLabel">Starting at</div>
                <input class="doseGroupTime" type="time" step="1" id="groupDoseStart" onchange="validateDoseGroupSch(` + i + `,0)" onfocusout="validateDoseGroupSch(` + i + `,0)" autocomplete="off">
            </div>
            <div style="width:250px;" class="doseGroupContainer">
                <div class="doseGroupLabel">Finishing at</div>
                <input class="doseGroupTime" type="time" step="1" id="groupDoseEnd" onchange="validateDoseGroupSch(` + i + `,0)" onfocusout="validateDoseGroupSch(` + i + `,0)" autocomplete="off">
            </div>
            <div class="fieldError" id="fieldError2"></div>\
            <hr style="width:80%; height:1px; color:#505050; background-color:#505050;">
            <div class="doseGroupContainer">
                <div class="doseGroupLabel">Dose</div>
                <input class="doseGroupField" type="number" id="perDoseML" onchange="validateDoseGroupSch(` + i + `,2)" onkeydown="validateDoseGroupSch(` + i + `,2)" onfocusout="validateDoseGroupSch(` + i + `,0)" autocomplete="off">
                <div class="doseGroupLabel">Milliliters Per Dose</div>
                <div class="fieldError" id="fieldError3"></div>\
            </div>
            <div class="doseGroupContainer doseGroupOption">OR</div>
            <div class="doseGroupContainer">
                <input class="doseGroupField" type="number" id="doseNumber" onchange="validateDoseGroupSch(` + i + `,3)" onkeydown="validateDoseGroupSch(` + i + `,3)" onfocusout="validateDoseGroupSch(` + i + `,0)" autocomplete="off">
                <div class="doseGroupLabel">Doses during time frame</div>
            </div>
            <div class="fieldError" id="fieldError4"></div>\
            <hr style="width:80%; height:1px; color:#505050; background-color:#505050;">
            <div class="schDaysContainer">\
                <div class="" id="repeatContainer">\
                    <input type="checkbox" id="repeatCheck" onclick="repeatDoseGroupSchedule()">\
                    <label for="repeatCheck" style="margin-right:5px;">Repeat every </label>\
                    <input class="schField" type="number" id="repeatDays" value="` + scheduleNew[6] + `"onchange="validateDoseGroupSch(` + i + `,0)" "onfocusout="validateDoseGroupSch(` + i + `,0)" autocomplete="off">\
                    <label for="repeatCheck" style="margin-left:5px;">days </label>\
                    <div class="fieldError" id="fieldError5"></div>\
                </div>\
            </div>\
            <div class="schDaysContainer" id="schDayContainter">\
                <div class="schDays">\
                    <label for="schDay1">Monday </label>\
                    <input type="checkbox" id="schDay1" onclick="doseGroupChangeDay(0)">\
                </div>\
                <div class="schDays">\
                    <label for="schDay2">Tuesday </label>\
                    <input type="checkbox" id="schDay2" onclick="doseGroupChangeDay(1)">\
                </div>\
                <div class="schDays">\
                    <label for="schDay3">Wednesday</label>\
                    <input type="checkbox" id="schDay3" onclick="doseGroupChangeDay(2)">\
                </div>\
                <div class="schDays">\
                    <label for="schDay4">Thursday</label>\
                    <input type="checkbox" id="schDay4" onclick="doseGroupChangeDay(3)">\
                </div>\
                <div class="schDays">\
                    <label for="schDay5">Friday</label>\
                    <input type="checkbox" id="schDay5" onclick="doseGroupChangeDay(4)">\
                </div>\
                <div class="schDays">\
                    <label for="schDay6">Saturday</label>\
                    <input type="checkbox" id="schDay6" onclick="doseGroupChangeDay(5)">\
                </div>\
                <div class="schDays">\
                    <label for="schDay7">Sunday</label>\
                    <input type="checkbox" id="schDay7" onclick="doseGroupChangeDay(6)">\
                </div>\
                <div class="fieldError" id="fieldError6"></div>\
            </div>\
            <div class="schDaysContainer">\
                <div class="scheduleListAlerts" id="email" onclick="doseGroupSchNewEmail()"></div>\
                <div class="scheduleListAlerts" id="alert" onclick="doseGroupSchNewAlert()"></div>\
            </div>\
        </div>
        <div class="fieldError" id="fieldError6"></div>
        <div class="widgetButtonBox">\
            <button class="button _wide" style="" type="button" onclick="validateDoseGroupSch(` + i + `,1)">Save Group Schedule</button>\
            <button class="button _wide" style="" type="button" onclick="dosingSettingsDetails(` + i + `)">Cancel</button>\
        </div>`;

        
    document.getElementById('schDescription').focus();

    if (scheduleNew[5] == 1) {
        document.getElementById('repeatCheck').checked = true;
        document.getElementById('repeatDays').disabled = false;
        document.getElementById('repeatDays').style = "background-color:#FFFFFF; width:70px;";
        document.getElementById('schDayContainter').style.display = "none";  // hide days
    }
    else {
        document.getElementById('repeatCheck').checked = false;
        document.getElementById('repeatDays').disabled = true;
        document.getElementById('repeatDays').value = '';
        document.getElementById('repeatDays').style = "background-color:#dfdfdf; width:70px;";
        document.getElementById('schDayContainter').style.display = "flex";  // show days
    }

    if (scheduleNew[7] == 1) {
        document.getElementById('schDay1').checked = true;
    }
    if (scheduleNew[8] == 1) {
        document.getElementById('schDay2').checked = true;
    }
    if (scheduleNew[9] == 1) {
        document.getElementById('schDay3').checked = true;
    }
    if (scheduleNew[10] == 1) {
        document.getElementById('schDay4').checked = true;
    }
    if (scheduleNew[11] == 1) {
        document.getElementById('schDay5').checked = true;
    }
    if (scheduleNew[12] == 1) {
        document.getElementById('schDay6').checked = true;
    }
    if (scheduleNew[13] == 1) {
        document.getElementById('schDay7').checked = true;
    }

    if (scheduleNew[15] == 1) {  // add email enabled icon
        document.getElementById('email').innerHTML =
            '<i class="bi bi-envelope-fill">&nbsp; Email Enabled</i>';
        document.getElementById('email').style.color = "#00b610";
    }
    else {
        document.getElementById('email').innerHTML =
            '<i class="bi bi-envelope-fill">&nbsp; Email Disabled</i>';
        document.getElementById('email').style.color = "#727272";
    }

    if (scheduleNew[16] == 1) {  // add dashboard alert enabled icon
        document.getElementById('alert').innerHTML =
            '<i class="bi bi-exclamation-triangle-fill">&nbsp; Dashboard Alert Enabled</i>';
        document.getElementById('alert').style.color = "#00b610";
    }
    else {
        document.getElementById('alert').innerHTML =
            '<i class="bi bi-exclamation-triangle-fill">&nbsp; Dashboard Alert Disabled</i>';
        document.getElementById('alert').style.color = "#727272";
    }
}

function validateDoseGroupSch(arrayLoc, source) {  // validate group schedule for dosing pump
    // console.log('validateDoseGroupSch =============== ');
    // scheduleNew[0] = 0;  // total milliliters
    // scheduleNew[1] = 0;  // start time
    // scheduleNew[2] = 0;  // finish time
    // scheduleNew[3] = 0;  // milliliters per dose
    // scheduleNew[4] = 0;  // number of doses during time frame
    // scheduleNew[5] = 0;  // repeat enabled - only used on UI, don't need to send to backend
    // scheduleNew[6] = 0;  // repeat number of days
    // scheduleNew[7] = 0;  // Monday
    // scheduleNew[8] = 0;  // Tuesday
    // scheduleNew[9] = 0;  // Wednesday
    // scheduleNew[10] = 0;  // Thursday
    // scheduleNew[11] = 0;  // Friday
    // scheduleNew[12] = 0;  // Saturday
    // scheduleNew[13] = 0;  // Sunday
    // scheduleNew[14] = 0;  // description
    // scheduleNew[15] = 0;  // email
    // scheduleNew[16] = 0;  // alert
    // scheduleNew[17] = 0;  // array location

    scheduleNew[0] = document.getElementById('totalML').value;
    scheduleNew[1] = document.getElementById('groupDoseStart').value;
    scheduleNew[2] = document.getElementById('groupDoseEnd').value;
    scheduleNew[3] = document.getElementById('perDoseML').value;
    scheduleNew[4] = document.getElementById('doseNumber').value;
    scheduleNew[6] = document.getElementById('repeatDays').value;
    scheduleNew[14] = document.getElementById('schDescription').value;
    
    if ((scheduleNew[1] == null) || (scheduleNew[1] == "")) {scheduleNew[1] = 0;}
    if ((scheduleNew[2] == null) || (scheduleNew[2] == "")) {scheduleNew[2] = 0;}
    
    scheduleNew[0] = parseInt(scheduleNew[0]);  // make sure value is numerical so we can compare properly
    scheduleNew[3] = parseInt(scheduleNew[3]);  // make sure value is numerical so we can compare properly
    scheduleNew[4] = parseInt(scheduleNew[4]);  // make sure value is numerical so we can compare properly

    
    if (isThisANumber(scheduleNew[3])) {} else {scheduleNew[3] = 0;}
    if (isThisANumber(scheduleNew[4])) {} else {scheduleNew[4] = 0;}
    // for (var i = 0; i < scheduleNew.length; i++) {
    //     console.log('scheduleNew[' + i + ']        = ' + scheduleNew[i]);
    // }
    
    if (source == 2) {document.getElementById('doseNumber').value = "";}  // empty number of doses
    else if (source == 3) {document.getElementById('perDoseML').value = "";}  // empty ml's per dose
    else if (source == 1) {  // save button
        if (scheduleNew[14] == "") {  // check description
            document.getElementById('fieldError7').style.width = "auto";
            document.getElementById('fieldError7').style.paddingLeft = "10px";
            document.getElementById('fieldError7').style.display = "inline-block";  // show error
            document.getElementById('fieldError7').innerHTML = "You need to enter number of days!";
            document.getElementById('schDescription').style.border = "2px solid rgb(255, 0, 0)";
            document.getElementById('schDescription').focus();
            validationFail = 7;
            return 0;
        }
        else if (((scheduleNew[0] == null) || (scheduleNew[0] == "")) || (scheduleNew[0] <= 0)) {  // check total milliliters
            document.getElementById('fieldError1').style.display = "inline-block";  // show error
            if ((scheduleNew[0] == null) || (scheduleNew[0] == "")) {document.getElementById('fieldError1').innerHTML = "Enter number of milliliters to be dosed!";}
            else {document.getElementById('fieldError1').innerHTML = "You need to dose at least 1 mL!";}
            document.getElementById('totalML').style.border = "2px solid rgb(255, 0, 0)";
            document.getElementById('totalML').focus();
            validationFail = 1;
            return 0;
        }
        else if ((scheduleNew[1] == null) || (scheduleNew[1] == "")) {  // check start time
            document.getElementById('fieldError2').style.display = "inline-block";  // show error
            document.getElementById('fieldError2').innerHTML = "Select a start time!";
            document.getElementById('groupDoseStart').style.border = "2px solid rgb(255, 0, 0)";
            document.getElementById('groupDoseStart').focus();
            validationFail = 2;
            return 0;
        }
        else if ((scheduleNew[2] == null) || (scheduleNew[2] == "")) {  // check finish time
            document.getElementById('fieldError2').style.display = "inline-block";  // show error
            document.getElementById('fieldError2').innerHTML = "Select a finish time!";
            document.getElementById('groupDoseEnd').style.border = "2px solid rgb(255, 0, 0)";
            document.getElementById('groupDoseEnd').focus();
            validationFail = 3;
            return 0;
        }
        else if (((scheduleNew[3] == null) || (scheduleNew[3] == "")) && ((scheduleNew[4] == null) || (scheduleNew[4] == ""))) {  // check mL per dose or number of doses option
            document.getElementById('fieldError4').style.display = "inline-block";  // show error
            document.getElementById('fieldError4').innerHTML = "Select an option above!";
            document.getElementById('perDoseML').style.border = "2px solid rgb(255, 0, 0)";
            document.getElementById('doseNumber').style.border = "2px solid rgb(255, 0, 0)";
            validationFail = 4;
            return 0;
        }
        else if ((scheduleNew[3] <= 0) && (scheduleNew[4] == "")) {  // check mL per dose or number of doses option
            document.getElementById('fieldError4').style.display = "inline-block";  // show error
            document.getElementById('fieldError4').innerHTML = "Value needs to be greater than 0";
            document.getElementById('perDoseML').style.border = "2px solid rgb(255, 0, 0)";
            validationFail = 5;
            return 0;
        }
        else if ((scheduleNew[3] == "") && (scheduleNew[4] <= 0)) {  // check mL per dose or number of doses option
            document.getElementById('fieldError4').style.display = "inline-block";  // show error
            document.getElementById('fieldError4').innerHTML = "Value needs to be greater than 0";
            document.getElementById('doseNumber').style.border = "2px solid rgb(255, 0, 0)";
            validationFail = 5;
            return 0;
        }
        else if (((scheduleNew[7] == 0) && (scheduleNew[8] == 0) && (scheduleNew[9] == 0) && (scheduleNew[10] == 0) && (scheduleNew[11] == 0) && (scheduleNew[12] == 0) && (scheduleNew[13] == 0)) && ((scheduleNew[6] == 0) || (scheduleNew[6] == "") || (scheduleNew[6] == null))) {  // check if no days were selected.  
            document.getElementById('fieldError5').style.display = "inline-block";  // show error
            document.getElementById('fieldError5').innerHTML = "You need to enter number of days!";
            document.getElementById('fieldError6').style.display = "inline-block";  // show error
            document.getElementById('fieldError6').innerHTML = 'You need to select a day for schedule to run or set "Repeat Every X Days"!';
            document.getElementById('repeatContainer').style.border = "2px solid rgb(255, 0, 0)";
            document.getElementById('schDayContainter').style.border = "2px solid rgb(255, 0, 0)";
            document.getElementById('schDayContainter').focus();
            validationFail = 6;
            return 0;
        }
        else if (scheduleNew[3] > scheduleNew[0]) {  // check if mL per dose is greater than total mL
            document.getElementById('fieldError4').style.display = "inline-block";  // show error
            document.getElementById('fieldError4').innerHTML = "Milliliters per dose can't be greater than total milliliters.";
            document.getElementById('perDoseML').style.border = "2px solid rgb(255, 0, 0)";
            document.getElementById('perDoseML').focus();
            validationFail = 8;
            return 0;
        }
        else {validationFail = 100;}  // validation passed
    }
    else if (validationFail > 0) {  // check if validation prompts need to be cleaned up when leaving fields
        if ((validationFail == 7) && (scheduleNew[14] != "")) {
            document.getElementById('fieldError7').style.display = "none";  // hide error
            document.getElementById('schDescription').style.border = "";
            validationFail = 0;
        }
        
        if ((validationFail == 1) && (scheduleNew[0] > 0)) {
            document.getElementById('fieldError1').style.display = "none";  // hide error
            document.getElementById('totalML').style.border = "";
            validationFail = 0;
        }

        if ((validationFail == 2) && (scheduleNew[1] != 0)) {
            document.getElementById('fieldError2').style.display = "none";  // hide error
            document.getElementById('groupDoseStart').style.border = "";
            validationFail = 0;
        }

        if ((validationFail == 3) && (scheduleNew[2] != 0)) {
            document.getElementById('fieldError2').style.display = "none";  // hide error
            document.getElementById('groupDoseEnd').style.border = "";
            validationFail = 0;
        }

        if ((validationFail == 4) && ((scheduleNew[3] > 0) || (scheduleNew[4] > 0))) {
            document.getElementById('fieldError4').style.display = "none";  // hide error
            document.getElementById('perDoseML').style.border = "";
            document.getElementById('doseNumber').style.border = "";
            validationFail = 0;
        }

        if ((validationFail == 5) && (((scheduleNew[3] > 0) && (scheduleNew[4] == "")) || ((scheduleNew[3] == "") && (scheduleNew[4] > 0)))) {
            document.getElementById('fieldError4').style.display = "none";  // hide error
            document.getElementById('perDoseML').style.border = "";
            document.getElementById('doseNumber').style.border = "";
            validationFail = 0;
        }

        if ((validationFail == 6) && ((scheduleNew[7] == 1) || (scheduleNew[8] == 1) || (scheduleNew[9] == 1) || (scheduleNew[10] == 1) || (scheduleNew[11] == 1) || (scheduleNew[12] == 1) || (scheduleNew[13] == 1) || (scheduleNew[6] > 0))) {  // check if no days were selected.  
            document.getElementById('fieldError5').style.display = "none";  // show error
            document.getElementById('fieldError6').style.display = "none";  // show error
            document.getElementById('schDayContainter').style.border = "";
            document.getElementById('repeatContainer').style.border = "";
            validationFail = 0;
        }

        if ((validationFail == 8) && (scheduleNew[0] >= scheduleNew[3])) {
            document.getElementById('fieldError4').style.display = "none";  // hide error
            document.getElementById('perDoseML').style.border = "";
            document.getElementById('doseNumber').style.border = "";
            validationFail = 0;
        }
    }
    
    if (scheduleNew[3] == "") {scheduleNew[3] = 0;}
    if (scheduleNew[4] == "") {scheduleNew[4] = 0;}
    if (scheduleNew[6] == "") {scheduleNew[6] = 0;}
    if ((source == 1) && (validationFail == 100)) {  // validation passed - send to backend
        // console.log('sending group schedule ============ ');
    
        // for (var i = 0; i < scheduleNew.length; i++) {
        //     console.log('scheduleNew[' + i + ']        = ' + scheduleNew[i]);
        // }
        // console.log('dosePinID[' + i + ']        = ' + dosePinID[i]);
        confirmDosingGroupSchedule(arrayLoc);
    }
    // console.log('validationFail =============== ' + validationFail);
}

function confirmDosingGroupSchedule(arrayLoc) {  // comfirm dosing group schedule
    $('#popupBackground').show();  // grey out background
    $('.ds18b20Popup-body').empty();
    ds18b20Popup.style.display = "block";
    document.querySelector("body").style.overflow = 'hidden';
    $('.ds18b20PopupHeader').empty();

    $(".ds18b20PopupHeader").append("Confirm Schedules");
    $(".ds18b20Popup-body").append(
        '<div style="text-align: center;">\
            <p>&nbsp;</p>\
            <p>Would you like to add the group schedule</p>\
            <div class="widgetButtonBox" id="widgetButtonBox">\
                <button class="button _wide" type="button" onclick="sendDosingGroupSchedule(' + arrayLoc + ')">Yes</button>\
                <button class="button _wide" type="button" onclick="closeDs18b20Popup()">No</button>\
            </div></br>\
        </div>');
}

function sendDosingGroupSchedule(arrayLoc) {  // send dosing group schedule to backend
    $('.ds18b20PopupHeader').empty();
    $('.ds18b20Popup-body').empty();

    $(".ds18b20PopupHeader").append("Adding Schedules");
    $(".ds18b20Popup-body").append(
        '<div style="text-align: center;">\
            <p>&nbsp;</p>\
            <p style="font-weight:bold">Adding Schedules...</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 = "92," + scheduleNew[0] + "," + secondsFromTime(scheduleNew[1]) + "," + secondsFromTime(scheduleNew[2]) + "," + scheduleNew[3] + "," + scheduleNew[4] + "," + scheduleNew[6] + "," + scheduleNew[7] + "," + scheduleNew[8] + "," + scheduleNew[9] + "," + scheduleNew[10] + "," + scheduleNew[11] + "," + scheduleNew[12] + "," + scheduleNew[13] + "," + scheduleNew[14] + "," + scheduleNew[15] + "," + scheduleNew[16] + "," + dosePinID[arrayLoc];
    sendToBackend(command);
}

function repeatDoseGroupSchedule() {  // new schedule repeat feature
    // console.log('repeatDoseGroupSchedule ---------------');
    if (scheduleNew[5] == 0) {  // repeat days not being used
        document.getElementById('repeatCheck').checked = true;
        document.getElementById('repeatDays').disabled = false;
        document.getElementById('repeatDays').style = "background-color:#FFFFFF; width:70px;";
        document.getElementById('repeatDays').focus();
        document.getElementById('repeatDays').select();
        document.getElementById('schDayContainter').style.display = "none";  // hide days
        scheduleNew[5] = 1;
        for (var i = 7; i < 14; i++) {  // set each day back to off
            scheduleNew[i] = 1;  // enable each day so we can disable
            doseGroupChangeDay(i-7);  // now change new day so we update variables and set each day disabled
        }
    }
    else {
        document.getElementById('repeatCheck').checked = false;
        document.getElementById('repeatDays').disabled = true;
        document.getElementById('repeatDays').value = '';
        document.getElementById('repeatDays').style = "background-color:#dfdfdf; width:70px;";
        document.getElementById('schDayContainter').style.display = "flex";  // show days
        scheduleNew[5] = 0;
        scheduleNew[6] = 0;
    }
}

function doseGroupChangeDay(day) {  // edit the days for new schedule
    // console.log('doseGroupChangeDay = ' + day);
    switch (day) {
        case 0:  // Monday
            if (scheduleNew[7] == 1) {
                document.getElementById('schDay1').checked = false;
                scheduleNew[7] = 0;
            }
            else {
                document.getElementById('schDay1').checked = true;
                scheduleNew[7] = 1;
            }
        break;
        case 1:
            if (scheduleNew[8] == 1) {
                document.getElementById('schDay2').checked = false;
                scheduleNew[8] = 0;
            }
            else {
                document.getElementById('schDay2').checked = true;
                scheduleNew[8] = 1;
            }
        break;
        case 2:
            if (scheduleNew[9] == 1) {
                document.getElementById('schDay3').checked = false;
                scheduleNew[9] = 0;
            }
            else {
                document.getElementById('schDay3').checked = true;
                scheduleNew[9] = 1;
            }
        break;
        case 3:
            if (scheduleNew[10] == 1) {
                document.getElementById('schDay4').checked = false;
                scheduleNew[10] = 0;
            }
            else {
                document.getElementById('schDay4').checked = true;
                scheduleNew[10] = 1;
            }
        break;
        case 4:
            if (scheduleNew[11] == 1) {
                document.getElementById('schDay5').checked = false;
                scheduleNew[11] = 0;
            }
            else {
                document.getElementById('schDay5').checked = true;
                scheduleNew[11] = 1;
            }
        break;
        case 5:
            if (scheduleNew[12] == 1) {
                document.getElementById('schDay6').checked = false;
                scheduleNew[12] = 0;
            }
            else {
                document.getElementById('schDay6').checked = true;
                scheduleNew[12] = 1;
            }
        break;
        case 6:
            if (scheduleNew[13] == 1) {
                document.getElementById('schDay7').checked = false;
                scheduleNew[13] = 0;
            }
            else {
                document.getElementById('schDay7').checked = true;
                scheduleNew[13] = 1;
            }
        break;
    }
    validateDoseGroupSch();
}

function doseGroupSchNewEmail() {
    // console.log('doseGroupSchNewEmail = ');
    if (scheduleNew[15] == 0) {  // add email enabled icon
        document.getElementById('email').innerHTML =
            '<i class="bi bi-envelope-fill">&nbsp; Email Enabled</i>';
        document.getElementById('email').style.color = "#00b610";
        scheduleNew[15] = 1;
    }
    else {
        document.getElementById('email').innerHTML =
            '<i class="bi bi-envelope-fill">&nbsp; Email Disabled</i>';
        document.getElementById('email').style.color = "#727272";
        scheduleNew[15] = 0;
    }
}

function doseGroupSchNewAlert() {
    // console.log('doseGroupSchNewAlert = ');
    if (scheduleNew[16] == 0) {  // add dashboard alert enabled icon
        document.getElementById('alert').innerHTML =
            '<i class="bi bi-exclamation-triangle-fill">&nbsp; Dashboard Alert Enabled</i>';
        document.getElementById('alert').style.color = "#00b610";
        scheduleNew[16] = 1;
    }
    else {
        document.getElementById('alert').innerHTML =
            '<i class="bi bi-exclamation-triangle-fill">&nbsp; Dashboard Alert Disabled</i>';
        document.getElementById('alert').style.color = "#727272";
        scheduleNew[16] = 0;
    }
}

function dosingCalibrate(arrayID) {  // calibration screen
    prevDisplayScreen = 10;  // set so pump details will show when finished
    removeFooter();

    document.getElementById('content').innerHTML +=
        '<div class="cleanScreen" id="cleanScreen">\
        <div class="dosingPumpsBoxContainer" id="dosingPumpsBoxContainer"></div>\
        </div>';

    document.getElementById('dosingPumpsBoxContainer').innerHTML =
    '<div class="settingsTitle">Calibrating ' + doseName[arrayID] + '</div>\
    <div class="doseCalibrationContainer">\
            <div class="doseCalibrationInstructions">\
                To calibrate your dosing pump you\'ll need a small measuring vessel, ideally it\
                should be close to the actual amount you\'ll be dosing during regular use. If you work with large doses\
                you can start with a small measuring vessel, once calibration is close you can increase the dose amount along with your\
                measuring vessel to fine tune. Before calibrating set the pump speed to your liking.\
                </br></br>\
                <ul class="numberBullets">\
                    <li>On the right side set the\
                        <span class="doseCalibrationInstructionsHighlight">calibration amount</span> to match your measuring vessel.\
                    </li>\
                    <li>Press the "Manual Dose" Button.</li>\
                    <li>If the vessel has more than the\
                        <span class="doseCalibrationInstructionsHighlight">calibration amount</span> increase the\
                        <span class="doseCalibrationInstructionsHighlight">pump rate</span> or vice versa.\
                    </li>\
                    <li>Empty the vessel and repeat steps 2-3 until you get the correct dose.</li>\
                    <li>Once complete you can exit.</li>\
                </ul>\
                <div class="dosePumpSpeedSliderBox">\
                    <div style="font-weight:bold; margin-left:16px;">\
                        Dosing Pump Speed\
                        <input class="nonFunctioningTextBox" type="text" id="dosePumpSpeedValue" value="" disabled="disabled">\
                    </div>\
                    <input type="range" min="0" max="100" oninput="moveDoseSpeedSlider(' + arrayID + ')" onmouseup="stopDoseSpeedSlider(' + arrayID + ')" value="" class="dosePumpSpeedSlider" id="dosePumpSpeedSlider_' + arrayID + '">\
                    (note moving slider will activate pump)\
                </div>\
            </div>\
            <div class="doseCalibrationSettings">\
                <div class="doseSettingsBox2" style="padding-top:10px; width:220px;">\
                    <div class="doseSettingsAmountBox" style="width:145px;">\
                        <div class="doseSettingsAmountLabel">Calibration Amount</div>\
                        <div class="doseSettingsAmount" id="changeDoseCalibrationAmount">' + doseCalibrationAmount[arrayID] +  ' mL</div>\
                    </div>\
                    <div class="parameterButtonBox">\
                        <button id="changeDoseCalibrationAmountUp" onmousedown="changeDoseCalibrationAmount(0,' + arrayID + ')" class="doseUpDownButton bi bi-arrow-up-short"></button></br>\
                        <button id="changeDoseCalibrationAmountDown" onmousedown="changeDoseCalibrationAmount(1,' + arrayID + ')" class="doseUpDownButton bi bi-arrow-down-short"></button>\
                    </div>\
                </div>\
                <div class="doseSettingsBox2" style="padding-top:10px; width:218px; border-top: solid 2px rgb(72, 72, 72);">\
                    <div class="doseSettingsAmountBox" style="width:145px;">\
                        <div class="doseSettingsAmountLabel">Pump Rate</div>\
                        <div class="doseSettingsAmount" id="changeDosePumpRate">' + dosePumpRate[arrayID] +  ' ms/mL</div>\
                    </div>\
                    <div class="parameterButtonBox">\
                        <button id="changePumpRateUp" onmousedown="changePumpRate(0,' + arrayID + ')" class="doseUpDownButton bi bi-arrow-up-short"></button></br>\
                        <button id="changePumpRateDown" onmousedown="changePumpRate(1,' + arrayID + ')" class="doseUpDownButton bi bi-arrow-down-short"></button>\
                    </div>\
                </div>\
            </div>\
    </div>';

    document.getElementById('dosingPumpsBoxContainer').innerHTML += 
        '<div class="widgetButtonBox">\
            <button class="button _wide" type="button" onclick="manualDoseCalibrate(`' + arrayID + '`)">Manual Dose</button>\
            <button class="button _wide" type="button" onclick="doseCalibrationDone(' + arrayID + '); dosingSettings()">Finished</button>\
        </div></br>';
    
    document.getElementById("dosePumpSpeedValue").value = dosePumpSpeed[arrayID] + "%";
    document.getElementById("dosePumpSpeedSlider_" + arrayID).value = dosePumpSpeed[arrayID];
    
    // press and hold when changing calibration dose amount
    var timeout;  // timer to track when button is held up or down
    var count = 0;
    var adjusted = 0;
    $('#changeDoseCalibrationAmountUp').mousedown(function () {  // action to take when mouse is down every 150ms
        timeout = setInterval(function () {
            adjusted = 1;
            changeDoseCalibrationAmount(0, editingArrayID);
            count++;  // count each cycle while mouse button is down
            if (count > 10) {  // after 10 cycles increase cycle speed to 50ms
                clearInterval(timeout); 
                timeout = setInterval(function () {
                    changeDoseCalibrationAmount(0, editingArrayID);
                    count++;
                    if (count > 60) {  // after 60 cycles increase cycle speed to 1ms
                        clearInterval(timeout);
                        timeout = setInterval(function () {
                            changeDoseCalibrationAmount(0, editingArrayID);
                        }, 1);
                    }
                }, 50);
            }
        }, 150);
    }).mouseup(function () {  // stop action when mouse is up
        count = 0;
        adjusted = 0;
        saveCalibrationAmount();
        clearInterval(timeout);
    }).mouseout(function () {  // stop action when mouse moves off up/down button
        count = 0;
        if (adjusted == 1) {saveCalibrationAmount();}
        adjusted = 0;
        clearInterval(timeout);
    });
    
    $('#changeDoseCalibrationAmountDown').mousedown(function () {  // action to take when mouse is down every 150ms
        timeout = setInterval(function () {
            adjusted = 1;
            changeDoseCalibrationAmount(1, editingArrayID);
            count++;  // count each cycle while mouse button is down
            if (count > 10) {  // after 10 cycles increase cycle speed to 50ms
                clearInterval(timeout); 
                timeout = setInterval(function () {
                    changeDoseCalibrationAmount(1, editingArrayID);
                    count++;
                    if (count > 60) {  // after 60 cycles increase cycle speed to 1ms
                        clearInterval(timeout);
                        timeout = setInterval(function () {
                            changeDoseCalibrationAmount(1, editingArrayID);
                        }, 1);
                    }
                }, 50);
            }
        }, 150);
    }).mouseup(function () {  // stop action when mouse is up
        count = 0;
        adjusted = 0;
        saveCalibrationAmount();
        clearInterval(timeout);
    }).mouseout(function () {  // stop action when mouse moves off up/down button
        count = 0;
        if (adjusted == 1) {saveCalibrationAmount();}
        adjusted = 0;
        clearInterval(timeout);
    });
    
    // press and hold when changing pump rate
    $('#changePumpRateUp').mousedown(function () {  // action to take when mouse is down every 150ms
        timeout = setInterval(function () {
            adjusted = 1;
            changePumpRate(0, editingArrayID);
            count++;  // count each cycle while mouse button is down
            if (count > 10) {  // after 10 cycles increase cycle speed to 50ms
                clearInterval(timeout); 
                timeout = setInterval(function () {
                    changePumpRate(0, editingArrayID);
                    count++;
                    if (count > 60) {  // after 60 cycles increase cycle speed to 1ms
                        clearInterval(timeout);
                        timeout = setInterval(function () {
                            changePumpRate(0, editingArrayID);
                        }, 1);
                    }
                }, 50);
            }
        }, 150);
    }).mouseup(function () {  // stop action when mouse is up
        count = 0;
        adjusted = 0;
        savePumpRate();
        clearInterval(timeout);
    }).mouseout(function () {  // stop action when mouse moves off up/down button
        count = 0;
        if (adjusted == 1) {savePumpRate();}
        adjusted = 0;
        clearInterval(timeout);
    });
    
    $('#changePumpRateDown').mousedown(function () {  // action to take when mouse is down every 150ms
        timeout = setInterval(function () {
            adjusted = 1;
            changePumpRate(1, editingArrayID);
            count++;  // count each cycle while mouse button is down
            if (count > 10) {  // after 10 cycles increase cycle speed to 50ms
                clearInterval(timeout); 
                timeout = setInterval(function () {
                    changePumpRate(1, editingArrayID);
                    count++;
                    if (count > 60) {  // after 60 cycles increase cycle speed to 1ms
                        clearInterval(timeout);
                        timeout = setInterval(function () {
                            changePumpRate(1, editingArrayID);
                        }, 1);
                    }
                }, 50);
            }
        }, 150);
    }).mouseup(function () {  // stop action when mouse is up
        count = 0;
        adjusted = 0;
        savePumpRate();
        clearInterval(timeout);
    }).mouseout(function () {  // stop action when mouse moves off up/down button
        count = 0;
        if (adjusted == 1) {savePumpRate();}
        adjusted = 0;
        clearInterval(timeout);
    });
}

function moveDoseSpeedSlider(arrayID){  // update slider when moved and send value to backend
    // console.log('moveDoseSpeedSlider =============== ' + arrayID);
    dosePumpSpeed[arrayID] = document.getElementById("dosePumpSpeedSlider_" + arrayID).value;
    document.getElementById("dosePumpSpeedValue").value = dosePumpSpeed[arrayID] + "%";
    stopSendingData = 100;  // pause communcations
    var command = "90, " + dosePinID[arrayID] + "," + dosePumpSpeed[arrayID];
    sendToBackend(command);  // send slider value to backend
}

function stopDoseSpeedSlider(arrayID){  // when slider is released make sure last value is sent to backend
    // console.log('stopDoseSpeedSlider =============== ' + arrayID);
    dosePumpSpeed[arrayID] = document.getElementById("dosePumpSpeedSlider_" + arrayID).value;
    document.getElementById("dosePumpSpeedValue").value = dosePumpSpeed[arrayID] + "%";
    stopSendingData = 0;  // resume communcations
    var command = "91, " + dosePinID[arrayID] + "," + dosePumpSpeed[arrayID];
    sendToBackend(command);  // send slider value to backend
}

function moveStirrerSpeedSlider(arrayID){  // update slider when moved and send value to backend
    // console.log('moveStirrerSpeedSlider =============== ' + arrayID);
    stirrerSpeed[arrayID] = document.getElementById("dosePumpSpeedSlider_" + arrayID).value;
    document.getElementById("dosePumpSpeedValue").value = stirrerSpeed[arrayID] + "%";
    stopSendingData = 100;  // pause communcations
    var command = "99, " + stirrerPinID[arrayID] + "," + stirrerSpeed[arrayID];
    sendToBackend(command);  // send slider value to backend
}

function stopStirrerSpeedSlider(arrayID){  // when slider is released make sure last value is sent to backend
    // console.log('stopStirrerSpeedSlider =============== ' + arrayID);
    stirrerSpeed[arrayID] = document.getElementById("dosePumpSpeedSlider_" + arrayID).value;
    document.getElementById("dosePumpSpeedValue").value = stirrerSpeed[arrayID] + "%";
    stopSendingData = 0;  // resume communcations
    var command = "100, " + stirrerPinID[arrayID] + "," + stirrerSpeed[arrayID];
    sendToBackend(command);  // send slider value to backend
}

function changeReservoirColor(picker, arrayID) {  // 
    // console.log('picker =============== ' + picker.toString()); 
    var color = picker.toString();
    $('#doseTubeDiv_' + [arrayID]).css('background','linear-gradient(90deg, ' + color + ' 100%, white 00%)');
    $('#doseTubeDiv_' + [arrayID]).css('background-repeat', 'no-repeat');
    doseReservoirColor[arrayID] = color;
    doseFillReservoirSettings(arrayID);
}

function saveReservoirColor(picker, arrayID) {  // 
    // console.log('saveReservoirColor =============== ' + picker.toString()); 
    $.ajax({  // save sort type to database
        method: "POST",
        url: "/php/dosingSaveReservoirColor.php",
        dataType: "text/plain",
        data: {
            "i": doseID[arrayID],
            "c": picker.toString(),
        }
    });
}

function changeDosingName(arrayID)  // 
{
    // console.log('changeDosingName =============== ' + arrayID);    
    var divExists = document.getElementById("doseSettingsName_" + arrayID);  // check if div ID is drawn
    if(divExists){
        document.getElementById('doseSettingsName_' + arrayID).innerHTML = 
            '<input class="editDoserName" type="text" id="editDoserName" value="' + doseName[arrayID] + '" onfocusout="saveDosingName(' + arrayID + ')" autocomplete="off">\
            <i class="bi bi-check saveCheckmark" id="saveCheckmark" onclick="saveDosingName(' + arrayID + ')"></i>';

        document.getElementById('editDoserName').select();

        document.getElementById("editDoserName")
            .addEventListener("keyup", function(event) {  // save name if enter key is pressed while editing
                event.preventDefault();
                if (event.keyCode === 13) {  // enter key
                    document.getElementById("saveCheckmark").click();
                }
            });
    }
}

function saveDosingName(arrayID)  // refill reservoir
{
    // console.log('saveDosingName =============== ' + arrayID);
    var divExists = document.getElementById("doseSettingsName_" + arrayID);  // check if div ID is drawn
    if(divExists){
        doseName[arrayID] = document.getElementById('editDoserName').value;
        document.getElementById('doseSettingsName_' + arrayID).innerHTML = 
            doseName[arrayID] + '<i class="bi bi-pencil-fill editPencil" onclick="changeDosingName(' + arrayID + ')"></i>';

        $.ajax({  // save custom name
            method: "POST",
            url: "/php/dosingSaveName.php",
            dataType: "text/plain",
            data: {
                "i": doseID[arrayID],
                "p": dosePinID[arrayID],
                "n": doseName[arrayID]
            }
        });
    }
}

function changeDoseInterval(direction, arrayID) {  // change minimum interval between doses
    // console.log('changeDoseInterval =============== ' + arrayID); 
    editingArrayID = arrayID;  // capature arrayID being adjusted so we can use to hold button down to increase/decrease value

    if (direction == 0) {  // up
        doseInterval[arrayID]++;
        if (doseInterval[arrayID] >= 10000) {doseInterval[arrayID] = 0;}
    }
    else if (direction == 1) {  // down
        doseInterval[arrayID]--;
        if (doseInterval[arrayID] < 0) {doseInterval[arrayID] = 9999;}
    }
    document.getElementById('doseInterval_' + arrayID).innerHTML = doseInterval[arrayID] + ' <span style="font-size:18px;">Minutes</span>';
}

function saveDoseInterval()  // save minimum interval between doses
{
    // console.log('saveDoseInterval =============== ' + editingArrayID);    
    var command = "89, " + dosePinID[editingArrayID] + "," + doseInterval[editingArrayID];
    sendToBackend(command);  // 
}

function changeReservoirCapacity(direction, arrayID) {  // 
    // console.log('changeReservoirCapacity =============== ' + arrayID); 
    editingArrayID = arrayID;  // capature arrayID being adjusted so we can use to hold button down to increase/decrease value

    if (direction == 0) {  // up
        doseReservoirSize[arrayID]++;
        if (doseReservoirSize[arrayID] >= 10000) {doseReservoirSize[arrayID] = 1;}
    }
    else if (direction == 1) {  // down
        doseReservoirSize[arrayID]--;
        if (doseReservoirSize[arrayID] <= 0) {doseReservoirSize[arrayID] = 9999;}
    }
    document.getElementById('doseReservoirSize_' + arrayID).innerHTML = doseReservoirSize[arrayID] + " mL";
}

function saveReservoirCapacity()  // save reservoir capacity
{
    // console.log('saveReservoirCapacity =============== ' + editingArrayID);    
    var command = "82, " + dosePinID[editingArrayID] + "," + doseReservoirSize[editingArrayID];
    sendToBackend(command);  //
    refillDoseReservoirConfirm(editingArrayID);
}

function changeResAlertML(direction, arrayID) {  // 
    // console.log('changeResAlertML =============== ' + arrayID); 
    editingArrayID = arrayID;  // capature arrayID being adjusted so we can use to hold button down to increase/decrease value

    if (direction == 0) {  // up
        doseResAlertML[arrayID]++;
        if (doseResAlertML[arrayID] >= 10000) {doseResAlertML[arrayID] = 1;}
    }
    else if (direction == 1) {  // down
        doseResAlertML[arrayID]--;
        if (doseResAlertML[arrayID] <= 0) {doseResAlertML[arrayID] = 9999;}
    }
    document.getElementById('doseResAlertML_' + arrayID).innerHTML = doseResAlertML[arrayID] + " mL";
}

function saveResAlertLevel()  // save reservoir alert level
{
    // console.log('saveResAlertLevel =============== ' + editingArrayID);    
    var command = "95, " + dosePinID[editingArrayID] + "," + doseResAlertML[editingArrayID];
    sendToBackend(command);  // 
}

function doseDisableReser(arrayID) {  // disable reservoir
    // console.log('doseDisableReser =============== ' + arrayID); 
    if (doseDisableRes[arrayID] == 0) {
        doseDisableRes[arrayID] = 1;
        document.getElementById('doseDisableResLabel_' + arrayID).innerHTML = "Reservoir Disabled";
        document.getElementById('resEnabled').innerHTML = "dosing pump will run</br>when reservoir is empty";
    }
    else if (doseDisableRes[arrayID] == 1) {
        doseDisableRes[arrayID] = 0;
        document.getElementById('doseDisableResLabel_' + arrayID).innerHTML = "Reservoir Enabled";
        document.getElementById('resEnabled').innerHTML = "dosing pump will not</br>run when reservoir is empty";
    }

    var command = "81, " + dosePinID[arrayID] + "," + doseDisableRes[arrayID];
    sendToBackend(command);  // 
}

function enableDoseStirrer(arrayID) {  // 
    // console.log('enableDoseStirrer =============== ' + arrayID); 
    if (doseStirrer[arrayID] == 0) {
        doseStirrer[arrayID] = 1;
        document.getElementById('doseStirrerLabel_' + arrayID).innerHTML = "Stirrer Enabled";
        $('#stirrerBox').show();  // show dropdown
    }
    else if (doseStirrer[arrayID] == 1) {
        doseStirrer[arrayID] = 0;
        doseStirrerID[arrayID] = 0;
        document.getElementById('stirrerPortSelect').value = 0;
        document.getElementById('doseStirrerLabel_' + arrayID).innerHTML = "Stirrer Disabled";
        $('#stirrerBox').hide();  // hide dropdown
        document.getElementById('fieldError1').style.display = "none";  // hide error
        document.getElementById('stirrerPortSelect').style.border = "";
    }

    var command = "84, " + dosePinID[arrayID] + "," + doseStirrer[arrayID];
    sendToBackend(command);  // 
}

function refillDoseReservoirConfirm(arrayID) {  // delete custom rule
    // console.log('refillDoseReservoirConfirm------ ' + arrayID);
    $('#popupBackground').show();  // grey out background
    $('.ds18b20Popup-body').empty();
    ds18b20Popup.style.display = "block";
    document.querySelector("body").style.overflow = 'hidden';
    $('.ds18b20PopupHeader').empty();
    
    $(".ds18b20PopupHeader").append("Refill Reservoir");
    $(".ds18b20Popup-body").append(
        '<div style="text-align: center;">\
            <p>&nbsp;</p>\
            <p>Are you sure you want to refill the reservoir for "' + doseName[arrayID] + '"?</p>\
            <div class="widgetButtonBox">\
                <button class="button _wide" type="button" onclick="refillDoseReservoir(`' + arrayID + '`)">Yes</button>\
                <button class="button _wide" type="button" onclick="closeDs18b20Popup()">No</button>\
            </div></br>\
        </div>');
}

function refillDoseReservoir(arrayID)  // refill reservoir
{
    // console.log('refillDoseReservoir =============== ' + arrayID); 
    closeDs18b20Popup();
    doseReservoirRemain[arrayID] = doseReservoirSize[arrayID];

    var divExists = document.getElementById("doseReservoirSize_" + arrayID);  // check if div ID is drawn
    if (!divExists) {divExists = document.getElementById("doseSettingsName_" + arrayID);}
    if(divExists){
        doseFillReservoirSettings(arrayID);
        var command = "86, " + dosePinID[arrayID];
        sendToBackend(command);  // 
        document.getElementById('doseRemainingDiv_' + arrayID).innerHTML = round(doseReservoirRemain[arrayID], 1) + " mL's Remaining";
    }
}

function changePumpRate(direction, arrayID) {  // change dose amount
    // console.log('changePumpRate =============== ' + arrayID); 
    editingArrayID = arrayID;  // capature arrayID being adjusted so we can use to hold button down to increase/decrease value
    if (direction == 0) {
        dosePumpRate[arrayID]++;
        if (dosePumpRate[arrayID] > 2000) {dosePumpRate[arrayID] = 1;}
    }
    else if (direction == 1) {
        dosePumpRate[arrayID]--;
        if (dosePumpRate[arrayID] <= 0) {dosePumpRate[arrayID] = 2000;}
    }    

    document.getElementById('changeDosePumpRate').innerHTML = dosePumpRate[arrayID] + " ms/mL";
}

function savePumpRate()  // save pump rate
{
    // console.log('savePumpRate =============== ' + editingArrayID);
    var command = "83, " + dosePinID[editingArrayID] + "," + dosePumpRate[editingArrayID];
    sendToBackend(command);  // 
}

function changeDoseCalibrationAmount(direction, arrayID) {  // change calibration dose amount
    // console.log('changeDoseCalibrationAmount =============== ' + direction); 
    editingArrayID = arrayID;  // capature arrayID being adjusted so we can use to hold button down to increase/decrease value
    if (direction == 0) {
        doseCalibrationAmount[arrayID]++;
        if (doseCalibrationAmount[arrayID] > 1000) {doseCalibrationAmount[arrayID] = 1;}
    }
    else if (direction == 1) {
        doseCalibrationAmount[arrayID]--; 
        if (doseCalibrationAmount[arrayID] <= 0) {doseCalibrationAmount[arrayID] = 1;}
    }    

    document.getElementById('changeDoseCalibrationAmount').innerHTML = doseCalibrationAmount[arrayID] + " mL";
}

function saveCalibrationAmount() {  // save calibration dose amount
    // console.log('saveCalibrationAmount =============== ' + editingArrayID);
    var command = "85, " + dosePinID[editingArrayID] + "," + doseCalibrationAmount[editingArrayID];
    sendToBackend(command);  // 
}

function manualDoseConfirm(arrayID) {  // enter amount to be dosed
    $('#popupBackground').show();  // grey out background
    $('.ds18b20Popup-body').empty();
    ds18b20Popup.style.display = "block";
    document.querySelector("body").style.overflow = 'hidden';
    $('.ds18b20PopupHeader').empty();

    $(".ds18b20PopupHeader").append("Manual Dosing");
    $(".ds18b20Popup-body").append(
        `<div style="text-align: center;">
            <p>&nbsp;</p>
            <p>How much would you like to dose?</p>
            <div class="doseGroupContainer" style="width:190px">
                <input class="doseGroupField" style="width:100px" type="number" id="doseML" autocomplete="off">
                <div class="doseGroupLabel">Milliliters</div>
                <div class="fieldError" id="fieldError"></div>\
            </div>
            <div class="widgetButtonBox" id="widgetButtonBox">
                <button class="button _wide" type="button" onclick="manualDose(` + arrayID + `)">Dose</button>
                <button class="button _wide" type="button" onclick="closeDs18b20Popup()">Cancel</button>
            </div></br>
        </div>`);

    document.getElementById('doseML').focus();
}

function manualDose(arrayID) {  // manually dose
    // console.log('manualDose =============== ' + arrayID);
    var dose = document.getElementById('doseML').value;

    if ((dose == null) || (dose == "")) {  // check if password is blank.    
        document.getElementById('fieldError').style.display = "inline-block";  // show error
        document.getElementById('fieldError').innerHTML = "Enter amount to dose!";
        document.getElementById('doseML').style.border = "2px solid rgb(255, 0, 0)";
        document.getElementById('doseML').focus();
        return 0;
    }
    else {
        document.getElementById('fieldError').style.display = "none";  // show error
        document.getElementById('doseML').style.border = "";
    }

    closeDs18b20Popup();
    
    if (((doseDisableRes[arrayID] == 0) && (doseReservoirRemain[arrayID] >= +dose)) || (doseDisableRes[arrayID] == 1))
    {
        var command = "80, " + dosePinID[arrayID] + "," + dose;
        sendToBackend(command);  // 

        doseReservoirRemain[arrayID] = doseReservoirRemain[arrayID] - dose;
        document.getElementById('doseRemainingDiv_' + arrayID).innerHTML = round(doseReservoirRemain[arrayID], 1) + " mL's Remaining";
    }
    else {document.getElementById('doseRemainingDiv_' + arrayID).innerHTML = "Low Reservoir - REFILL";}
    
    doseFillReservoirSettings(arrayID);
}

function doseFillReservoirSettings(arrayID)  // calculate how much remains in reservoir
{
    // full reservoir = position 24px and size 113px
    // empty reservoir = position 136px and size 1px
    // full scale is 112px
    // 1% = 1.12px
    dosePercentageRemaining[arrayID] = (doseReservoirRemain[arrayID] / doseReservoirSize[arrayID]) * 100;
    var position = (136 - (dosePercentageRemaining[arrayID] * 1.12)) + "px";
    var size = (1 + (dosePercentageRemaining[arrayID] * 1.12)) + "px";
    var size2 = (1 + (dosePercentageRemaining[arrayID] * 1.05)) + "px";
    var divExists = document.getElementById("doseTubeDiv_" + arrayID);  // check if div ID is drawn
    if(divExists){
        document.getElementById('doseTubeDiv_' + [arrayID]).style.backgroundPosition = "7px " + position;  // set background position
        document.getElementById('doseTubeDiv_' + [arrayID]).style.backgroundSize = "32px " + size;  // set background size

        document.getElementById('doseClickColor_' + [arrayID]).style.height = size2;  // set background size
        document.getElementById('doseClickColor_' + [arrayID]).style.marginTop = "-" + size2;  // set background size
    }
}

function manualDoseCalibrate(arrayID) {  // manually dose during calibration
    // console.log('manualDoseCalibrate =============== ' + arrayID);    
    var command = "87, " + dosePinID[arrayID];
    sendToBackend(command);  // 
}

function doseCalibrationDone(arrayID) {  // calibration finished
    // console.log('doseCalibrationDone =============== ' + arrayID);
    var command = "88," + dosePinID[arrayID];
    sendToBackend(command);  // 
}

function updateDosingStatus(id, value, resRemain) {  // update dosing port status as data comes in from backend   // using to send dosing pump status to update UI, need to replace with web socket sending command to frontend without request
    // console.log("updateDosingStatus = " + id + ", " + value);
    if (displayScreen == 0) {  // dashboard
        for (var i=0; i < dosePinID.length; i++) {
            if (dosePinID[i] == id) {
                if (value == 1) {  // stirring
                    doseStatus[i] = value;  // record new state
                    document.getElementById('doseTubeDiv_' + i).style.color = "#FF0000";
            
                    document.getElementById('doseTubeDiv_' + i).innerHTML =
                    '<span id="doseRemainingDiv_' + i + '">Stirring</span></br>\
                    <div id="doseClickColor_' + i + '"></div>\
                    <img class="reservoirImage" height="130px;" src="images/icons/doseReservoir_Red.png">';
                }
                else if (value == 2) {  // settling
                    doseStatus[i] = value;  // record new state
                    document.getElementById('doseTubeDiv_' + i).style.color = "#FF0000";
            
                    document.getElementById('doseTubeDiv_' + i).innerHTML =
                    '<span id="doseRemainingDiv_' + i + '">Settling</span></br>\
                    <div id="doseClickColor_' + i + '"></div>\
                    <img class="reservoirImage" height="130px;" src="images/icons/doseReservoir_Red.png">';
                }
                else if (value == 3) {  // dosing
                    doseStatus[i] = value;  // record new state
                    document.getElementById('doseTubeDiv_' + i).style.color = "#FF0000";
            
                    document.getElementById('doseTubeDiv_' + i).innerHTML =
                    '<span id="doseRemainingDiv_' + i + '">Dosing</span></br>\
                    <div id="doseClickColor_' + i + '"></div>\
                    <img class="reservoirImage" height="130px;" src="images/icons/doseReservoir_Red.png">';
                }
                else if ((doseStatus[i] == 3) && (value == 0)) {  // finished
                    doseStatus[i] = value;  // record new state
                    doseReservoirRemain[i] = resRemain;
                    doseFillReservoirSettings(i);
            
                    document.getElementById('doseTubeDiv_' + i).style.color = "#FFFFFF";

                    document.getElementById('doseTubeDiv_' + i).innerHTML =
                        '<span id="doseRemainingDiv_' + i + '">' + round(doseReservoirRemain[i], 1) + '</span></br>\
                        <div id="doseClickColor_' + i + '"></div>\
                        <img class="reservoirImage" height="130px;" src="images/icons/doseReservoir_White.png">';
                }
                break;
            }
        }
    }
    else if (displayScreen == 10) {  // dosing page
        for (var i=0; i < dosePinID.length; i++) {
            if (dosePinID[i] == id) {
                if (value == 1) {  // stirring
                    doseStatus[i] = value;  // record new state
                    document.getElementById('doseRemainingDiv_' + i).innerHTML = "Stirring";

                    $(document).ready(function() {
                        $("#reservoirImage_" + i).attr('src',"images/icons/doseReservoir_Red.png");
                    });
                }
                else if (value == 2) {  // settling
                    doseStatus[i] = value;  // record new state
                    document.getElementById('doseRemainingDiv_' + i).innerHTML = "Settling";

                    $(document).ready(function() {
                        $("#reservoirImage_" + i).attr('src',"images/icons/doseReservoir_Red.png");
                    });
                }
                else if (value == 3) {  // dosing
                    doseStatus[i] = value;  // record new state
                    document.getElementById('doseRemainingDiv_' + i).innerHTML = "Dosing";

                    $(document).ready(function() {
                        $("#reservoirImage_" + i).attr('src',"images/icons/doseReservoir_Red.png");
                    });
                }
                else if ((doseStatus[i] == 3) && (value == 0)) {  // finished
                    doseStatus[i] = value;  // record new state
                    doseReservoirRemain[i] = resRemain;

                    document.getElementById('doseRemainingDiv_' + i).innerHTML = round(doseReservoirRemain[i], 1) + ' mL\'s Remaining';

                    $(document).ready(function() {
                        $("#reservoirImage_" + i).attr('src',"images/icons/doseReservoir_White.png");
                    });
                }
                break;
            }
        }
    }
    else {  // all other pages
        for (var i=0; i < dosePinID.length; i++) {
            if (dosePinID[i] == id) {
                if (value == 1) {  // stirring
                    doseStatus[i] = value;  // record new state
                }
                else if (value == 2) {  // settling
                    doseStatus[i] = value;  // record new state
                }
                else if (value == 3) {  // dosing
                    doseStatus[i] = value;  // record new state
                }
                else if ((doseStatus[i] == 3) && (value == 0)) {  // finished
                    doseStatus[i] = value;  // record new state
                    doseReservoirRemain[i] = resRemain;
                }
                break;
            }
        }
    }
}
