
var port=5050;
var express = require('express');
var http  = require( 'http' );
var app  = express();
var engine  = require( 'ejs-locals' );
var fs  =   require('fs');
var passwordHash = require('password-hash');


var server = http.createServer(app);
var io = require('socket.io').listen(server);

//////MONGOOOSE////
var mongoose = require( 'mongoose' );

//on creer le schema
var userSchema = new mongoose.Schema
({
	username : String,
	password : String,
	language : String,
	gameData :
	{
		user_id : String,
		timePlayed:{ type : Number, min : 0,  default : 0 } ,
		nbrGames:{ type : Number, min : 0,  default : 0 } ,
		nbrPoints:{ type : Number, min : 0,  default : 0 } ,
		nbrGuessWords:{ type : Number, min : 0,  default : 0 },
		nrbNoGuessWords:{ type : Number, min : 0,  default : 0 } ,
		nbrDraws: { type : Number, min : 0,  default : 0 } ,
		nrbNoDraws:{type : Number, min : 0,  default : 0 }
	}
});

//on instancie le model depuis le schema
var userModel=mongoose.model( 'User', userSchema );

////FIN MONGOSE


app.set("nav.ejs", "/views");

//////ROUTES///////
app.get('/', function(req, res) {
    res.render('index.ejs');
});

app.get('/index', function(req, res) {
    res.render('index.ejs');
});

app.get('/myprofile', function(req, res) {
    res.render('myprofile.ejs');
});


app.get('/logout', function(req, res) {
    res.render('logout.ejs');
});

app.get('/play', function(req, res) {
    res.render('play.ejs');
});

app.get('/ladder', function(req, res) {
    res.render('ladder.ejs');
});

app.get('/room', function(req, res) {
    res.render('room.ejs');
});

app.use(express.static(__dirname + '/'));

app.use(function(req, res, next){
    res.setHeader('Content-Type', 'text/plain');
    res.send(404, 'Page introuvable !');
});
//FIN ROUTE//




//// SOCKET.IO ////
var messages = [];
var players = [];
var draws = [];
var rooms=[];
var roomPlayers=[];
var initTimer=65;
var timeTimer=initTimer;
var canvasColor, canvasSize;


// Quand une personne se connecte au serveur
io.sockets.on('connection', function (socket)
{		

	////////CANVAS ZONE/////////
	 socket.emit('recupererDessin', draws);
	//on recoit une modif dans le canvas
	socket.on('sendCanvas', function (line) 
		{
			// On l'ajoute au tableau (variable globale commune à tous les clients connectés au serveur)
			draws.push(line);
			// On envoie à tout les clients connectés (sauf celui qui a appelé l'événement) le nouveau message
			socket.broadcast.emit('recupererNouveauDessin', line);
		});

		socket.on('eraseCanvas', function(draws)
		{
			draws=[];
			socket.broadcast.emit('eraseAllDraws',draws);
		});
		
		//si on recoit un changement de couleur
		socket.on('canvasChangeColor', function(color)
		{
			socket.broadcast.emit('recupererColor', color);
			canvasColor=color;
		});
		
		//si on recoit un changement de size
		socket.on('canvasChangeSize', function(size)
		{
			socket.broadcast.emit('recupererSize', size);
			canvasSize=size;
		});
		
		

	////////TCHAT/////////
    // On donne la liste des messages (événement créé du côté client)
    socket.emit('recupererMessages', messages);
    // Quand on reçoit un nouveau message
    socket.on('nouveauMessage', function (mess) 
	{
        // On l'ajoute au tableau (variable globale commune à tous les clients connectés au serveur)
        messages.push(mess);
        // On envoie à tout les clients connectés (sauf celui qui a appelé l'événement) le nouveau message
        socket.broadcast.emit('recupererNouveauMessage', mess);
    });
	
	
	
	////////TIMER/////////
	//quand quelqu'un se connecte on lui envoie le temps
	socket.emit('initTimer',timeTimer);
	
	//quand on recoit la demande de Start du timer
	socket.on('startTimer', function (time)
	{
		//socket.broadcast.emit('displayTimer',timeTimer);
		socket.broadcast.emit('goTimer',timeTimer);
		socket.broadcast.emit('hideButton','start');
	});
	
	socket.on('myTime', function (time)
	{	console.log('TIME= '+time);
		time-=1;
		timeTimer=time;
		console.log('TIME -1 = '+time);
		socket.broadcast.emit('displayTimer',time);
		socket.emit('displayTimer',time);
	});
	
	socket.on('stopTimer', function(time)
	{
		socket.broadcast.emit('stopTimerB',time);
	});
	
	socket.on('resetTimer', function(reset)
	{
		socket.broadcast.emit('resetTimerB',reset);
		//socket.broadcast.emit('initTimer',timeTimer);
	});
	
	
	
	////////SCORING ZONE/////////
	//on donne la liste des joueurs
	socket.emit('recupererJoueurs', players);
	
	//quand on recoit un nouveau joueur
	socket.on('newPlayer', function(pseudo)
	{
		players.push(pseudo);
		socket.broadcast.emit('recupererNouveauJoueur', pseudo);
	});
	
	//quand un utlisateur quitte
	socket.on('delPlayer', function(pseudo)
	{	
		//on va chercher l'index
		for(var i = 0, l = players.length; i < l; i++)
		{
			if(players[i].pseudo==pseudo) var indexPseudo=i;
		}
		players.splice(indexPseudo,1);
		socket.broadcast.emit('recupererAnciensJoueurs', players);
		console.log('SYSTEM NOTIFICATION : '+pseudo+' LEFT');
	});
	
	socket.on('newScore', function(pseudo)
	{
		//on va chercher le profil
		for(var i = 0, l = players.length; i < l; i++)
		{
			if(players[i].pseudo==pseudo) {players[i].score+=1;
			console.log("score : "+players[i].score);}
			socket.broadcast.emit('recupererScores', players);
		}
	});
	
	
	
		/////REGISTER////
 socket.on('register', function(data) 
	{ 
		var username=data.username;
		var password=data.password;
		var confirm=data.confirm;
		var language=data.language;
	
        console.log('------------------------------');
        console.log("Nouvel enregistrement d'utilisateur");
        console.log("username : " + username);
        console.log("password : " +password);
        console.log("language : " + language);
        console.log('------------------------------');

        // On se connecte à la bdd
        mongoose.connect('mongodb://localhost/pictionary', function(err) 
        {
          if (err) { throw err; }
        });    

		// Ici on va récupérer les users ayant le pseudo entrés
		var query = userModel.find(null);
		query.where('username', username);
		query.exec(function (err, users) 
		{

			if (err) { throw err; }
			var message = '';
			var validation = null;

			//on vérifie ce que renvoie la requête
			if (users == false && password === confirm )
			{

				// On crée une instance du Model
				var NewUser = new userModel({ username : username, password : password, language : language });

				// On le sauvegarde dans MongoDB 
				NewUser.save(function (err) 
				{
					if (err) { throw err; }
					message = "User Registered";
					validation = 1;
					console.log("> " + message);
					socket.emit('register', {message: message, validation: validation, username:username});
					mongoose.connection.close();// On se déconnecte de MongoDB maintenant
				});
			}
			else
			{
				message = "This username is already taken or the Passwords doesn't match";
				validation = 0;
				console.log("> " + message);	
				socket.emit('register', {message: message, validation: validation});
				mongoose.connection.close();
			}
		});
    });
	
	
	//////LOGIN///////
	socket.on('login', function (data)
	{
		var username = data.username;
		var password = data.password;
		console.log('------------------------------');
		console.log("Nouvel tentative de connection utilisateur");
		console.log("username : " + username);
		console.log("password : " + password);
		console.log('------------------------------');

		// On se connecte à la base de données
		mongoose.connect('mongodb://localhost/pictionary', function(err) 
		{
		  if (err) { throw err; }
		});    

		// On cherche une ligne où le pseudo ET le password correspondent à ce qu'on a entré
		var query = userModel.find(null);
		query.where('username', username).where('password', password);
		query.exec(function (err, users)
		{

		  if (err) { throw err; }
		  var message = '';
		  var validation = null;

		  //on vérifie ce que renvoie la requête
		  if (users == false) 
			{

				message = "Failed login : incorect username or password";
				validation = 0;
				console.log("> " + message);
				socket.emit('login', {message: message, validation: validation});
				mongoose.connection.close();
			}
			else
			{
				message = "Success Login";
				validation = 1;
				console.log("> " + message);
				socket.emit('login', {message: message, validation: validation, username: username});
				mongoose.connection.close();
			};
		});
    }); 
	
	
	///////////PROFILE////////
	socket.on('profile', function(pseudo)
	{
		// On se connecte à la base de données
        mongoose.connect('mongodb://localhost/pictionary', function(err) 
        {
          if (err) { throw err; }
        });    

		// Ici on va récupérer les users ayant le pseudo récupéré par le cookie
		var query = userModel.find(null);
		query.where('username', pseudo);
		query.exec(function (err, users)
		{
			if (err) { throw err; }
			var message = '';
			var validation = null;

			//on vérifie ce que renvoie la requête
			if (users == false) 
			{
				message = "L'utilisateur n'existe pas";
				validation = 0;
				console.log("> " + message);
				io.sockets.emit('RecupProfile', {message: message, validation: validation});
				mongoose.connection.close();// On se déconnecte de MongoDB maintenant
			}
			else
			{
				message = "Récupération des données";
				validation = 1;
				console.log("> " + message);
				io.sockets.emit('recupProfile', {message: message, validation: validation, user: users});
				mongoose.connection.close();
			};
		});
	});
	
	
	/////////LADDER/////////
	socket.on('ladder', function(filtrer)
	{
		// On se connecte à la base de données
        mongoose.connect('mongodb://localhost/pictionary', function(err) 
        {
          if (err) { throw err; }
        });    
		// Ici on va récupérer les users ayant le pseudo récupéré par le cookie
		var query = userModel.find(null);
		query.where();
		query.sort([[filtrer, 'ascending']]);
		query.exec(function (err, users)
		{	
			if (err) { throw err; }
			var message = '';
			var validation = null;

			//on vérifie ce que renvoie la requête
			if (users == false) 
			{
				message = "There is no users";
				validation = 0;
				console.log("> " + message);
				socket.emit('RecupLadder', {message: message, validation: validation});
				mongoose.connection.close();// On se déconnecte de MongoDB maintenant
			}
			else
			{
				message = "Sending data...";
				validation = 1;
				console.log("> " + message);
				io.sockets.emit('recupLadder', {message: message, validation: validation, user: users});
				mongoose.connection.close();
			};
		});
	});
	
	
	
	///////ROOMS//////
	
	//quand on recoit une demande de nouvelle salle
	socket.on('newRoom', function(room)
	{
		rooms.push(room);
		socket.broadcast.emit('recupRooms', {'rooms':rooms,'validation':1} );
	});
	
	//quand on se conecte on recup les rooms présentent
	socket.emit('recupRooms', {'rooms':rooms,'validation':1} );
	
	//quand quelqu'un se connecte a une room
	socket.on('joinRoom', function(data)
	{
		roomPlayers.push(data);
		console.log('>>'+data.username+' has join the room '+data.room);
		socket.broadcast.emit('newPlayerInTheRoom',{'players':roomPlayers});
	});
	
	//on nous demande les joueurs d'une rooms
	socket.on('RoomPlayers', function(room)
	{
		socket.emit('recupRoomPlayers',{'players': roomPlayers});
	});
	
	//on recoit la demande pour lancer le jeu
	socket.on('launchGame', function(room)
	{
		//on broadcast aux user
		socket.broadcast.emit('letsPlay',{'players':roomPlayers});
		//on supprime la room du tableau pour pas que l'on puisse rentrer de nouveau 
		//on va chercher l'index
		for(var i = 0, l = rooms.length; i < l; i++)
		{
			if(rooms[i].name==room) var indexRoom=i;
		}
		rooms.splice(indexRoom,1);
		
	});
	
	
	//quand un utlisateur quitte une room
	socket.on('delPlayerRoom', function(pseudo)
	{	
		//on va chercher l'index
		for(var i = 0, l = roomPlayers.length; i < l; i++)
		{ 
			if(roomPlayers[i].username==pseudo) var indexPseudo=i;
		}

		roomPlayers.splice(indexPseudo,1);
		socket.broadcast.emit('recupRoomPlayers',{'players': roomPlayers});
	});
	
	
});
////FIN SOCKET//

server.listen(port);
console.log("Server Started on port : "+port);
