* Informations
Ce fichier contient le journal de bord de Matthieu Nicolas concernant son activité sur PLM.
** Bibliographie
- https://github.com/oster/PLM
  Le lien vers le repo de la version originale de PLM
- https://github.com/MatthieuNICOLAS/webPLM
  Le lien vers le repo de la version web de PLM
* Journal de bord
** Semaine du <2015-02-09 lun.> au <2015-02-13 ven.>
*** Done
**** DONE Etablir le plan de la présentation
**** DONE Créer un dépôt pour la présentation
- Voir [[https://github.com/MatthieuNICOLAS/IJD-seminar-2015-03-03][ici]].
**** DONE Prendre en main reveal.js
- Ajout de [[https://github.com/hakimel/reveal.js][reveal.js]] au dépôt.
- Utilisation de [[http://johnmacfarlane.net/pandoc/][Pandoc]] pour [[http://johnmacfarlane.net/pandoc/demo/example9/producing-slide-shows-with-pandoc.html][générer les slides]] à partir d'un fichier *Markdown*.
**** DONE Ajouter l'opération BuggleDontHaveBaggle
**** DONE Ajouter l'opération CellAlreadyHaveBaggle
**** DONE Mettre en place les tests unitaires pour le code JS
- Ajout de [[http://jasmine.github.io/][jasmine]] et de [[http://sinonjs.org/][sinon]] au projet.
- Création d'une [[http://localhost:9000/specRunner][page]] permettant d'exécuter les tests.
- Ajout de tests unitaires pour les principales opérations.
- Ajout de tests unitaires pour les constructeurs des modèles de
  données.
- Ajout de tests unitaires pour *BuggleWorld*.
- Ajout de tests unitaire pour *canvas*.
*** Questions
**** Créer le type d'opération "ExceptionOperation" ?
- Actuellement, il existe un type d'opération spécifique pour chaque
  au type d'exception existant.
- Ne faudrait-il mieux pas créer un type d'opération générique
  possédant juste un nom et un message?
- Cela permettrait de factoriser le code de la génération des
  opérations et de leur exécution.
- Mais cela perdrait en clarté selon moi.
- Réponse Mt: On a pour l'instant une exception par type de problème
  potentiel car je me disais qu'un jour, les apprenants pourraient
  vouloir rattraper des exceptions et agir en conséquence. Il faut
  donc pas arrêter de faire ainsi, stp.
**** Refactorer BuggleWorld.generateOperation (JS) ?
- En appliquant *JSHint* sur *BuggleWorld*, j'ai relevé un
  avertissement généré expliquant que la complexité cyclomatique
  de *generateOperation* est actuellement trop élevée.
- Ceci est dû à l'utilisation d'un switch pour déterminer quel
  constructeur utiliser en fonction des données reçues.
- Comment pouvons-nous refactorer *generateOperation* pour que sa
  complexité ne soit plus une source d'avertissement?
**** Refactorer le code gérant la conversion en JSON des objets Scala ?
- Les objets Scala du serveur sont transmis au client après avoir été
  converti au format JSON.
- Pour chaque type d'objet, une fonction de conversion est définie.
- Ces fonctions sont actuallement éparpillées dans plusieurs
  fichiers: *PLMActor* et *ExecutionSpy*
- Comment mieux gérer cette partie du code? Mise en place d'un utilitaire?
*** Planned
**** TODO Préparer la présentation pour le séminaire IJD
- Travailler le plan de la présentation
- Voir pour essayer [[https://github.com/hakimel/reveal.js][reveal.js]].
**** TODO Ajouter des opérations correspondant aux exceptions levées
- BuggleDontHaveBaggleException
- CellAlreadyHaveBaggle
- BuggleInOuterSpaceException
- "Sorry Dave, I cannot let you use..."
**** TODO Poursuivre le développement de tests unitaires
- Ajouter des tests unitaires pour le code JS permettrait de s'assurer de la robustesse du code.
- Voir comment utiliser [[http://jasmine.github.io/][jasmine]].
- Voir comment utiliser [[http://sinonjs.org/][sinon]].
** Semaine du <2015-02-02 lun.>  au <2015-02-06 ven.>
*** Done
**** DONE Stocker localement la vitesse d'exécution de l'animation
- Il serait intéressant pour l'utilisateur que la vitesse d'exécution
  de l'animations soit conservée entre les exercices/entre les
  sessions.
- Utilisation de *localStorage*?
- Il existe un module *ngStorage* permettant de stocker facilement
   avec *localStorage* une valeur manipulée par *AngularJS*
- Implémentation de *ngStorage*.
- *ngStorage* semble ne plus être maintenu et comporter plusieurs problèmes: [[http://stackoverflow.com/questions/28136231/angularjs-controller-is-caching-in-firefox-and-ie-how-to-disable][voir ce thread]].
- Implémentation de [[https://github.com/tymondesigns/angular-locker][angular-locker]] à la place.
**** DONE Fixer le bug de "Program steps" dans le cas d'un monde possédant plusieurs entités
- Dans certains exercices, tels que BDR, plusieurs entités (buggles
  dans ce cas là) sont présentes dans le monde. Le programme de
  l'utilisateur s'exécutant en concurrence sur chacune des entités,
  les buggles bougent de façon chaotique jusqu'à atteindre l'état
  final.
 - A cause de cela, les pas décrits dans "Program steps" ne
 correspondent pas à un pas d'un buggle mais aux actions de plusieurs,
  ce qui peut gêner la compréhension du programme.
- Stocke maintenant les opérations dans les entités et non plus dans
  un tableau commun au monde.
- Lorsqu'un *worldStep* est détecté, on n'envoie les opérations que
  des entités étant marqué comme prête à envoyer.
**** DONE Permettre à l'utilisateur de sélectionner une leçon en double-cliquant dessus
- *$location.path* permet de rediriger l'utilisateur vers une nouvelle page
- *ng-dblclick* permet de détecter un double-clique
**** DONE Fixer le changement de monde involontaire
- Dans le 1er exercice de la leçon labyrinthe par exemple, lorsque
  l'utilisateur exécute son programme, la vue du monde passe toute
  seule sur la celle de *Blue cheese*.
- Dû à une erreur dans la méthode *reset*, qui remplaçait le monde
  affiché actuellement par le monde qu'on venait de remettre à zéro.
**** DONE Permettre à l'utilisateur d'écourter le replay
- Lorsque l'utilisateur rejoue l'exécution de son programme, il n'a
  pas d'autres choix que d'attendre la fin de l'animation pour pouvoir
  naviguer de nouveau entre les étapes.
- Il devrait pouvoir stopper l'animation (avec les boutons *reset* et *last* ?)
**** DONE Fixer les buggles décalés
- Si le monde n'est pas carré, les buggles ne sont pas correctement alignés sur le damier
**** DONE Etudier les options de codeMirror
- Auto-complétion des {}, ()... => Add-on [[http://codemirror.net/doc/manual.html#addon_closebrackets][closebrackets]]
- Suggestion de mots-clés => Add-on [[http://codemirror.net/doc/manual.html#addon_show-hint][show-hint]]
- Indentation par défaut => Option *tabSize* à passer dans la directive AngularJS
**** DONE Mettre en valeur le message d'erreur reçu lorsqu'on n'a pas réussi un exercice
- Message affiché dans l'onglet "Result", mais rien n'indique que quelque chose de nouveau y est écrit.
- Maintenant sélectionne l'onglet "Result" automatiquement lorsqu'il est mis à jour.
**** DONE Fix la compilation en Scala
- J'ai tenté de jouer avec les versions de Scala utilisées (2.10, 2.11) et avec l'origine de la dépendance (PLM ou webPLM) pour corriger le bug, sans succès.
- Je suis tombé sur [[http://stackoverflow.com/questions/27470669/scala-reflect-internal-fatalerror-package-scala-does-not-have-a-member-int][ce sujet]] traitant d'un problème similaire, mais aucune réponse n'a été proposée.
- Lancer l'application avec *activator start* au lieu de *activator run* permet de "résoudre" le problème!
**** DONE Bloquer les actions utilisateurs pendant le changement du langage de programmation
- Empêcher l'utilisateur de changer le langage de programmation actuel alors qu'un programme est en cours.
**** DONE Ajouter un message de félicitations lorsque l'utilisateur réussit un exercice
**** DONE Ajouter un bouton permettant de passer à l'exercice suivant
**** DONE Permettre à l'utilisateur de parcourir la liste des exercices
**** DONE Permettre à l'utilisateur de passer à l'exercice suivant
**** DONE Récupérer la liste des exercices pour chaque leçon
- getRootLectures permet de récupérer les exercices principaux d'une leçon
- getChildren permet ensuite de récupérer les exercices secondaires
*** Questions
**** Pourquoi la compilation de code Scala ne fonctionne pas si on lance l'application en mode développement?
- Post d'une [[https://groups.google.com/forum/#!topic/play-framework/a_80eHRxbAk][question]] sur la mailing list de *Play Framework* pour demander des explications, en attente d'une réponse.
**** Y a-t-il un intérêt à extraire la liste des exercices de ExerciseController pour en faire un data service?
- Un service permettrait de ne récupérer qu'une fois la liste des exercices au début d'une leçon, puisque les données sont conservées entre plusieurs pages.
- Mais comment le service serait informé du changement de leçon, s'il y en a eu un?
**** Comment gérer les opérations rajoutées par l'exercice ?
- Dans l'exercice *Voie du paradis*, les cases sur lesquelles passent
  le buggle s'illumine d'elles-même au fur et à mesure de l'exécution.
- Ca correspond à l'ajout d'opérations dans *Program steps* mais qui
  ne correspondent pas au pas attendu (le buggle avance alors qu'il
  est écrit qu'il est en train de peindre la case par exemple).
- Répone Mt: ha oui, c'est dommage. La magie de ce genre d'exercice va
  un peu tomber à l'eau. Tant pis pour l'instant.
*** Planned
**** TODO Fixer la duplication des baggles
- Un buggle a pu ramassé un baggle et le reposer ailleurs, sans que le baggle original ne soit retiré de la vue du monde.
**** TODO Fixer le baggle invisible
- Lors de la séance de test réalisée avec Gérald sur son Mac, un baggle présent dans l'exercice n'était pas dessiné.
**** TODO Refactorer le code concernant le passage au prochain exercice
- Nettoyer le code
- Voir pour l'extraire de ExerciseController et en faire un service
**** TODO Poursuivre le développement de tests unitaires
** Semaine du <2015-01-27 mar.> au <2015-01-30 ven.>
*** Done
**** DONE Rédiger le README du projet
**** DONE Permettre à l'utilisateur de changer le langage de programmation
   - Pour chaque exercice, récupérer la liste des langages disponibles
     et le langage actuellement selectionné.
   - Afficher cette liste côté client.
   - La liste doit permettre de changer le langage actuellement
     sélectionné ainsi que le mode de l'IDE.
**** DONE Refactorer drawBuggleImage
   - La méthode actuelle rencontre des difficultés à changer la
     couleur du Buggle: getImageData permet ed récupérer les pixels
     représentants l'image et de les modifier, mais ceux-ci
     correspondent aussi à la cellule sur laquelle se trouve le
     buggle...
   - Il faut donc colorier uniquement les pixels du buggle.
   - Le buggle dessiné n'a pas non plus toujours la bonne taille.
   - [[http://fabricjs.com/][Fabricjs]] propose des fonctions permettant de manipuler les
     images, à étudier.
*** Questions
**** Pourquoi la compilation de code Scala ne fonctionne pas dans webPLM mais fonctionne dans PLM?
*** Planned
**** CANCELLED Refactorer les controllers
   - Retirer les parties du codes interrogeant le serveur pour
     récupérer la liste des exercices/les données d'un exercice des
     controllers et en faire des services à la place.
   - Actuellement nécessaire d'écouter l'évènement "onmessage" pour
     traiter les messages provenant du serveur et n'étant pas une
     réponse à une requête (par exemple "operations"), on peut donc
     difficilement sortir complètement la logique de communication
     client/serveur des controllers.
** Semaine du <2015-01-19 lun.> au <2015-01-23 ven.>
*** Done
**** DONE Permettre à l'utilisateur de consulter l'API du monde
**** DONE Ajouter des tests unitaires côté serveur
   - Voir [[https://www.playframework.com/documentation/2.3.x/ScalaTestingYourApplication][la documentation de Play]] concernant l'ajout de tests
     unitaires.
   - Ajout de tests unitaires pour models.PLM.
   - Ajout de tests unitaires pour log.RemoteLogWriter.
**** DONE Retravailler l'interface de l'exerciseur
   - Revoir le placement des différents composants: consigne, éditeur
     de code, vue du monde/player.
   - Ajouter la console de log.
   - Ajouter le composant "dernier résultat" indiquant si le programme
     lancé a passé les tests et indiquant l'erreur rencontré dans le
     cas contraire.
   - Ajouter une liste des actions réalisées pour chaque monde
     (alternative au slider).
   - Lier les nouveaux composants aux données du controller.
**** DONE Intégrer les collisions avec les murs de BuggleWorld dans WebPLM
   - Gestion des collisions avec les murs
     - Transmission du message d'erreur au client
     - Arrêt de l'exécution du programme
**** DONE Intégrer les messages au sol de BuggleWorld dans WebPLM
   - Gestion des messages au sol (attribut content)
     - Ajout des opérations correspondantes
     - Représentation des messages dans l'interface cliente
**** DONE Refactorer l'architecture du projet côté client
   - Voir les bonnes pratiques listées dans [[https://github.com/johnpapa/angularjs-styleguide][ce guide]] et [[https://github.com/toddmotto/angularjs-styleguide][celui-ci]].
   - Utilisation de [[http://requirejs.org/docs/commonjs.html][CommonJS]] pour gérer les dépendances?
     => Non, juste besoin de lister l'ensemble des fichiers JS dans index.html.
   - Déplacement des directives: une par fichier.
**** DONE Fix Logger.debug
   - Rediriger la sortie standard vers l'interface client empêche les
     messages de debug du serveur de s'afficher.
   - Ajout d'un LoggerUtils s'occupant de désactiver/réactiver la
     capture de la sortie lorsque l'on souhaite logger.
**** DONE Rediriger ce qui est écrit dans la console de la PLM vers l'interface client
   - Voir Game.setOutputWriter
   - Ajout de RemoteLogWriter qui redirige la sortie standard vers la websocket.
**** DONE Fix la démo de RandMouseMaze
   - Lorsqu'on exécute la démo de cet exercice, le baggle n'est pas
     ramassé à la fin. De plus, si on recharge la page et relance la
     démo, la 1ère opération effectuée sera celle ramassant le baggle.
   - Ajout d'un stepUI à la fin de pickupBaggle
*** Questions
*** Planned
** du <2014-12-01 lun.> au <2015-01-16 lun.>
*** Done
**** DONE S'assurer que la procédure de mise en place de l'environnement de développement décrite ici est complète.
**** DONE Étudier comment déployer l'application au format standalone et la rendre facile d'utilisation
**** DONE Créer une archive zip de l'application à partir [[https://www.playframework.com/documentation/2.4.x/ProductionDist#Using-the-dist-task][des instructions suivantes]]
    SCHEDULED: <2014-12-02 mar.> 
    - L'archive résultante possède deux binaires, un pour les
      environnements UNIX et un pour les environnements Windows.
**** DONE Vérifier que le binaire pour UNIX fonctionne correctement
     SCHEDULED: <2014-12-02 mar.>

**** DONE Vérifier que le script .bat fonctionne correctement
     SCHEDULED: <2014-12-02 mar.>
**** DONE Mettre en place plusieurs vues côté client
   SCHEDULED: <2014-12-17 mer.>
   - *Angular* permet de créer des applications web fonctionnant en 1 page.
   - L'application reste néanmoins composée de plusieurs vues qui sont
     chargées à la volée par *Angular* selon l'état actuel.
   - Il faut donc modifier le code de l'interface cliente pour diviser
     l'application en vues.
**** DONE Création de l'interface de l'exerciseur
**** DONE Affichage de la consigne de l'exercice
    SCHEDULED: <2014-12-18 jeu.>
    - Quelques soucis de CSS encore par contre...
**** DONE Implémentation d'un éditeur de code
    SCHEDULED: <2014-12-19 ven.>
    - *CodeMirror* semble fonctionner correctement avec *Angular* grâce à [[https://github.com/angular-ui/ui-codemirror][ce module]].
**** DONE Représentation du monde courant et de son état
**** DONE Récupérer le code de l'étudiant pour l'exercice en cours
   SCHEDULED: <2014-12-19 ven.>
   - Reprendre le code utilisé dans GitSpy
**** DONE Permettre à l'étudiant d'exécuter son code
   SCHEDULED: <2015-01-05 lun.>
**** DONE Ajouter un bouton qui permet à l'étudiant d'envoyer son code à un web-service
    - La fonction déclenchée lors du click doit récupérer le code
      contenu dans CodeMirror et le transmettre au web-service.
**** DONE Le web-service exécute le code de l'étudiant
    - Reprendre le code utilisé dans les tests
**** DONE Le web-service renvoie le résultat au client
    - Actuellement, n'attend pas la fin de l'exécution du code pour
      envoyer le résultat (faussé du coup).
    - Modifier le web-service pour qu'il attende que le thread exécutant le programme se termine?
    - Web-service modifié pour qu'il ajoute un progressSpyListener à
      PLM, qui se charge de communiquer les résultats de l'exécution
      au client.
**** DONE L'interface affiche le résultat de l'exécution
**** DONE Afficher les étapes de l'exécution du code de l'étudiant
**** DONE Modifier les interactions entre le client et le serveur
    - Pour permettre au serveur d'envoyer des données en continu au
      client lors de l'exécution d'un programme, une WebSocket est
      requise.
**** DONE Permettre à PLM de streamer l'exécution du code
    - Créer une classe basée sur [[https://github.com/oster/PLM/blob/command-view/src/plm/universe/Bridge.java][Bridge]] et [[https://github.com/oster/PLM/blob/command-view/src/plm/universe/ISender.java][ISender]] enregistrant les
      différents actions effectuées à chaque pas et les écrivant dans un
      stream.
    - Créer une classe implémentant IWorldView et vidant un buffer à
      chaque WorldHasMoved?
**** DONE Transmettre le stream de l'exécution du code au client
    - Le serveur doit rediriger le stream dans la websocket du client.
    - Pas de solution simple pour créer un stream?
    - Donner à la classe une référence vers PLMActor et utiliser sa
      méthode createMessage permet de contourner ce problème.
**** DONE Envoyer l'état initial du monde
   - Au démarrage d'un exercice, le serveur doit fournir au client
     l'état initiaux des mondes.
**** DONE Créer le modèle local du monde
   - Le client doit récupérer les données pour créer un modèle local
     de chaque monde en fonction de son type.
**** DONE Représenter côté client le monde de l'exercice
   - Une fois le modèle du monde créé, il faut ensuite dessiner sa représentation.
**** DONE Ajouter un bouton permettant de stopper l'exécution en cours
   - Si l'étudiant code une boucle infinie, cela peut s'avérer plus
     pratique que de devoir redémarrer le serveur.
**** DONE Permettre à l'utilisateur de naviguer entre les étapes de son programme
   - La liste des opérations reçues doit être stockée pour chaque
     monde et l'utilisateur doit pouvoir les jouer/dé-jouer pour
     examiner le comportement de son programme.
**** DONE Etudier comment binder une valeur du modèle à un slider avec AngularJS
   - Ceci nous permettrait d'utiliser des sliders pour permettre à
     l'utilisateur de régler la vitesse d'animation ou de naviguer
     entre les différentes étapes du programme.
**** DONE Corriger l'affichage des murs
   - Les murs correspondant à la bordure du monde ne sont actuellement
     pas dessinés.
**** DONE Ajouter des types d'opérations supplémentaires
   - ChangeBuggleDirection
   - ChangeCellColor
**** DONE Ajouter la gestion des baggles
**** DONE Retirer le délai d'exécution côté serveur
**** DONE Récupérer l'état objectif du monde
   - Plutôt que de récupérer l'état objectif du monde, on peut se
     contenter de récupérer les opérations obtenues lors de
     l'exécution de la solution.
**** DONE Permettre à l'utilisateur de consulter l'objectif pour chaque monde
**** DONE Permettre à l'utilisateur d'exécuter le code de la solution en guise de démo
   - Nous n'avons pas besoin de rejouer la solution côté serveur
     lorsque l'étudiant souhaite voir la démo, puisque nous possèdons
     déjà les opérations de la solution.
**** DONE Permettre à l'utilisateur de passer d'un monde à l'autre
   - Certains exercices comportent plusieurs mondes.
   - L'utilisateur doit pouvoir passer d'un à l'autre pour observer le
     déroulement de son algorithme en fonction des différentes
     conditions.
   - La description d'une leçon est stockée dans différents fichiers
     selon la langue actuellement selectionnée. On utilise donc
     /FileUtils/ pour récupérer la description de la langue choisie.
   - Mais /FileUtils/ utilise /Locale/ pour déterminer le fichier à
     lire, qui semble rencontrer des problèmes d'initialisation
     avec *Play framework*.
   - Affecter la valeur par défaut à /Locale/ avant le test levant
     l'exception permet de pallier temporairement à ce problème.
**** DONE Instancier Game au lancement du serveur
   - Game n'est instancié qu'au moment où le serveur l'interroge. Son
     instanciation prenant plusieurs secondes, elle entraîne un
     timeout qui renvoie une erreur à l'utilisateur.
**** DONE Mettre en place une routine permettant de compiler les fichiers Dart en Javascript, rendant l'application compatible avec tous les navigateurs
    SCHEDULED: <2014-12-02 mar.> 
    - Dans Eclipse, le plugin Dart et son option /pub build/
      permettent de générer un dossier *build* contenant le code Dart
      ainsi que son équivalent Javascript.  Cependant, il est ensuite
      nécessaire de modifier les références vers les scripts pour
      qu'elles pointent vers ce nouveau dossier:
      - Soit nous mettons à jour les références côté client (fichiers
        HTML) pour tenir compte de ce changement,
      - Soit nous modifions le fichier /conf/routes.conf/ pour que ça
        soit le serveur qui redirige les requêtes des clients vers les
        bons fichiers.
    - Après plusieurs tests plus poussés, l'option /pub build/ ne
      fonctionne pas (plus?). En effet, lorsqu'on définit le template
      HTML d'un *Component* (élément basique d'*AngularDart*) dans un
      autre fichier que dans /component.dart/, /pub build/ échoue car
      il n'arrive pas à le localiser. Quant à la commande /dart2js -o
      main.dart.js main.dart/, elle fonctionne toujours et permet de
      générer directement les fichiers Javascript à l'emplacement
      souhaité.
**** DONE Modifier /build.sbt/ pour lancer la commande /dart2js -o main.dart.js main.dart/ avant de créer l'archive zip
     SCHEDULED: <2014-12-02 mar.>
    - J'ai rencontré des difficultés à modifier /build.sbt/ pour que
      les fichiers Dart soient compilés avant la création de
      l'archive. Je n'ai en effet pas trouvé comment configurer *sbt*
      pour ajouter l'exécution d'une commande shell lors du build.
    - J'ai donc créé un script shell se contentant de lancer les deux
      commandes à la suite et permettant ainsi de rendre l'application
      compatible avec tous les navigateurs et de l'exporter dans une
      archive zip.
**** DONE Instancier un objet PLM côté serveur
   SCHEDULED: <2014-12-03 mer.>
   - Plusieurs problèmes ont été rencontrés avant de réussir à
     instancier un objet PLM depuis un projet Play Framework.
     - Tout d'abord, le jar produit par PLM embarque pour plusieurs
       librairies, dont le *compilateur Scala*. Ceci provoque alors un
       doublon avec la configuration par défaut d'un projet *Play
       Framework*. Il a donc fallu retirer cette librairie du build de
       PLM.
     - Par défaut, Play Framework utilise la /version 2.11/ du
       compilateur Scala. Cette version est cependant incompatible
       avec PLM, qui est compilée à l'heure actuelle avec la /version
       2.10.5/ du compilateur. Pour permettre à l'application de
       fonctionner, il faut donc downgrader la version de scala
       utilisée en modifiant la valeur affectée à ~scalaVersion~ dans
       /build.sbt/.
**** DONE Mettre en place un webservice RESTful permettant d'interagir avec PLM
   SCHEDULED: <2014-12-04 jeu.>
**** DONE Ajouter pop-up au démarrage informant l'utilisateur que PLM conserve une trace de son activité suite au [[https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=772026][bug report suivant]]
   SCHEDULED: <2014-12-05 ven.>
**** DONE Permettre aux utilisateurs de désactiver l'envoi de la trace de leur activité au repo central
   SCHEDULED: <2014-12-05 ven.>
**** DONE Ajouter une fonction à PLM retournant la liste des leçons
   SCHEDULED: <2014-12-08 lun.>
**** DONE Etudier comment récupérer à partir du nom d'une leçon son image et sa description
   - Actuellement, /src/plm/core/ui/ChooseLessonDialog.java/ récupère
     à partir de la liste des leçons l'image et la description associée à chacune.
     Celles-ci sont contenues dans le jar de la PLM.
   - Maintenant que nous passons à une interface WEB, devons-nous
     externaliser ces fichiers (images et descriptions) pour y accéder
     directement depuis l'implémentation du serveur ou devons-nous les
     rendre accessibles par le biais d'attributs présents dans les
     classes exposées au serveur?
   - Possible d'accéder à une image contenue dans le jar à partir
     d'une son URL. Nous avons donc juste besoin de pouvoir récupérer
     le chemin de l'image associée à la leçon.
   - Possible de charger la description d'une leçon à son initialisation dans un champ.
**** DONE Modifier PLM pour disposer d'une liste de leçons initialisées au lancement
   - Ceci permettrait au serveur de récupérer la liste des leçons et
     de leurs données, qui seraient ensuite transmises au client pour
     construire la page d'accueil.
   - Les exercices des leçons et leurs solutions seraient toujours
     chargées uniquement au moment où l'utilisateur essaient d'y
     accéder.
**** DONE Charger la description d'une leçon
   SCHEDULED: <2014-12-11 jeu.>
   - La description d'une leçon est stockée dans différents fichiers
     selon la langue actuellement selectionnée. On utilise donc
     *FileUtils* pour récupérer la description de la langue choisie.
   - Mais *FileUtils* utilise /Locale/ pour déterminer le fichier à
     lire, qui n'est pas initialisée suite aux modifications apportées
     à l'instanciation de Game.
   - Il a donc fallu modifier *FileUtils* pour utiliser /getLocale/
     plutôt que /locale/ directement, /getLocale/ se chargeant
     d'initialiser cette dernière si elle n'est pas initialisée.
**** DONE Instancier Game au lancement du serveur
   SCHEDULED: <2014-12-11 jeu.>
   - Game n'est instancié qu'au moment où le serveur l'interroge. Son
     instanciation prenant plusieurs secondes, elle entraîne un
     timeout qui renvoie une erreur à l'utilisateur.
   - /Play Framework/ permet de définir un objet *Global* permettant
     de surcharger les fonctions appelées au lancement et au stop de
     l'application. Ceci permet d'instancier *Game* au démarrage.
**** DONE Afficher la page d'accueil de l'application automatiquement au lancement du serveur
   SCHEDULED: <2014-12-12 ven.>
**** CANCELLED Faire un mock-up de l'interface WEB
   - Il convient de choisir un framework CSS au préalable pour
     faciliter le développement de l'interface WEB. [[http://usablica.github.io/front-end-frameworks/compare.html][Cette page]] liste
     un grand nombre de ces derniers.
   - *BootStrap*, *Foundation* se démarquent par leur communauté importante (surtout *BootStrap*).
   - *Semantic UI* est aussi un choix intéressant, mais semble encore jeune (trop?).
   - Il est aussi important de prendre l'intégration du framework CSS
     avec le framework JS utilisé: il semblerait que les frameworks
     tels qu'*Angular* peuvent buggés suite à une modification du DOM
     par un autre script.
**** DONE Ajouter pop-up au démarrage informant l'utilisateur que PLM conserve une trace de son activité suite au [[https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=772026][bug report suivant]]
   SCHEDULED: <2014-12-05 ven.>
**** DONE Permettre aux utilisateurs de désactiver l'envoi de la trace de leur activité au repo central
   SCHEDULED: <2014-12-05 ven.>
**** DONE Implémenter une page web incorporant un éditeur de code tel que [[http://ace.c9.io/#nav=about][Ace]] ou [[http://codemirror.net/][CodeMirror]] depuis Dart
   SCHEDULED: <2014-12-08 lun.>
   - Création d'un /Component/ se chargeant des interactions entre
     Dart et Ace.
   - Mais avec AngularDart, un Component est inclus dans son
     propre *ShadowDom* ce qui empêche Ace de trouver l'élément à
     transformer en éditeur de code.
   - Possibilité de désactiver le ShadowDom en modifiant l'attribut ~useShadowDom~ du Component.
   - Hériter de *ShadowRootAware* permet d'écouter
     l'évènement *onShadowRoot* qui indique quand le DOM est chargé.
**** DONE Tester Foundation
   SCHEDULED: <2014-12-15 lun.>
   - *Foundation* propose des fonctionnalités qui peuvent s'avérer
     intéressantes telles que [[http://foundation.zurb.com/docs/components/block_grid.html][celle-ci]] ou encore [[http://foundation.zurb.com/docs/components/joyride.html][celle-là]].
   - Mais sa faiblesse est qu'il ne gère pas l'HTML généré
     dynamiquement (voir les issues [[https://github.com/zurb/foundation/issues/5503][#5503]] et [[https://github.com/zurb/foundation/issues/4827][#4827]]).
   - Pour pallier à ce problème, il est nécessaire d'appeler la
     méthode /$(document).foundation()/ à chaque fois que l'on modifie
     le DOM et que l'on souhaite utiliser une fonctionnalité
     de *Foundation*.
   - Est-ce que des appels répétés à cette méthode peuvent être
     handicapant pour l'application et ses performances au cours d'une
     longue session d'utilisation?
*** Questions
*** Planned
**** TODO Modifier les messages concernant l'envoi de données au serveur
   - Actuellement, plusieurs messages sont affichés pour informer
     l'utilisateur que PLM est en train d'envoyer les données de son
     activité au serveur.
   - Ces messages apparaissent même si l'utilisateur a refusé de
     communiquer ses données, ce qui peut prêter à confusion.
   SCHEDULED: <2014-12-08 lun.>

**** CANCELLED S'assurer que la procédure de mise en place de l'environnement de développement décrite [[https://github.com/MatthieuNICOLAS/play-with-dart/blob/master/README.md#getting-started][ici]] est complète.
**** CANCELLED Créer un jar de l'application [[https://www.playframework.com/documentation/2.4.x/ProductionDist#Using-the-SBT-assembly-plugin][à partir des instructions suivantes.]]
    SCHEDULED: <2014-12-01 lun.>
    - Lors de la création du jar, plusieurs erreurs surgissent:
    En effet, les librairies importées par Play Framework par défaut
    déclenchent un conflit puisqu'elles déclarent des classes avec le
    même nom.  Il est donc nécessaire de définir une [[https://github.com/sbt/sbt-assembly#merge-strategy][stratégie de résolution des conflits.]]
      - Tout d'abord,il faut remplacer /assemblyMergeStrategy/ de leur
        exemple par /mergeStrategy/ dans notre cas (doc pas à jour?)).
      - Utiliser /MergeStrategy.rename/ lève l'exception
        /Java.io.FileNotFoundException/. En effet, les fichiers en
        conflits sont renommés, et leur nouveau nom dépasse 255
        caractères.  Ceci empêche donc la création du jar.
      - Utiliser /MergeStrategy.last/ permet au build de
        passer. Cependant, la classe /play.core.server.NettyServer/
        n'est pas embarquée dans le jar, empêchant ainsi l'application
        de fonctionner.
      - Utiliser une combinaison de /MergeStrategy/ telle que:
        ~mergeStrategy in assembly := { 
case "META-INF/MANIFEST.MF" => MergeStrategy.rename 
case _ => MergeStrategy.first 
}~ 
        gènère aussi un jar ne fonctionnant pas car
        une dépendance est manquante.
**** CANCELLED Voir si on peut facilement passer d'un fichier /routes.conf/ pour le développement à un fichier /routes.conf/ pour le déploiement
     SCHEDULED: <2014-12-02 mar.>
**** CANCELLED Implémenter une page web incorporant un éditeur de code tel que [[http://ace.c9.io/#nav=about][Ace]] ou [[http://codemirror.net/][CodeMirror]] depuis Dart
   SCHEDULED: <2014-12-08 lun.
**** CANCELLED Tester Bootstrap
   SCHEDULED: <2014-12-16 mar.>
   - *Bootstrap* serait capable de détecter
     automatiquement les changements apportés au DOM.
   - Il reste à déterminer si cette détection automatique est plus
     performante que le refresh manuel de *Foundation*.

