'use strict';

var _ = require('lodash');
var path = require('path'); // init path so we can create paths using path.join()
var os = require('os');
// init app using express to make app a function handler which we can parse on to the HTTP server
var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var SerialPort = require('serialport').SerialPort;
var schema = require("./schema");

require("serialport").list(function (err, ports) {
    ports.forEach(function(port) {
        console.log(port);
    });
});

// Open a connection to a serial port
var ports = {
    "linux": "/dev/ttyUSB0",
    "darwin": "/dev/tty.usbserial-A900FLLE",
    "win32": "COM3",
};
var serialport = new SerialPort(ports[os.platform()], {
    baudrate: 115200,
    parser: require('./parser')(),
});
var clientsConnected = 0; // Keep statistics of the amount of connected clients

app.use(express.static(path.join(__dirname, 'public')));


// We hook up on the socket.io connection event.
io.on('connection', function(socket){
    clientsConnected++; // increment amount of clients
    console.log('a client connected');
    console.log("Total: " + clientsConnected);
    // Hook up for disconnect event
    socket.on('disconnect', function(){
        clientsConnected--; // decrement amount of clients
        console.log("a client disconnected");
        console.log("Total: " + clientsConnected);
    });

    socket.on('download', function() {
        var buf = new Buffer(3); // 3: uint8 - uint16 -
        buf.writeUInt8(0x01, 0);        //Write 1 offset by 0
        buf.writeUInt16LE(0x0001, 1);   //Write 0 and 3 offset by 1
        serialport.write(buf);
    });
});

var pktList = [];
var lastSend = Date.now()
var sendPackage = function(key, pkt) {
	pktList.push(pkt);
	var now = Date.now();
	if (now - lastSend > 100) {
		io.emit(key, pktList);
		pktList = [];
		lastSend = now;
	}
}

// We make the http server listen to port 3000
var PORT = 3000;
http.listen(PORT, function(){
    console.log('listening on port', PORT);
});

// the serial port is opened asynchronously, meaning we are not able to read data
// before the 'open' event has happened.
serialport.on('open', function(error) {
    if (error) console.log(error);
    console.log('Serial port is now open');

    // Event for received data
    serialport.on('data', function(data){
        schema.unpack(data, function(err, pkt) {
            if (err) throw err;
            console.log(pkt, ",");
            if (pkt.name === "request log") {
                pkt.value = require("./log2csv").toCsv(pkt.value);
            }
            sendPackage('data', pkt);
        });
    });


});
serialport.on('error', function(error){
    //throw new Error(error);
    console.log(error);
});

var debug = true;
//Debug functions
if(debug) {
    setInterval(function() {
        sendPackage('data', {
            name: 'RoadSpeed (km/h)',
            value: (Math.random() - 0.5) * 20
        });
    }, 10);

    setInterval(function() {
        sendPackage('data', {
            name: 'GX',
            value: Math.floor(Math.random() * 3)+2.5
        });
    }, 10);

    setInterval(function() {
        sendPackage('data', {
            name: 'GY',
            value: Math.floor(Math.random() * 3)
        });
    }, 10);

    setInterval(function() {
        sendPackage('data', {
            name: 'GZ',
            value: Math.floor(Math.random() * 3)-2.5
        });
    }, 10);

	// for (var i = 0; i < 50; i++) {
	// 	(function(i){
	// 		setInterval(function() {
	// 			sendPackage('data', {
	// 				name: 'data-' + i,
	// 				value: Math.floor(Math.random() * i)-2.5
	// 			});
	// 		}, 10);
	// 	})(i)
	// }
}

@@ -1771,16 +1771,37 @@
 te.now()
+;%0Avar timeout = null;
 %0Avar sen
@@ -1837,136 +1837,308 @@
  %7B%0A%09
-pktList.push(pkt);%0A%09var now = Date.now();%0A%09if (now - lastSend %3E 100) %7B%0A%09%09io.emit(key, pktList);%0A%09%09pktList = %5B%5D;%0A%09%09lastSend = now
+if (timeout !== null) clearTimeout(timeout);%0A%09pktList.push(pkt);%0A%09var timeoutTime = 100;%0A%09var now = Date.now();%0A%09var flush = function() %7B%0A%09%09io.emit(key, pktList);%0A%09%09pktList = %5B%5D;%0A%09%09lastSend = now;%0A%09%7D%0A%09if (now - lastSend %3E timeoutTime) %7B%0A%09%09flush();%0A%09%7D else %7B%0A%09%09timeout = setTimeout(flush, timeoutTime)
 ;%0A%09%7D

Make sure the pktList is flushed atleast ever 100ms