/*******************************************************************************************
 * Parsing the gases depends on the machine
 * 
 * RIE FLuor 1  = RIEFluor1
 * RIE FLuor 2  = RIEFLuor2
 * RIE SiCl4    = RIESiCl4
 * ND200        = ND200
 * 
 * *****************
 */
function changeGasName(gasName, machineName)
{
    switch (machineName)
    {
        case "RIEFluor1":
            switch (gasName)
            {
                case "Gaz02":
                    return "O2";
                case "Gaz03":
                    return "SF6";
                case "Gaz04":
                    return "CHF3";
            }
            break;
        case "RIEFluor2":
            switch (gasName)
            {
                case "Gaz01":
                    return "O2";
                case "Gaz02":
                    return "SF6";
                case "Gaz03":
                    return "CHF3";
                case "Gaz04":
                    return "O2";
                case "Gaz05":
                    return "SF6";    
            }
            break;
        default:
            throw new Error("Wrong machine name in your JavaScript Parser !");
            
    }

    return "Bad Gas";

}





//
// Exctact a String from the bufferDile starting @index and with the length stringLength
//
function bufferString (buffer, index)
{
    var stringBuffer = "";
    var stringLength = buffer[index];
    var i = 0;

    for (i=0; i < stringLength; i++)
    {
        stringBuffer = stringBuffer + String.fromCharCode(buffer[++index]);
    }

    console.log("String = " + stringBuffer + "; Length = " + stringLength);
    return [stringBuffer, index];

}

/**********************************************************************
 * Convert the strange/weird format of floating numbers used by Nextral to decimal
 * inside toString(2) is used to convert decimal to binary
 */

function readWeirdNumber (buffer, index)
{
    var i = 0;
    var raw = "";
    var bin = "";
    var float = 0.0;
    var sign = 0;  // get the sign
    var exponent = 0;  // get the exposant
    var mantis = 0;  // get the mantis

    var initial = index;

    for (i=0; i<6; i++)
    {
        raw = buffer[index++].toString(2);
        bin = bin + raw.padStart(8, '0'); // complete with 0 before the binary number.
    }

    //reverse order of the bits in each Bytes of bin to read the mantis (??)
    for (i=0; i<40; i++)
    {
        mantis  += bin[8+i]*(2.0**(2*8*Math.floor(i/8)+7-i));
        //console.log (i + "  mantis = " + mantis);
    }
    mantis = 1.0 + mantis/(2.0**39);

    sign = bin.substr(48, 1) ? -1 : 1;    

    exponent = buffer[initial] - 129;  //parseInt(bin.substr(40, 48), 2)

    //console.log ("sign = " + sign + "  mantis = " + mantis + " exponent = " + exponent);

    if(mantis === 1.0 && exponent === -129)
    {
        float = 0.0;        
    } 
    else 
    {
        float = sign*mantis*2.0**exponent;
    }

    console.log(float);

    return [float, index];

}


/****************************************************************
 * This function read the items of the header of the file as below
 * bin_header = [
    [3,"unknown",False], #constant apparently
    [1,"length","byte"], #specified although file_name always has 8 reserved bytes
    [-1,"file_name","string"],
    [8,"unknown",False],
    [1,"length","byte"],
    [-1,"date","string"],
    [23,"unknown",False],
    [4,"unknown",False],
    [1,"length","byte"],
    [-1,"operator_name","string"],
    [1,"length","byte"],
    [-1,"title","string"],
    [2,"unknown",False],
    [1,"nb_steps","byte"],
    [4,"unknown",False],
    [1,"unknown",False],
                ]   
   Most of the data are useless but because of the unknown length of strings
   we need to parse them.
 */
function header (bufferFile, parameterArray)
{
    var stringCarCode = "";
    var counter = 0; //Counter is set to 0 because we read the header of the file (begining)
    var length = 0; // variable used for loop max value; length of a string to read;

    counter = 3; // the first 3 Bytes are useless
    [stringCarCode, counter] = bufferString(bufferFile, counter);
    parameterArray["recipename"]=stringCarCode;

    counter = 20;
    [stringCarCode, counter] = bufferString(bufferFile, counter);
    parameterArray["recipeDate"]=stringCarCode;

    counter = 58;
    [stringCarCode, counter] = bufferString(bufferFile, counter);
    parameterArray["recipeCreatorName"]=stringCarCode;  
    
    [stringCarCode, counter] = bufferString(bufferFile, ++counter);
    parameterArray["title"]=stringCarCode;

    counter= counter + 3;
    parameterArray["stepsNb"] = bufferFile[counter++];

    counter = counter + 30;
    
    return [parameterArray, counter];

}

/**************************************************************************************
 * Read one step in the recipe file starting @index in the bufferFile
 * and output the step values as an array in parameterArray
 * 
 * The index will point to the end of the step, 
 * ready to rread the next step or the end of the buffer
 */
function stepRead (bufferFile, index, machineName)
{
    var counter = index;
    var parameterArray = [];

    [stringCarCode, counter] = bufferString(bufferFile, counter);
    parameterArray["stepTitle"] = stringCarCode;

    counter = counter + 12;

    [stringCarCode, counter] = bufferString(bufferFile, counter);
    stringCarCode = changeGasName (stringCarCode, machineName); // to get the gasname used in the process sheet.
    parameterArray["gas1"] = stringCarCode;

    [parameterArray["flowGas1"], counter] = readWeirdNumber(bufferFile, ++counter);
    counter = counter + 3; //ignore 3 unknown Bytes

    [stringCarCode, counter] = bufferString(bufferFile, counter);
    stringCarCode = changeGasName (stringCarCode, machineName); 
    parameterArray["gas2"] = stringCarCode;

    [parameterArray["flowGas2"], counter] = readWeirdNumber(bufferFile, ++counter);

    return [parameterArray, counter];

}

/**********************************************************************************************
 * Read All the steps and then ask to choose the right step
 * then give back the parameters of the chosen step
 * 
 * ****************************************************************
 */

function readChooseSteps (outputArray, bufferFile, index, machineName)
{
    var i = 0;
    var parameterArray = [];
    for (i=0 ; i < outputArray["stepsNb"] ; i++)
    {
        [parameterArray[i], index] = stepRead(bufferFile, index, machineName);
    }

    var stepnumber = prompt (" Which Step do you want to read ? " );

    outputArray["stepTitle"] = parameterArray[stepnumber]["stepTitle"];
    outputArray["gas1"] = parameterArray[stepnumber]["gas1"];
    outputArray["flowGas1"] = parameterArray[stepnumber]["flowGas1"];

    return [outputArray, index];
}

//
// Main Function to parse 
// We are using a viewer for the buffer Uint8Array
// So tu scan the file we just read the value
//

function parse_nextral(file, recipeName, machineName)
{
    var outArray = {}; 
    var FileArray = new Uint8Array (file);
    var i = 0;
    var increment = 0;

    [outArray, increment] = header(FileArray, outArray);

    [outArray, increment] =readChooseSteps (outArray, FileArray, increment, machineName);

    console.log("Number of steps = " + outArray["stepsNb"]);
    console.log("stepTitle = " + outArray["stepTitle"]);
    console.log("Length of the file = " + file.byteLength);
    console.log("Recipe Name = " + outArray["recipename"] + " or " + recipeName);
    console.log(outArray["gas1"] + "flow1 = " + outArray["flowGas1"]);
    console.log(outArray["recipeCreatorName"]);

    return outArray;
}

if (operationType!="process")
	{
		throw new Error("operationType must be process");
	}

return parse_nextral(fileContent, fileName, "RIEFluor1"); //refer to the function changeGasName to get the right machineName