var express = require('express');
var app = express();
var server = require('http').Server(app);
var io = require('socket.io').listen(server);
var mqttClient = require('./mqtt/mqttClient');
//var workingEvents = require('./db/workingEvents');
var workingEvents = require('./db/workingEvents1');
var dataFormatter = require ('./dataFormatter.js');
var moment = require('moment');
var randomMac = require('random-mac');
var sensorEvents = [];

// format of sensor data
//-------------------------------
// doc = [ { id: 'rasp1',
//   time: '2014-09-18T14:33:52.000Z',
//   count: 79,
//   label: 'BC:F5:AC:F5:E1:99',
//   zone: 'zoneA',
//   topic: 'SENSOR/GENERATOR/IN'} ]

path = require('path');

var params = {	
	timeinterval : 1000,
	numrecords : 100,
	daymonth : "07",
	month : "Oct",
	countlimit : 5,
	year : "2014"
}

app.use(express.static(path.join('.')));
app.get('/', function (req, res) {
  res.sendFile('/index.html');
});

// subscribes to mqtt to get the last numrecords recors
// and save them a working database (this can ba also a list)
// function subscribeToSensor(){
//   var count = 0;

  //mqttClient.client.subscribe('SENSOR/#');

//   mqttClient.client.subscribe('SENSOR/#');
 

//   mqttClient.client.on('message', function (topic, message){
//   			console.log("New message", message, "on Topic", topic);
//           var obj = JSON.parse(message);

//           // console.log("Recieved events from sensor ", obj);
//           // function hashCode(s){
//           //   return s.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0);              
//           // }
//           // obj.label = hashCode(obj.label);
//           obj.topic = topic; 
//           workingEvents.saveEvent(obj, function(error){
//             console.log("Error saving to working database: ", error);
//           }); 
//           count++;

          
        
//   });        
// }

//subscribeToSensor();

var c = Math.floor(Math.random() * (60 - 50 + 1)) + 50;

var eventCount = 0;

function generateEvents(){	

		function randomDate(start, end) {
		    return new Date(start.getTime() + Math.random() * (end.getTime() - start.getTime()));
		}

		var obj = {};

		obj.id = 'rasp1';
		obj.zone = 'zoneA';
		obj.label = randomMac();	
		obj.time = moment().format("YYYY-MM-DDTHH:mm:ss").concat('.000Z');
					//randomDate(new Date(2014, 0, 1), new Date()).toISOString();
		Math.floor(Math.random() * (1 - 0 + 1)) + 0 == 0 ? obj.topic = 'SENSOR/GENERATOR/IN' : obj.topic = 'SENSOR/GENERATOR/OUT'

		if (obj.topic == 'SENSOR/GENERATOR/IN') {
			obj.count = c+1;
			c = obj.count;
			//console.log("count in ", obj.count);
		} else {
			obj.count = c-1;
			c = obj.count;
			//console.log("count out ", obj.count);
		}

		console.log("count ", obj.count);
		
		          //Math.floor(Math.sin(eventCount++ / 10.0) * 30 + 50);
		

		//console.log("time ", obj.time);

		workingEvents.saveEvent(obj, function(error){
	    	console.log("Error saving to working database: ", error);     
	    });	
}


var run1 = setInterval(generateEvents, 1000);


Object.prototype.in = function() {
    for(var i=0; i<arguments.length; i++)
       if(arguments[i] == this) return true;
    return false;
}

var events = {},realtimeInOut = [];

io.sockets.on('connection', function (socket) {

	var startDate1 = "", endDate1 = "", startDate2 = "", endDate2 = "";
	var start = "", end = "";

	// Events in month 
	//---------------------------------------------------
	socket.on('devicesMonth', function (monthSelected, yearSelected) {		

		var month = monthSelected;
		if (monthSelected < 10) {
			month = "0".concat(month.toString());
		}

		startDate1 = yearSelected.concat("-").concat(month).concat("-01T00:00:00.000Z");

		if (parseInt(month).in(01,03,05,07,08,10,12)){

			endDate1 = yearSelected.concat("-").concat(month).concat("-31T00:00:00.000Z");

		} else if (parseInt(month) == 02){

			endDate1 = yearSelected.concat("-").concat(month).concat("-28T00:00:00.000Z");

		} else {

			endDate1 = yearSelected.concat("-").concat(month).concat("-30T00:00:00.000Z"); 
		}

		var queryEventsSensorInMonth = {
			time: {$gte: startDate1.toString(), $lt: endDate1.toString()}
		}	
				
		workingEvents.getEvents (queryEventsSensorInMonth, undefined, function (docs){
			if (docs) {
				var devicesMonth = dataFormatter.formatDevicesMonth(docs);

				// sort the list because data comes in random order (when generator of events is used)
				devicesMonth.data.sort(function(a, b) { 
				    return a.x - b.x;
				});

				// for(var i in devicesMonth.data) {
				// 	console.log(devicesMonth.data[i]);
				// }
    				
				socket.emit('devicesMonth', [devicesMonth]);

			}
		});			
		
	});

	// Events with increased number of devices (people)
	//---------------------------------------------------
	socket.on('busyDays', function (monthSelected, yearSelected, countSelected) {
		var month = monthSelected;
		if (monthSelected < 10) {
			month = "0".concat(month.toString());
		}
		startDate2 = yearSelected.concat("-").concat(month).concat("-01T00:00:00.000Z");

		if (parseInt(month).in(01,03,05,07,08,10,12)){

			endDate2 = yearSelected.concat("-").concat(month).concat("-31T00:00:00.000Z");

		} else if (parseInt(month) == 02){

			endDate2 = yearSelected.concat("-").concat(month).concat("-28T00:00:00.000Z");

		} else {

			endDate2 = yearSelected.concat("-").concat(month).concat("-30T00:00:00.000Z"); 
		}

		var queryEventsSensorInBusyDays = {
			time: {$gte: startDate2.toString(), $lt: endDate2.toString()},
			count: {$gt: parseInt(countSelected)}
		}	

		workingEvents.getEvents (queryEventsSensorInBusyDays, undefined, function (docs){
			if (docs){
				
				// for(var i in docs) {
				// 	console.log("count ",docs[i].count);
				// }
				var busyDays = dataFormatter.formatBusyDays(docs, countSelected);

				// sort the list because data comes in random order (when generator of events is used)
				busyDays.data.sort(function(a, b) { 
				    return a.x - b.x;
				});

				for(var i in busyDays.data) {
					//console.log('busyDays ', busyDays.data[i]);
				}

				socket.emit('busyDays', [busyDays]);
			}
		});	
	});

	// Realtime events (exits, entrances and both)
	//---------------------------------------------------
	var showRealtimeData = function() {

		// Realtime entrances and exits
		var today = moment().format("YYYY-MM-DD").concat('T00:00:00.000Z').toString();
		var now = moment().format("YYYY-MM-DDTHH:mm:ss").concat('.000Z').toString();		

		// because sensor was off
		// var today  = '2014-10-07T00:00:00.000Z';
		// var now = '2014-10-08T00:00:00.000Z'
		
		var queryEventsSensorIn = {
		 	topic : "SENSOR/GENERATOR/IN",
		 	time: {$gte: today, $lt: now}
		
		}
		var queryEventsSensorOut = {
		 	topic : "SENSOR/GENERATOR/OUT",
		 	time: {$gte: today, $lt: now}
		}

		var queryEventsSensorInOut = {
		 	time: {$gte: today, $lt: now}		
		}

		
		workingEvents.getEvents (queryEventsSensorIn, 50, function (docs){
			if (docs){
				realtimeIn = docs;				
				events.ins = realtimeIn;
				//console.log("entrances ", events.ins );
			}
		});
		workingEvents.getEvents (queryEventsSensorOut, 50, function (docs){
			if (docs){
				realtimeOut = docs;
				events.outs = realtimeOut;
				//console.log("entrances ", events.outs );
			}
		});
		workingEvents.getEvents (queryEventsSensorInOut, 10, function (docs){
			if (docs){
				realtimeInOut = docs;
				//console.log("real ", realtimeInOut);
			}
		});
		var devices = dataFormatter.formatRealtimeEvents(events);
		var devicesIn = devices.devicesIn;
		var devicesOut = devices.devicesOut;
		var realtimeTraffic = dataFormatter.formatRealtime(realtimeInOut);

		//socket.emit('realtimeEvents', [devicesIn, devicesOut, realtimeTraffic]);

		socket.emit('realtimeEvents', [devicesIn, devicesOut, realtimeTraffic]);


		// Events for a chosen day (realtime events) 
		//--------------------------------------------------

		// If the chosen day is the current day, make countinuous
		// refresh of the graph with the new data

		if (start == moment().format("YYYY-MM-DD")) {

			var startDate = start.toString().concat('T00:00:00.000Z');
			var dayChosen = start.toString().slice(-2);
			var remain = start.toString().slice(0,8);
			var nextDay = parseInt(dayChosen)+1;
			if (dayChosen < 10) {				
				nextDay = "0".concat(nextDay.toString());
			} 			
			var endDate = remain.concat(nextDay).concat('T00:00:00.000Z');

			var queryEventsSensorDay = {
			time: {$gte: startDate.toString(), $lt: endDate.toString()}
			}

			workingEvents.getEvents (queryEventsSensorDay, 50, function (docs){
				if (docs) {
					var devicesDay = dataFormatter.formatDevicesDay(docs);
					socket.emit('devicesDay', [devicesDay]);
				}				
			});
		}

		// If the chosen day is different then current day, 
		// draw the graph only once with the historic data	

		socket.on('devicesDay', function (date) {
			start = date;
			// console.log("start ", start);
			// console.log("moment ", moment().format("YYYY-MM-DD"));
      		startDate = date.toString().concat('T00:00:00.000Z');
			var dayChosen = date.toString().slice(-2);
			var remain = date.toString().slice(0,8);
			var nextDay = parseInt(dayChosen)+1;
			if (dayChosen < 10) {				
				nextDay = "0".concat(nextDay.toString());
			} 			
			endDate = remain.concat(nextDay).concat('T00:00:00.000Z');

			var queryEventsSensorDay = {
			time: {$gte: startDate.toString(), $lt: endDate.toString()}
			}
			workingEvents.getEvents (queryEventsSensorDay, 100, function (docs){
				if (docs) {
					var devicesDay = dataFormatter.formatDevicesDay(docs);
					socket.emit('devicesDay', [devicesDay]);
				}				
			});			
		});	
	}	

	// The graph is shown within a specified timeinterval
	var run = setInterval(showRealtimeData, params.timeinterval);

   	socket.on('disconnect', function() {
     	clearInterval(run);    
	});

});

server.listen(3000, function() {
	console.log("Started a server on port 3000");
});
