<?php
/**
 * Classe pour les salles
 * 
 * @author Olivier Arteau
 */

define('FLAG_SALLEPRIVEE', 'p');

class Salle {

    private $password = null;
    private $nom = null;
    private $flags = null;
    private $id = null;
    private $utilisateurs = null;
    
    /**
     * Constructeur d'une salle.
     * 
     * @param (String) 	nom
     * @param (Boolean) ifNotExistCreate Si la salle n'existe pas elle est créer
     */
    
    public function __construct($nom = null, $ifNotExistCreate = false) {
    	if ($nom != null) {
    		$this->loadRoom($nom, $ifNotExistCreate);
    	}
    }
    
    /**
     * Charge les données d'une salle, sauf les utilisateurs (sur demande seulement).
     * 
     *  @param (String) $name Nom de la salle.
     *  @param (Boolean) $ifNotExistCreate Crée la salle si elle n'existe pas
     */
    
    public function loadRoom($nom, $ifNotExistCreate = false) {
    	if (!$this->isValideNom($nom)) {
    		throw new Exception('Nom "' . $nom . '" invalide. Les caractères permis sont les lettres minuscules et majuscule, les chiffres et les _. Il faut avoir au moins 2 caractères.');
    	}
    	
    	$this->nom = $nom;
    	
    	if ($ifNotExistCreate) {
    		try {
    			$this->loadInfo();
    		} catch (Exception $e) {
    			// Création de la salle //
    			$bd = BDConnexion::getBdConnexion();
    			$sql = 'INSERT INTO salles (`nom`, `flags`, `password`) VALUES (?,?,?)';
    			$param = array($this->nom, '', '');
    			$bd->execQuery($sql, $param);
    			
    			// On charge les informations dont le ID qui est assigné //
    			$this->loadInfo();
    		}
    	}
    }
    
    /**
     * Retourne si le nom est valide
     * 
     * @param (String) $nom Nom à tester.
     * @return (Boolean) Si le nom est valide.
     */
    
    private function isValideNom($nom) {
    	$regexp = '/^[a-zA-Z0-9_]{2,32}$/';
    	return (preg_match($regexp, $nom) != 0);
    }
    
    /**
     * Charge les informations de la salle.
     */
    
    private function loadInfo() {
    	$bd = BDConnexion::getBdConnexion();
    	$sql = 'SELECT id, flags, password, nom FROM salles WHERE';
    	$parametre = array();
    	
    	if (isset($this->nom)) {
    		$sql .= ' nom=?';
    		array_push($parametre, $this->nom);
    		if (isset($this->id))
    			$sql .= ' AND ';
    	}
    	
    	if (isset($this->id)) {
    		$sql .= ' id=?';
    		array_push($parametre, $this->id);
    	}
    	
    	$resultat = $bd->execQuerySelect($sql, $parametre);
    	
    	if (isset($resultat[0])) {
	    	$this->password = $resultat[0]['password'];
	    	$this->flags = $resultat[0]['flags'];
	    	$this->id = $resultat[0]['id'];
	    	$this->nom = $resultat[0]['nom'];
    	} else {
    		throw new Exception('Salle inexistante');
    	}
    }
    
    /**
     * 
     */
    
    public function joinRoom(Utilisateur $utilisateur) {
    	if ($this->id == null)
    		$this->loadInfo();
    	
    	$bd = BDConnexion::getBdConnexion();
    	$sql = 'INSERT INTO occupation (`salleID`,`utilisateurID`) VALUES (?,?)';
    	$param = array($this->id, $utilisateur->getID());
    	$bd->execQuery($sql, $param);
    }
    
    public function leaveRoom(Utilisateur $utilisateur) {
    	if ($this->id == null)
    		$this->loadInfo();
    	
    	$bd = BDConnexion::getBdConnexion();
    	$sql = 'DELETE FROM occupation WHERE salleID=? AND utilisateurID=?';
    	$param = array($this->id, $utilisateur->getID());
    	$bd->execQuery($sql, $param);
    }
    
    /**
     * Chargement sur demande seulement, car cela utilise beaucoup de requête à la base de donné pour tout charger.
     * 
     * @return (array <Utilisateur>) $utilisateurs Liste des utilisateurs dans la salle.
     */
    
    public function getUtilisateurs() {
    	if ($this->id == null)
    		$this->loadInfo();
    	
    	if ($this->utilisateurs == null) {
    		$bd = BDConnexion::getBdConnexion();
    		$this->utilisateurs = array();
    		$sql = 'SELECT u.nom AS nom FROM occupation o INNER JOIN utilisateurs u ON o.utilisateurID=u.id WHERE o.salleID=? AND u.lastping>?';
	    	$parametre = array($this->id, time() - PING_TIMEOUT);
	    	$iterateur = $bd->execQueryIterator($sql, $parametre);
	    	while ($data = $iterateur->getNext()) {
	    		array_push($this->utilisateurs, new Utilisateur($data['nom']));
	    	}
    	}
    	
    	return $this->utilisateurs;
    }
    
    /**
     * Retourne le mot de passe encrypté de la salle.
     * S'il n'est pas chargé, effectue le chargement.
     * 
     * @return (String) Mot de passe
     */
    
    public function getPassword () {
    	if ($this->password == null)
    		$this->loadInfo();
    		
    	return $this->password;
    }
    
    /**
     * Retourne les flags de la salle.
     * S'il n'est pas chargé, effectue le chargement.
     * 
     * @return (String) Flags
     */
    
    public function getFlags () {
    	if ($this->flags == null)
    		$this->loadInfo();
    		
    	return $this->flags;
    }
    
    public function getNom () {
    	if ($this->nom == null)
    		$this->loadInfo();
    	return $this->nom;
    }
    
    public function setNom ($nom) {
    	$this->nom = $nom;
    }
    
    public function getID() {
    	if ($this->id == null)
    		$this->loadInfo();
    	return $this->id;
    }
    
    public function setID ($id) {
    	$this->id = $id;
    }
}
?>