/*globals console, angular, bson, app, document*/

// Main module
angular.module('IOLabApp', ['ui.bootstrap', 'ngSanitize']);

angular.module('IOLabApp').run(function ($window, IOLab) {
    'use strict';

    // Expose the IOLabServiceObjectForCppObjectApp object  to the global scope!
    // This function is called from the CEF Application depending on signals
    // sent by the API
    $window.IOLabServiceObjectForCppObjectApp = {
        executeMethod: function (args) {
            var execArgs = args || {};
            IOLab.execute(execArgs.method, execArgs.args);
        }
    };

    IOLab.getAcquisitionStack();
    IOLab.getHardwareState();
});

// The "app" listener is accessible within the CEF application.
// It is used to communicate with the CEF client.
angular.module('IOLabApp').factory('IOLabAPI', function () {
    'use strict';

    var exports = {}, i;

    /*
    * Helper method to build the buffer array...
    */
    var buildBuffer = function (args) {
        var len = args.length;
        var $buffer = new Array(len);
        for (i = 0; i < len; i++) {
            $buffer[i] = args.charCodeAt(i);
            if ($buffer[i] < 0) {
                $buffer[i] += 65280;
            }
        }
        return $buffer;
    };

    console.log('Chromium Embedded Framework');

    exports.remotePowerOff = function (remote) {
        app.sendMessage('iolab_remotePowerOff', [remote]);
    };

    exports.sendCommand = function (cmd) {
        app.sendMessage('iolab_sendCommand', [cmd]);
    };

    exports.pairRemote = function (remote, status) {
        app.sendMessage('iolab_pairRemote', [remote, status]);
    };

    exports.setFixedConfig = function (remote, config, force) {
        app.sendMessage('iolab_setFixedConfig', [remote, config, force]);
    };

    exports.resetSensorOffset = function (remote, type) {
        app.sendMessage('iolab_resetSensorOffset', [remote, type]);
    };

    exports.exportData = function (remote, type, fileName) {
        app.sendMessage('iolab_exportData', [remote, type, fileName]);
    };

    exports.startDataAcquisition = function () {
        app.sendMessage('iolab_startData', []);
    };

    exports.stopDataAcquisition = function () {
        app.sendMessage('iolab_stopData', []);
    };

    // getHardwareState
    exports.getHardwareState = function (callback) {
        var message = 'iolab_getHardwareState' + (exports.getHardwareState.count++);
        app.setMessageCallback(message, function (msg, args) {
            app.removeMessageCallback(message);
            callback(buildBuffer(args));
            exports.getHardwareState.count %= 100;
        });
        app.sendMessage(message, []);
    };
    exports.getHardwareState.count = 0;

    // getAcquisitionStack
    exports.getAcquisitionStack = function (callback) {
        var message = 'iolab_getAcquisitionStack' + (exports.getAcquisitionStack.count++);
        app.setMessageCallback(message, function (msg, args) {
            app.removeMessageCallback(message);
            callback(buildBuffer(args));
            exports.getAcquisitionStack.count %= 100;
        });
        app.sendMessage(message, []);
    };
    exports.getAcquisitionStack.count = 0;

    // GetSensorData
    exports.getSensorData = function (callback, params) {
        var message = 'iolab_getSensorData' + (exports.getSensorData.count++);
        app.setMessageCallback(message, function (msg, args) {
            app.removeMessageCallback(message);
            callback(buildBuffer(args));
            exports.getSensorData.count %= 100;
        });
        app.sendMessage(message, params);
    };
    exports.getSensorData.count = 0;

    // GetSensorData2
    exports.getSensorData2 = function (callback, params) {
        var message = 'iolab_getSensorDataII' + (exports.getSensorData2.count++);
        app.setMessageCallback(message, function (msg, args) {
            app.removeMessageCallback(message);
            callback(buildBuffer(args));
            exports.getSensorData2.count %= 100;
        });
        app.sendMessage(message, params);
    };
    exports.getSensorData2.count = 0;

    exports.stackAcquisition = function () {
        app.sendMessage('iolab_stackAcquisition', []);
    };

    exports.deleteAcquisition = function () {
        app.sendMessage('iolab_deleteAcquisition', []);
    };

    /*
    * Bson management
    */
    exports.saveBson = function (collection, bsrec) {
        app.sendMessage('iolab_saveBson', [collection, bsrec]);
    };

    // executeQuery
    exports.executeQuery = function (callback, collection, qrec) {
        var message = 'iolab_executeQuery' + (exports.executeQuery.count++);
        app.setMessageCallback(message, function (msg, args) {
            app.removeMessageCallback(message);
            callback(buildBuffer(args));
            exports.executeQuery.count %= 100;
        });
        app.sendMessage(message, [collection, qrec]);
    };
    exports.executeQuery.count = 0;

    return exports;
});
