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

const DEFAULT_MAST_HEIGHT = 45.0;
const RENORMALISATION_THRESHOLD = 2;

class MastMotionModel extends ObservableModel
{
    constructor(index)
    {
        super();

        this.index = (index || "0");
        this.section = "windsource" + this.index;

        this.data = 
        {
            mastheight : DEFAULT_MAST_HEIGHT,
            motionthreshold : 0.0,
            motionthresholdenabled : false
        };

        this.canbusDevices = [];
    }

    get canbusAddress()
    {
        if (this.canbusDevices !== undefined && this.canbusDevices.length >= 1)
        {
            let device = this.canbusDevices.find(({ uniqueid }) => BigInt.asUintN(64, uniqueid) === this.canbusDevice);

            if (device !== undefined) return device.address;
        }

        return 0;
    }

    get canbusDevice()
    {
        return BigInt.asUintN(64, this.data.uniqueid);
    }

    get senderPair()
    {
        switch (this.data.source)
        {
            case "nmea0183":
            {
                return 0x0C00 | parseInt(this.data.instance);
            }

            case "canbus":
            {
                return 0x0D00 | parseInt(this.canbusAddress);
            }

            default:
            {
                if (this.data.source.includes("wind"))
                {
                    // This is a wind board
                    return 0x0500 | parseInt(this.data.source.split(':')[1]);
                }
                else return 0;
            }
        }
    }

    init()
    {
        const self = this;

        $.when(readSingle("Wind", "MotionThreshold"), readSingle("Wind", "MotionThresholdEnabled"),
         readSection(this.section)).done(function(thresholdResponse, thresholdEnabledResponse, sectionResponse)
        {
            let async = [];

            console.log(thresholdResponse);
            console.log(thresholdEnabledResponse);

            if (sectionResponse && sectionResponse[0])
            {
                self.data = $.extend({}, self.data, JSON.parse(sectionResponse[0]));

                if (self.data.source == "canbus")
                {
                    const id = self.canbusDevice;
                    async.push(readSection("CanDevices:" + id).done(function(response)
                    {
                        if (response.status)
                        {
                            self.canbusDevices.push(
                                { 
                                    "uniqueid" : id,
                                    "model" : (response.result.model || ""),
                                    "address" : (response.result.address || 0)
                                }
                            )
                        }
                    }));
                }
            }

            if (thresholdResponse && thresholdResponse[0])
                self.data.motionthreshold = thresholdResponse[0] || "0.0";

            if (thresholdEnabledResponse && thresholdEnabledResponse[0])
                self.data.motionthresholdenabled = thresholdEnabledResponse[0] || false;

            $.when.apply($, async).then(function()
            {
                self.notifyAll();
            });
        });
    }

    persistData()
    {
        let databaseArray = [];

        databaseArray.push(
            {
                'section': this.section,
                'key': "mastheight",
                'value': this.data.mastheight
            });
        databaseArray.push(
            {
                'section': "Wind",
                'key': "MotionThreshold",
                'value': this.data.motionthreshold
            });
        databaseArray.push(
            {
                'section': "Wind",
                'key': "MotionThresholdEnabled",
                'value': this.data.motionthresholdenabled
            });

        writeToDatabase(databaseArray, "mastmotion");
    }
}

class MastMotionController extends BasicController
{
    constructor(model)
    {
        super(model);
    }

    changeMastHeight(e)
    {
        validateRange($(e.target), 1, 20, 100);

        this.model.data.mastheight = $(e.target).val();
    }

    changeThreshold(e)
    {
        validateRange($(e.target), 1, 0, 10);

        this.model.data.motionthreshold = $(e.target).val();
    }

    toggleThreshold(e)
    {
        this.model.data.motionthresholdenabled = $(e.target).is(':checked');
    }
}

class MastMotionView extends BasicView
{
    constructor(controller)
    {
        super(controller);

        this.controller.model.init();
    }

    bindEvents()
    {
        super.bindEvents();

        $('#mast-height').on('change', this.controller.changeMastHeight.bind(this.controller));
        $('#threshold').on('change', this.controller.changeThreshold.bind(this.controller));
        $('#threshold-enable').on('click', this.controller.toggleThreshold.bind(this.controller));

        $('.modal-ok').on('click', () => $('.modal').hide());
        $('#modal-open').on('click', () => $('.modal').show());
        $('.modal-close').on('click', () => $('.modal').hide());
    }

    update(model)
    {
        console.log(model);

        $('#mast-height').val(model.data.mastheight);
        $('#threshold').val(model.data.motionthreshold);
        $('#threshold-enable').prop('checked', model.data.motionthresholdenabled);
        $('#wind-source').text("Wind Input " + (parseInt(model.index) + 1) + (model.data.name == "" ? "" : " - " + model.data.name));

        let input = model.data.source || "";
        let instance = 0;
        switch (input)
        {
            case "canbus":
                instance = model.canbusAddress;
                break;

            case "nmea0183":
                instance = model.data.instance;
                break;

            case "":
            default:
                if (input.includes("wind"))
                {
                    instance = input.split(':')[1];
                }
                break;
        }

        $('.modal .field-container').not('#heel-gyro, #pitch-gyro').attr('data-sender', input);
        $('.modal .field').not('#heel-gyro, #pitch-gyro').attr('data-instance', instance);

        const ctxHeel = $('#heel-canvas')[0].getContext('2d');
        this.heel = new Chart(ctxHeel, $.extend(true, {}, chartOptionsGyro));
        setInterval(updateChartGyro.bind(this), 100, this.heel, 'ATProcessor', 0x0);

        const ctxAWA = $('#awa-canvas')[0].getContext('2d');
        this.awa = new Chart(ctxAWA, $.extend(true, {}, chartOptionsMAWA));
        setInterval(updateChartMAWA, 100, this.awa, input, instance);

        const ctxAWS = $('#aws-canvas')[0].getContext('2d');
        this.aws = new Chart(ctxAWS, $.extend(true, {}, chartOptionsMAWS));
        setInterval(updateChartMAWS, 100, this.aws, input, instance);
    }
}
