class FaroModel extends ObservableModel {
    constructor() {
        super();

        // Class constants
        this.cFaro = "Faro";

        // Class properties
        this.FaroChannels = new Array();
        this.FaroData = new Object();

        this.init();
    }

    init() {
        var async = new Array();
        var deferred = new $.Deferred();
        var self = this;

        async.push(readSection("Faro").done(function(section) {
            self.FaroData = $.extend(true, self.FaroData, JSON.parse(section));

            // Construct and sort channel array
            var channelArray = self.FaroData.channels.split(',');
            for (var i = 0; i < (channelArray.length - 2); i += 3) {
                self.FaroChannels.push(
                    { channelNum: channelArray[i], channelName: channelArray[i+1],
                      channelFormat: 1, displayName: "", fieldId: channelArray[i+2] }
                );
            }

            for (var property in self.FaroData) {
                if (property.toLowerCase().indexOf("config") >= 0) {
                    var items = self.FaroData[property].split(',');
                    if (items.length >= 3) {
                        var channelNumber = items[0];
                        var channelFormat = items[1];
                        var displayName = items[2];
 
                        var channel = self.FaroChannels.find(x => x.channelNum == channelNumber);
                        if (channel !== undefined) {
                            channel.channelFormat = channelFormat;
                            channel.displayName = displayName;
                        }
                    }
                }
            }
        }));

        var menuDeferred = new $.Deferred();
        async.push(menuDeferred.promise());
        $.getScript('/js/atp.channel-menu.js').done(function() {
            self.menu = new ChannelMenu();
            self.menu.init().done(function() {
                menuDeferred.resolve();
            });
        });

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

        return deferred.promise();
    }

    persistData() {
        var databaseArray = new Array();
        var index = 0;

        for (var index in this.FaroChannels) {
            var channel = this.FaroChannels[index];
            databaseArray.push(
                { section: 'Faro', key: 'Config:' + channel.channelName, 
                  value: channel.channelNum + ',' + channel.channelFormat + ',' + channel.displayName }
            );
        }
        
        return writeToDatabase(databaseArray, 'Faro');
    }
}

class FaroView extends BasicView {
    constructor(controller) {
        super(controller);
    }

    bindEvents() {
        super.bindEvents();

        $('#faro-container').on('change', 'select', this.controller.changeFormat.bind(this.controller));
        $('#faro-container').on('change', 'input', this.controller.changeDisplayName.bind(this.controller));
    }

    update(model) {
        console.log(model);
        var $container = $('#faro-container');
        $container.empty();

        if (model.FaroChannels.length <= 0) {
            // Insert 'no channels available' screen
            $container.removeClass('faro-grid');
            $container.append('<fieldset class="placeholder-box"><div>No Faro headings received.</div></fieldset>');
        } else {
            $container.append(
                  '<h2>Data Name</h2>'
                + '<h2>Format</h2>'
                + '<h2>Display Name</h2>'
                + '<h2>Raw Value</h2>'
            )
        }

        for (var i = 0; i < model.FaroChannels.length; i++) {
            var channelName = model.FaroChannels[i].channelName;
            var channelNum = model.FaroChannels[i].channelNum;
            var channelFormat = model.FaroChannels[i].hasOwnProperty('channelFormat') ? model.FaroChannels[i].channelFormat : 1;
            var displayName = model.FaroChannels[i].hasOwnProperty('displayName') ? model.FaroChannels[i].displayName : "";
            var fieldId = model.FaroChannels[i].fieldId;
            $container.append(
                  '<div>' + channelName + '</div>'
                + '<select data-channel=' + channelNum + '>'
                +   '<option value="3" ' + ((channelFormat==3)?"selected":"") + '>Angle (&plusmn; 180&deg;)</option>'
                +   '<option value="5" ' + ((channelFormat==5)?"selected":"") + '>Bearing (0-360&deg;)</option>'
                +   '<option value="0" ' + ((channelFormat==0)?"selected":"") + '>Decimal (0 D.P)</option>'
                +   '<option value="1" ' + ((channelFormat==1)?"selected":"") + '>Decimal (1 D.P)</option>'
                +   '<option value="2" ' + ((channelFormat==2)?"selected":"") + '>Decimal (2 D.P)</option>'
                +   '<option value="6" ' + ((channelFormat==6)?"selected":"") + '>Time    (HH:MM:SS)</option>'
                + '</select>'
                + '<input type="text" data-channel=' + channelNum + ' value="' + displayName + '"></input>'
                + '<div class="flex-field">'
                +   '<div class="field-container" id="' + channelNum + '" data-field="' + fieldId + '" data-sender="Faro" data-instance="0">&nbsp;</div>'
                + '</div>'
            );
        }
    }
}

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

    changeDisplayName(e) {
        var channelNum = $(e.target).attr("data-channel");
        this.model.FaroChannels.find(x => x.channelNum == channelNum).displayName = $(e.target).val();
    }

    changeFormat(e) {
        var channelNum = $(e.target).attr("data-channel");
        this.model.FaroChannels.find(x => x.channelNum == channelNum).channelFormat = $(e.target).find("option:selected").val();
    }
}
