/** Requires that the main page calling this has an array list of company employees called 'companies' to pull from. **/
function getSUCompanyEmployeesAsSelectOptions(selectName, selected="-1", style="") {
    // Start the inner HTML with nobody
    var returnHtml='<option value="-1" selected>Nobody</option>';

    // Determine if the SU company is defined
    if (typeof(companies["1"]) !== 'undefined' && 
        companies["1"] !== null) {
        // Add the SU company group
        returnHtml = returnHtml + '<optgroup label="Evolve Engineering & Software">';

        // Loop through the values in super company's array
        var suCompanyEmployees = companies["1"].employees;
        for(i = 0; i < suCompanyEmployees.length; i++) {
            var selectedText = '';
            
            // Determine if this is the one selected
            if (suCompanyEmployees[i].UserID === selected) {
                // Set this one as selected
                selectedText='selected';
                
            }
            // add this option
            returnHtml = returnHtml + '<option class="EmployeeOption" ' + selectedText + ' value="' + suCompanyEmployees[i].UserID + '">' + suCompanyEmployees[i].UserName + '</option>';
        }
    }

    // Add the select tag
    returnHtml = '<select style="' + style + '" id="' + selectName + '" name="' + selectName + '">' + returnHtml + '</select>';

    // Return what we got
    return returnHtml;
} 

function openPage(pageName) {
    // Hide all elements with class="tabcontent" by default */
    var i, tabcontent;
    tabcontent = document.getElementsByClassName("tabcontent");
    for (i = 0; i < tabcontent.length; i++) {
        tabcontent[i].style.display = "none";
    }

    // Show the specific tab content
    document.getElementById(pageName).style.display = "block";
}

function openChildPage(pageName, theTab) {
    // Hide all elements with class="tabcontent" by default */
    var i, tabcontent;
    tabcontent = document.getElementsByClassName("childtabcontent");
    for (i = 0; i < tabcontent.length; i++) {
        tabcontent[i].style.display = "none";
    }

    // Now change the buttons to make it look like a tab
    var tablinks = document.getElementsByClassName("childtablink");
    for (i = 0; i < tablinks.length; i++) {  
        // Set a normal look
        tablinks[i].style = "border-left: 1px solid gray; border-right: 1px solid gray; border-top: 1px solid gray; border-bottom: 2px solid forestgreen;";
    }
    
    // Set the passed in tab link as the active looking tab
    theTab.style = "border-left: 2px solid forestgreen; border-right: 2px solid forestgreen; border-top: 2px solid forestgreen; border-bottom: none;";
    
    // Show the specific tab content
    document.getElementById(pageName).style.display = "block";
}

function toggleDisableOfChildren(parentName, isDisabled){
    // Get the child controls of the passed in parent name to disable them
    var childNodes = document.getElementById(parentName).getElementsByTagName('*');
    
    // Loop through the children
    for (var node of childNodes) {
        // Disable this child in the loop
        node.disabled = isDisabled;
    }    
};

// Variable and function go together.  Requires no other variables named this.
var theImageElementName = "";
function PreviewImage(fileElementName, imgName) {
    // Create a reader and read the file that is in the file element
    var oFReader = new FileReader();
    oFReader.readAsDataURL(document.getElementById(fileElementName).files[0]);

    // Set the image file name to be loading image into
    theImageElementName = imgName;
    
    // Create and onload of the reader created that will populate the image element
    oFReader.onload = function (oFREvent, imgName) {
        // Populate the image element
        document.getElementById(theImageElementName).src = oFREvent.target.result;

        // Show the image element
        document.getElementById(theImageElementName).style.display='block';
    };
};

function getHumanReadableFileSize(size){
    // Set an internal variable to work with
    var fSize = size;
    
    // Create the array of different size annotations
    var fSExt = new Array('Bytes', 'KB', 'MB', 'GB');
    
    // Loop throught the size to determine on which level it is
    var annotationPosition=0;
    while(fSize>900){
        // do the math
        fSize/=1024;
        
        // Increment the value for the array
        annotationPosition++;
    }
    
    // Return the visual string to let the user know the file size in whatever increment
    return Math.round(fSize*100)/100 + ' ' + fSExt[annotationPosition];
}

/* 
 * General javascript functions that can be used in many places of the code
 */
function date2str(x, y) {
    var z = {
        M: x.getMonth() + 1,
        d: x.getDate(),
        h: x.getHours(),
        m: x.getMinutes(),
        s: x.getSeconds()
    };
    y = y.replace(/(M+|d+|h+|m+|s+)/g, function(v) {
        return ((v.length > 1 ? "0" : "") + eval('z.' + v.slice(-1))).slice(-2)
    });

    return y.replace(/(y+)/g, function(v) {
        return x.getFullYear().toString().slice(-v.length)
    });
}    

function populateCurrentDateTime(/*Args[controlToPopulate,format]*/){
    // Get the control off of the first passed in argument, which should be the control to populate
    var controlToPopulate = document.getElementById(arguments[0]);

    // Create the current date
    var currentDateString = date2str(new Date(), arguments[1]);

    // populate the control with the formatted date
    controlToPopulate.value = currentDateString;
}

function div_toggleVisibilityOnCheckbox() {
    // Get the info on whether or not to show the subtask
    var checkBox = document.getElementById(arguments[0]);

    // Determine if it should be shown
    if (checkBox!==null){
        if ((checkBox.checked===true && arguments[2]==='NORMAL') ||
            (checkBox.checked===false && arguments[2]==='OPPOSITE')){
            // Get the outer div and show it
            div_show(arguments[1]);
        }
        else {
            // Get the outer div and show it
            div_hide(arguments[1]);
        }
    }
}

//Function To Display Divs
function div_showCheckArea() {
    // Get the info on whether or not to show the subtask
    var checkBox = document.getElementById(arguments[0]);

    // Check the checkbox
    checkBox.checked=true;
    
    // Get the div and show it
    div_show(arguments[1]);
}

function div_toggleClassVisibility() {
    // Get all expandable branches 
    var theClass = document.getElementsByClassName(arguments[1]);
    var theClassAnchor = document.getElementsByClassName(arguments[2]);
    
    // Loop through the branches
    for (var i = 0; i < theClass.length; i++) {
        // Get the computed style
        var display = window.getComputedStyle(theClass[i]).display;
        
        // Check the class ID to see if it is the one we want to change
        if (theClass[i].id!==arguments[0]){
            // Change it to be hidden
            theClass[i].style.display = "none";
            
            // Detemine if the class of the control to open is a branch
            if (theClass[i].className=="expandedBranch"){
                // Set the value to be a right arrow
                theClassAnchor[i].innerText="→";
            }
        }
        else {
            // Determine if it is currently hidden
            if (display=="none"){
                // Change it to be shown
                theClass[i].style.display = "block";
                
                // Detemine if the class of the control to open is a branch
                if (theClass[i].className=="expandedBranch"){
                    // Set the value to be a down arrow
                    theClassAnchor[i].innerText="↓";
                }
            }
            else {
                // Change it to be hidden
                theClass[i].style.display = "none";
                
                // Detemine if the class of the control to open is a branch
                if (theClass[i].className=="expandedBranch"){
                    // Set the value to be a right arrow
                    theClassAnchor[i].innerText="→";
                }
            }
        }
    }    
}

//Function To Display Popup
function div_show() {
    // Get the outer div and show it
    document.getElementById(arguments[0]).style.display = "block";
}

//Function to Hide Popup
function div_hide(){
    // Get the outer div and hide it
    document.getElementById(arguments[0]).style.display = "none";
} 

/*
 * Code used in multiple places, but not everywhere.
 */


/* Used 0n the add and update task pages */
function enableOrderControl(machineValue){
//    $("option[value='Machining']")
//        .attr("disabled", "disabled")
//        .siblings().removeAttr("disabled");
  
    // Get the machine order control
    var machineOrderCtrl = document.getElementById("machineTaskOrder");
    var hiddenOrderCtrl = document.getElementById("hiddenMachineTaskOrder");
    var isPendingApprovalCtrl = document.getElementById("isPendingApproval"); 
    var isWaitingToBeReviewedCtrl = document.getElementById("isWaitingToBeReviewed"); 
    var isPendingToolsCtrl = document.getElementById("isPendingTools"); 
    var partHardwareTextArea = document.getElementById("partHardware");     
    
//    var toolsTabBtn = document.getElementById("toolsTabButton"); 
//    var setupsTabBtn = document.getElementById("setupsTabButton"); 

    // Determine if the machine ID is something 
    if (machineValue>0){
        // Enable the controls
        isPendingApprovalCtrl.disabled=false;
        isWaitingToBeReviewedCtrl.disabled=false;
        isPendingToolsCtrl.disabled=false;
        partHardwareTextArea.disabled=false;
        
//        toolsTabBtn.disabled=false;
//        setupsTabBtn.disabled=false;
        
        // Get the control that holds the status ID
        var statusCtrl = document.getElementById("status");

        // Create a variable to hold the displayed status value
        var statusDisplay = "";

        // Determine if it is a hidden control
        if (statusCtrl.type==="hidden"){
            // Get the value in the hidden control
            statusDisplay = document.getElementById("statusName").value;
        }
        else {
            // Get the value in the hidden control
            statusDisplay = statusCtrl.options[statusCtrl.selectedIndex].text;
        }
        
        // Determine if we are in machining phase
        // Get the value of the status and determine if it is machining
        if (statusDisplay==="Machining"){
            // Enable the control
            machineOrderCtrl.disabled=true;
            
            // Set the value of the control to be 1
            machineOrderCtrl.value = 1;
            hiddenOrderCtrl.value = 1;
        } 
        else {
            // Enable the control
            machineOrderCtrl.disabled=false;
        }
    }
    else {
        // Disable the controls
        machineOrderCtrl.disabled=true;
        isPendingApprovalCtrl.disabled=true;
        isWaitingToBeReviewedCtrl.disabled=true;
        isPendingToolsCtrl.disabled=true;
        partHardwareTextArea.disabled=true;
        
//        toolsTabBtn.disabled=true;
//        setupsTabBtn.disabled=true;
        
    }
}

function prefillOrderControl(statusValue){
    // Get the value of the machine and determine if it has one
    if (document.getElementById("machineID").value>0){
        // Get the order text box
        var orderTxtBx = document.getElementById("machineTaskOrder");
        var hiddenOrderCtrl = document.getElementById("hiddenMachineTaskOrder");

        // Get the value of the status and determine if it is machining
        if (statusValue.trim()==="Machining"){
            // The order should be the first one in this case
            orderTxtBx.value = 1;
            hiddenOrderCtrl.value = 1;

            // Disable the control
            orderTxtBx.disabled=true;
            
            // Set the position desired to the first position
            positionDesired=1;
        } 
        else {
            // Enable the control
            orderTxtBx.disabled=false;
            
            // Set the position desired to the first position
            positionDesired=document.getElementById("oldMachineTaskOrder").value;
            
        }
    }
}

function modifyTaskForThePresent(taskNumber=null, machineID=null, setupSheetOnly=1, sessionID=null, manualMachining=false)
{
    // set the return variable 
    var returnValue = false;

    // Determine if there is a task ID
    if (taskNumber==null){
        // Let the user know there is something wrong
        alert ("Cannot modify a null task.  Try again.");
    }
    // Determine if we are at the manual machining phase without a machine
    else if ((machineID==null || machineID==-1)&&manualMachining){
        // Just try to make a packet for them
        returnValue = true;
    }
    // Determine if there is a machine ID
    else if ((machineID==null || machineID==-1)&&!manualMachining){
        // Let the user know there is something wrong
        alert ("Cannot modify a task to create the packet on a task that is not on a machine.  Try again.");
    }
    else {
        // Setup the parameters to pass to PHP
        var params = {
            "setupSheetOnly" : setupSheetOnly,
            "machineID"      : machineID,
            "taskID"         : taskNumber, 
            "sessionID"      : sessionID
        };

        // Create the string containing the PHP file to use
        var url = "php_only_scripts/jquery_only/modify_task_for_present.php";

        // Setup AJAX for communication
        $.ajax({
            context : this,
            type    : "GET", 
            url     : url, 
            data    : params, 
            dataType: "text", 
            encode  : true,
            async   : false, 
            cache   : false
        })
        .done(function(data){
            // Determine if it was NOT success
            if (data.trim() !== ""){
                // Check to see if there is a reason NOT to allow the move
                if (data.includes("ABORT")){
                    // Split the string on the double colon
                    var errorStrings=data.trim().split("::");

                    // Give an alert popup of the problem
                    alert(errorStrings[1]);
                }

                // Log any errors to the console
                console.log(data.trim());

                // Return a failed result
                returnValue = false;
            }
            else {
                // If there is NO message coming back, then we are good
                returnValue = true;
            }
        })
        .fail(function(data){   
            // Log any errors to the console
            console.log(data);

            // Return a failed result
            returnValue = false;
        }); 
    }

    // return what we got
    return returnValue;
}    

function checkForSessionChange(sessionID=null, showMessage=false)
{
    // set the return variable 
    var returnValue = false;

    // Setup the parameters to pass to PHP
    var params = {
        "sessionID"      : sessionID
    };

    // Create the string containing the PHP file to use
    var url = "php_only_scripts/jquery_only/check_for_session_change.php";

    // Setup AJAX for communication
    $.ajax({
        context : this,
        type    : "GET", 
        url     : url, 
        data    : params, 
        dataType: "text", 
        encode  : true,
        async   : false, 
        cache   : false
    })
    .done(function(data){
        // Determine if it was NOT success
        if (data.trim() !== ""){
            // Check to see if there is a reason NOT to allow the move
            if (data.includes("ABORT") && showMessage){
                // Split the string on the double colon
                var errorStrings=data.trim().split("::");

                // Give an alert popup of the problem
                alert(errorStrings[1]);
            }

            // Log any errors to the console
            console.log(data.trim());

            // Return a failed result
            returnValue = false;
        }
        else {
            // If there is NO message coming back, then we are good
            returnValue = true;
        }
    })
    .fail(function(data){   
        // Log any errors to the console
        console.log(data);

        // Return a failed result
        returnValue = false;
    }); 

    // return what we got
    return returnValue;
}    

function getStatesAsSelectOptions(selectedState, selectName='state', abbreviated=false){
    // Create the states array
    var states = new Array ('AK','AL','AR','AZ','CA','CO','CT','DC','DE','FL',
                            'GA','HI','IA','ID','IL','IN','KS','KY','LA','MA',
                            'MD','ME','MI','MN','MO','MS','MT','NC','ND','NE',
                            'NH','NJ','NM','NV','NY','OH','OK','OR','PA','RI',
                            'SC','SD','TN','TX','UT','VA','VT','WA','WI','WV',
                            'WY');
                            
    var stateNames = new Array ('Alaska', 'Alabama', 'Arkansas', 'Arizona', 
                                'California', 'Colorado', 'Connecticut',  
                                'District Of Columbia', 'Delaware', 'Florida', 
                                'Georgia', 'Hawaii', 'Iowa', 'Idaho', 'Illinois', 
                                'Indiana', 'Kansas', 'Kentucky', 'Louisiana',  
                                'Massachusetts', 'Maryland', 'Maine', 'Michigan', 
                                'Minnesota', 'Missouri', 'Mississippi', 'Montana',
                                'North Carolina', 'North Dakota', 'Nebraska', 
                                'New Hampshire', 'New Jersey', 'New Mexico', 'Nevada', 
                                'New York', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 
                                'Rhode Island', 'South Carolina', 'South Dakota', 
                                'Tennessee', 'Texas', 'Utah', 'Virginia', 'Vermont', 
                                'Washington', 'Wisconsin', 'West Virginia', 'Wyoming');
                            
    // Start the return with the beginning of the select
    var result='<select id="' + selectName + '" name="' + selectName + '">';

    // Loop through the state array
    for (var currentStateNumber in states) {
        // Determine if this is one that is to be selected
        var selectedText='';
        if (selectedState===states[currentStateNumber]) {
            // Create the selected html
            selectedText='selected';
        }

        // Determine if they want the abbreviated form
        if (abbreviated){
            // Add this option to the select
            result = result + '<option value="' + states[currentStateNumber] + '" ' + 
                     selectedText + '>' + states[currentStateNumber] + '</option>';
        }
        else{
            // Add this option to the select
            result = result + '<option value="' + states[currentStateNumber] + '" ' + 
                     selectedText + '>' + states[currentStateNumber] + '  (' + 
                     stateNames[currentStateNumber] + ')</option>';
        }
    }

    // End the select
    result=result + '</select>';
    
    // Return the result
    return result;
}

function detectPopupBlocker(giveErrorMessage) {
    try {
        // Check it by attempting it
        var myTest = window.open(null,"","directories=no,height=1,width=1,menubar=no,resizable=no,scrollbars=no,status=no,titlebar=no,top=0,location=no");
        
        // If closing throws an exception, then they are blocked so try to close it.
        myTest.close();
        
        // Return doesn't have popup blocker
        return false;
        
    }
    catch (error){
        // Determine if they want an error popup
        if (giveErrorMessage){
            // Give them an alert
            alert("A popup blocker was detected. Cannot continue with the full functionality without allowing popups.");
        }
        
        // Return that they DO have blockers on
        return true;
    }
}

function getSelectSelectedOptionAttribute(selectName, attribute) {
    try {
        // Attempt to get the element
        var element = document.getElementById(selectName);
        
        // Determine if it exists
        if (typeof(element) !== 'undefined' && element !== null)
        {
            // Determine what they want
            switch(attribute) {
              case "label":
                  // Return the label
                  return element.options[element.selectedIndex].label;
                  
                  // break out
                  break;
              case "name":
                  // Return the label
                  return element.options[element.selectedIndex].attributes["name"].value;
                  
                  // break out
                  break;
              case "title":
                  // Return the title
                  return element.options[element.selectedIndex].title;
                  
                  // break out
                  break;
              default:
                  // Return nothing
                  return "";
            }
        }

        
        // Return Nothing
        return "";
        
    }
    catch (error){
        // Determine if they want an error popup
        if (giveErrorMessage){
            // Give them an alert
            alert("A popup blocker was detected. Cannot continue with the full functionality without allowing popups.");
        }
        
        // Return that they DO have blockers on
        return true;
    }
}

function popupWindow(url, windowName, win, w, h) {
    // Calculate the middle of the window passed in
    const y = win.top.outerHeight / 2 + win.top.screenY - ( h / 2);
    const x = win.top.outerWidth / 2 + win.top.screenX - ( w / 2);
    
    // Open the window
    win.open(url, windowName, `toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=${w}, height=${h}, top=${y}, left=${x}`);

    pollTimer = window.setInterval(function() {
        if (win.closed !== false) { // !== is required for compatibility with Opera
            window.clearInterval(pollTimer);
            refreshMachineTasks();
            return false;
        }
    }, 100);
}

function getMultipleSelectCSV(select) {
    var result = '';
    var options = select.selectedOptions;

    // loop through the values
    for (var i=0, iLen=options.length; i<iLen; i++) {
        result = result + options[i].value + ',';
    }
    
    // Determine if there is a string
    if (result!==''){
        // Set the result to remove the last comma
        result=result.substring(0, result.length - 1);
    }
    
    return result;
}

function changeUserClockStatus(laborClockID=null, laborCategoryID=null, sessionID=null)
{
    // set the return variable 
    var returnValue = false;

    // Determine if there is a labor clock ID
    if (laborClockID===null){
        // Let the user know there is something wrong
        alert ("Cannot modify a null labor clock row.  Try again.");
    }
    // Determine if there is a labor category ID
    else if (laborClockID===null){
        // Let the user know there is something wrong
        alert ("Cannot modify a user to a different labor category without the category information.  Try again.");
    }
    else {
        // Setup the parameters to pass to PHP
        var params = {
            "laborClockID"    : laborClockID,
            "laborCategoryID" : laborCategoryID, 
            "sessionID"       : sessionID
        };

        // Create the string containing the PHP file to use
        var url = "php_only_scripts/jquery_only/change_user_clock_status.php";

        // Setup AJAX for communication
        $.ajax({
            context : this,
            type    : "GET", 
            url     : url, 
            data    : params, 
            dataType: "text", 
            encode  : true,
            async   : false, 
            cache   : false
        })
        .done(function(data){
            // Determine if it was NOT success
            if (data.trim() !== ""){
                // Check to see if there is a reason NOT to allow the move
                if (data.includes("ABORT")){
                    // Split the string on the double colon
                    var errorStrings=data.trim().split("::");

                    // Give an alert popup of the problem
                    alert(errorStrings[1]);
                }

                // Log any errors to the console
                console.log(data.trim());
            }
            else {
                // If there is NO message coming back, then we are good
                returnValue = true;
            }
        })
        .fail(function(data){   
            // Log any errors to the console
            console.log(data);

            // Return a failed result
            returnValue = false;
        }); 
    }

    // return what we got
    return returnValue;
}    

// Add a delay function
function sleep(milliseconds) {
    const date = Date.now();
    let currentDate = null;
    do {
        currentDate = Date.now();
    } 
    while (currentDate - date < milliseconds);
}

// disabe or enable controls
function disableControlAndChildrenByID(controlID, disable=true){
    // Get the controls in question
    var fields = document.getElementById(controlID).getElementsByTagName('*');
    
    // Loop through the controls
    for(var i = 0; i < fields.length; i++)
    {
        // Disable or enable the controls
        fields[i].disabled = disable;
    }
    
    return;
}

function checkPendingStockBoxesDependingOnOthers(controlChanged, jobBlanksID, newBlank=false){
    // Attempt to get all of the checkboxes in question
    var blankReadyElement=null;
    var isPendingStockElement=null;

    // Determine if we are checking a new note or old
    if (newBlank){
        // Attempt to get all of the checkboxes in question
        blankReadyElement=document.getElementById('newBlankReady' + jobBlanksID);
        isPendingStockElement=document.getElementById('newIsPendingStock' + jobBlanksID);
    }
    else {
        // Attempt to get all of the checkboxes in question
        blankReadyElement=document.getElementById('blankReady' + jobBlanksID);
        isPendingStockElement=document.getElementById('isPendingStock' + jobBlanksID);
    }
    
    // Determine if there IS an pending stock control
    if (isPendingStockElement!==null){
        // Now determine which changed
        if (controlChanged.id.toLowerCase().indexOf("blankready") !== -1 &&
            isPendingStockElement.checked===true && 
            controlChanged.checked===true){
            // Check the control to be opposites
            isPendingStockElement.checked=false;
        }
        else if (controlChanged.id.toLowerCase().indexOf("ispendingstock") !== -1 &&
                 blankReadyElement.checked===true && 
                 controlChanged.checked===true){
            // Check the control to be opposites
            blankReadyElement.checked=false;
        }
    }
}

function wantsFirstPositionOnMachiningMachine(originalMachineID, viewedMachineControl, positionDesired, oldMachineTaskOrder){
    // set the return to be an no for now
    var returnValue=false;

    // Determine if they are changing machines, the viewed name is not null, 
    // is a machine that has a machining task and they want position one.
    if (viewedMachineControl!==null && 
        viewedMachineControl.options[viewedMachineControl.selectedIndex].text.includes("*") && 
        ((originalMachineID !== parseInt(viewedMachineControl.value)) || 
         (originalMachineID === parseInt(viewedMachineControl.value) && parseInt(oldMachineTaskOrder)!==1)) &&
        positionDesired!==null && parseInt(positionDesired)===1){
        // Set the return value to a true
        var returnValue=true;
    }

    // Return the value
    return returnValue;
}

function doesFileNameHaveBadChars (fileName){
    // set the return to be an no for now
    var returnValue=false;

    // Determine if the comma is in the filename
    if (fileName!=null && fileName.includes(",")){
        // set the return value to true
        returnValue=true;
    }

    // Return the value
    return returnValue;    
}

