/**
 * @category    Webserver
 * @package     ATPX
 * @author      Sam Meredith <sam@aandtinstruments.com>
 * @version     0.1
 */

let angleNormalisationValue = 0;

const normaliseAngleData = function(datum, normalisationValue)
{
    let normalised = datum - normalisationValue;

    if (normalised < -180) normalised += 360;
    else if (normalised > 180) normalised -= 360;

    return normalised;
}

const chartOptionsMAWA =
{
    type: 'scatter',
    data: 
    {
        datasets: 
        [{
            label: 'MAWA',
            data: [],
            showLine: true,
            borderColor: 'rgb(255, 65, 54)',
            parsing: false,
            normalised: true
        },
        {
            label: 'Motion Corrected MAWA',
            data: [],
            showLine: true,
            borderColor: 'rgb(0, 116, 217)',
            parsing: false,
            normalised: true
        }]
    },
    options:
    {
        animation: false,
        datasets:
        {
            scatter:
            {
                pointRadius: 0
            }
        },
        maintainAspectRatio: false,
        parsing: false,
        plugins:
        {
            decimation:
            {
                enabled: true,
                algorithm: 'min-max'
            },
            legend:
            {
                display: true,
                position: 'bottom',
                labels:
                {
                    boxHeight: 1,
                    boxWidth: 20,
                    padding: 20
                },
            },
            title:
            { 
                display: true,
                font:
                {
                    size: 18
                },
                position: 'top',
                text: 'Measured Wind Angle Data'
            },
            tooltip:
            {
                enabled: false
            }
        },
        scales:
        {
            x:
            {
                type: 'realtime',
                realtime:
                {
                    duration: 60000,
                    delay: 300,
                    pause: false,
                    // Duration of data to be kept
                    // Undefined causes data to be deleted as soon as it falls off the chart
                    ttl: undefined,
                    // Frequency at which the chart is drawn
                    // Decreasing this has the biggest impact on CPU utilisation
                    frameRate: 10
                },
                ticks:
                {
                    display: false
                }
            },
            y:
            {
                // Since the data is normalised, it is always drawn around 0 (with the labels doctored)
                suggestedMax: 5.0,
                suggestedMin: -5.0,
                ticks:
                {
                    callback: function(value, index, ticks)
                    {
                        return normaliseAngleData(value + angleNormalisationValue, 0).toFixed(1);
                    }
                },
                title:
                {
                    display: true,
                    font:
                    {
                        size: 18
                    },
                    text: 'Wind Angle °'
                }
            }
        },
        spanGaps: true
    }
};

const updateChartMAWA = function(chart, sender, instance)
{
    const fields = new Set(['0x1358', '0x0317']);

    const self = this;

    $.ajax(
    {
        type: 'POST',
        url: '/atp.fields.php',
        data: 
        {
            'action': 'getFields',
            'fields': Array.from(fields),
            'id': sender,
            'instance': instance
        },
        success: function(response) 
        {
            if (self.dataDebounce) return;

            // Parse value and append to dataset
            const json = JSON.parse(response);
        
            if (json.status)
            {
                let responseData = [];

                // Strip HTML tags
                const match = json.response.match(/.*<BODY>(.*)<\/BODY>.*/s);
                if (match)
                {
                    match[1].split("\r\n").forEach(datum =>
                    {
                        const split = datum.split('=');
                        responseData.push({ 'field' : parseInt(split[0]), 'data' : parseFloat(split[1]) });
                    });
                }

                // Normalise both datasets around the measuredWindAngle data
                let dataset = chart.data.datasets[0].data;

                // Calculate the average of the de-normalised dataset
                const sum = dataset.reduce((acc, obj) => acc +
                    obj.y + angleNormalisationValue, 0);
                let avg = (sum / dataset.length) || 0;

                // If the average has deviated significantly from the normalisation value, re-normalise
                if (Math.abs(normaliseAngleData((avg - angleNormalisationValue), 0)) > RENORMALISATION_THRESHOLD)
                {
                    // If angle continues changing in one direction, avg will just increase for ever
                    // If we wrap it around 360 it doesn't cause a re-draw
                    if (avg > 360) avg -= 360;

                    console.log('Re-normalised angle data around ' + avg);
                    dataset.forEach(function(datum)
                    {
                        // Add the old normalisation value, subtract the new one
                        // then shift into the correct range
                        datum.y = normaliseAngleData(datum.y + angleNormalisationValue,
                            avg);
                    });
                    chart.data.datasets[0].data = dataset;

                    dataset = chart.data.datasets[1].data;
                    dataset.forEach(function(datum)
                    {
                        datum.y = normaliseAngleData(datum.y + angleNormalisationValue,
                            avg);
                    });
                    chart.data.datasets[1].data = dataset;

                    angleNormalisationValue = avg;
                }
                
                const MAWAValue = (responseData.find(element => element.field == 0x1358) || { data: "NaN" }).data;

                chart.data.datasets[0].data.push(
                    {
                        x: Date.now(),
                        y: normaliseAngleData(parseFloat(MAWAValue), angleNormalisationValue)
                    }
                );

                const MotionCorrectedMAWAValue = (responseData.find(element => element.field == 0x0317) || { data: "NaN" }).data;

                chart.data.datasets[1].data.push(
                    {
                        x: Date.now(),
                        y: normaliseAngleData(parseFloat(MotionCorrectedMAWAValue), angleNormalisationValue)
                    }
                );

                // Update chart
                chart.update('quiet');
            }
        }
    });
}
