<repo_name>jcolnago/LibrasProject<file_sep>/librasProject/librasproject/learning/ReviewThread.java
package learning;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.scene.paint.Color;

/**
 * Worker thread that implements the behavior of a review and its components
 * 
 * @author <NAME>
 */
public class ReviewThread extends Task<Void> {

    /* Class variables */
    private ReviewController controller;
    public ArrayList<LessonComponent> reviews;
    public String extraInformation;
    public List<String> images;
    public boolean review;
    
    
    /**
     * Class constructor
     * @params the reviewController that starts the thread and the review it
     * should run.
     */
    ReviewThread(ReviewController controller, boolean review) {
        this.controller = controller;
        this.review = review;
    }
    
    
    /**
     * Implements the logic of the behavior.
     * @return a string informing that it is done
     */
    @Override
    protected Void call() throws Exception {      
        boolean result;
        String recognized;
        PreparedStatement pStatement;
        Statement statement;
        
        int mistakes = 0;
        int iterations = controller.lessonComponents.size();
        
        Socket clientSocket = new Socket(controller.application.prop.getProperty("server"),
                Integer.parseInt(controller.application.prop.getProperty("port")));
        BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
        
        pStatement = controller.application.getConnection().prepareStatement(
                  "UPDATE review_component SET mistakes=?, last_reviewed='" 
                + controller.getCurrentTimeStamp() + "' WHERE component_id=? AND user_id='"
                + controller.application.getUserName() + "';");
        
        while (iterations >= 0) {
            
            /* Waits for the user to be ready */
            controller.setActiveCircle(Color.RED);
            synchronized(controller.ready) {
                controller.ready.wait(); 
            }

            Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                      controller.setRecognized("");
                    }
             });
            
            /* Indicate the user can start */
            controller.setActiveCircle(Color.GREEN);
            out.println("START");
            Thread.sleep(3000);  // In order to get the predominant value recognized
            out.println("STOP");
 
            recognized = in.readLine();
            result = recognized.equalsIgnoreCase(controller.currentComponent);
                      
            if (result) {
                /* Update the review_component with the amout of mistakes made */
                pStatement.setInt(1, mistakes);
                pStatement.setString(2, controller.currentComponent);
                pStatement.executeUpdate();

                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                      controller.progress+=1/controller.total;
                      controller.showNextElement();
                      controller.setActiveCircle(Color.RED);
                    }
                });  
                iterations--;
                mistakes = 0;
            }
            else {
                mistakes++;
                final String temp = recognized;
                
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                      controller.setRecognized(temp);
                    }
                });
            }          
        }
        if (!review) {
            statement = controller.application.getConnection().createStatement();
            statement.executeUpdate("UPDATE user_lesson SET complete=true" 
                + " WHERE lesson_id='" + controller.lessonName + "' AND user_id='"
                + controller.application.getUserName() + "';");
        }
        in.close();
        out.close();
        return null;
    }
}<file_sep>/librasProject/librasproject/login/LoginController.java
package login;

import java.net.URL;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;
import application.LibrasProject;

/**
 * This class is responsible for the control of the login scene.
 * 
 * @author <NAME>
 */
public class LoginController extends AnchorPane implements Initializable {

    /* Class variables */
    private LibrasProject application;
    
    /* FXML id for the different ui components */
    @FXML
    TextField userId;
    @FXML
    PasswordField password;
    @FXML
    Label errorMessage;
    
    
    /**
     * Performs the proper actions for when the close button receives an action.
     * 
     * @param event the action event information
     */
    @FXML
    private void handleCloseButtonAction(ActionEvent event) {
        application.closeConnection();
        Platform.exit();    // finishes the application
    }
    
    
    /**
     * Sets up the application and any other work that needs to be done on start
     * up.
     * 
     * @param application responsible for the scene
     */
    public void setApp(LibrasProject application){
        this.application = application;
    }   
    
    
    /**
     * This function responds to the event of pressing the login button.
     * It verifies if the user exists and, if so, if the password and login pair
     * is a valid one
     * 
     * @param event information about the event
     */
    @FXML
    public void processLogin(ActionEvent event) {
        PreparedStatement pStatement;
        ResultSet rs;
        try {
            pStatement = application.getConnection().prepareStatement("SELECT password " 
                    + "FROM user_login WHERE user_id='" + userId.getText() + "'");
            rs = pStatement.executeQuery();
            if (!rs.next()) {
                errorMessage.setText("Usuario nao cadastrado.");
            }
            else {
                if (!password.getText().equals(rs.getString("password"))){
                    errorMessage.setText("Usuario ou senha incorreta.");
                }
                else {
                    application.setUserName(userId.getText());
                    application.gotoSelection();
                }
            }
        } catch (SQLException ex) {
            Logger.getLogger(LoginController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    
    /**
     * This function responds to the event of pressing the register button.
     * It starts the registration scene.
     * 
     * @param event information about the event
     */
    @FXML
    public void registerUser(ActionEvent event) {
        application.gotoRegistration();
    }
    
    
    @Override
    public void initialize(URL location, ResourceBundle resources) {
        errorMessage.setText("");
        userId.setPromptText("learningLibras");
        password.setPromptText("<PASSWORD>");       
    } 
}
<file_sep>/librasProject/librasproject/learning/LearnController.java
package learning;

import kinect.ViewerPanel;
import java.net.URL;
import java.sql.SQLException;
import java.util.Random;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.layout.Pane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.util.Duration;
import application.LibrasProject;
import java.net.URISyntaxException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;

/**
 * This class is responsible for the control of the Lessons scene.
 * 
 * @author <NAME>
 */
public class LearnController extends LearningController implements Initializable {
    
    /* Class variables */
    private LearnThread learn;
    private MemorizeThread memorize;
    public final Object waitVideo = new Object();
    public final Object waitVerification = new Object();
    public boolean isCorrect = false;
    private ViewerPanel vp;
    
    /* FXML id for the different ui components */
    @FXML
    Pane Video;
    @FXML
    Button Play;
    
   
    
    /**
     * Performs the proper action for when the back button receives an action.
     * 
     * @param event the action event information
     */
    @FXML
    private void handleBackButtonAction(ActionEvent event) {
        learn.cancel();
        vp.closeDown();
        application.gotoSelection();    // returns to the selection scene
    }
    
    
    /**
     * Performs the proper action for when the back button receives an action.
     * 
     * @param event the action event information
     */
    @FXML
    private void handlePlayButtonAction(ActionEvent event) {
        stopVideo();    
        playVideo();
    }
    
    
   /**
     * Checks if the element clicked is the correct one.
     * 
     * @param event the action event information
     */
    @FXML
    private void checkIfCorrect(MouseEvent event) {
        ImageView image = (ImageView)event.getSource(); 
        isCorrect = image.getId().equals(currentComponent);
        synchronized(waitVerification) {
            waitVerification.notify();  
       } 
    }
    
    
    /**
     * Sets up the application and any other work that needs to be done on start
     * up.
     * 
     * @param application responsible for the scene
     * @param lessonName lesson's name that needs to be loaded
     */
    public void setApp(LibrasProject application, String lessonName) throws SQLException {        
        this.application = application;
        this.lessonName = lessonName;
        progress = 0;
        
        /* Get the information from these components*/
        lessonComponents = getLessonInformation();
        total = lessonComponents.size();
        
        showNextElement();
               
        vp = new ViewerPanel(this);
        Thread th1 = new Thread(vp);
        th1.setDaemon(true);
        th1.start();   // start updating the panel's image
        
        learn = new LearnThread(this);
        Thread th = new Thread(learn);
        th.setDaemon(true);
        th.start();  

    }
      

    /**
     * Sets up the path for the video to be used for the next lesson component.
     * 
     * @param fileLocation a string containing the video path
     */
    public void setVideo(String fileLocation) {
        if (!Video.getChildren().isEmpty()) {
            stopVideo();
            Video.getChildren().remove(0);
        }

        String video;
        try {
            video = (LibrasProject.class.getClassLoader().getResource(fileLocation).toURI().toString());
            Media media = new Media(video);

            // Create the player and set to play automatically.
            MediaPlayer mediaPlayer = new MediaPlayer(media);
            //mediaPlayer.setAutoPlay(true);
            mediaPlayer.setCycleCount(1);

             // Create the view and add it to the Scene.
            MediaView mediaView = new MediaView(mediaPlayer);
            mediaView.setFitHeight(274.0);
            mediaView.setFitWidth(300.0);
            mediaView.setPreserveRatio(false);
            Video.getChildren().add(mediaView);
        } catch (URISyntaxException ex) {
            Logger.getLogger(LearnController.class.getName()).log(Level.SEVERE, null, ex);
        }
   
    }
    
    
    /**
     * Plays the current video.
     */
    public void playVideo() {
       ((MediaView)Video.getChildren().get(0)).getMediaPlayer().play();
       synchronized(waitVideo) {
         waitVideo.notify();  
       }  
    }
    
    
    /**
     * Stops the current video displaying.
     */
    public void stopVideo() {
       if (((MediaView)Video.getChildren().get(0)).getMediaPlayer().getStatus() == MediaPlayer.Status.PLAYING) {
           ((MediaView)Video.getChildren().get(0)).getMediaPlayer().stop();
       }
    }
    
    
    /**
     * Gets the duration in milliseconds of the current video
     */
    public Duration getVideoDuration() {
       return ((MediaView)Video.getChildren().get(0)).getMediaPlayer().getMedia().getDuration();
    }

    
    /**
     * This function sets the value for the new element to be shown and if all
     * elements have already been shown, display the "done" message.
     */
    public void showNextElement() {
        int index;
        Random r = new Random();
        
        Progress.setProgress(progress);
        
        if (!lessonComponents.isEmpty()) {
           /* Defines new random lesson component */
            index = r.nextInt(lessonComponents.size());
            /* In case of the lessonsController set up the video */
            setVideo(lessonComponents.get(index).getVideo());
            /* Sets up the first lesson components to be shown */
            currentComponent = setUpLessonComponents(index);         
        }
        else {
            /* Part one has finished */
            application.gotoMemorize(lessonName);
        }
    }
    
    
    /**
     * This function sets the value for the new element to be shown and if all
     * elements have already been shown, display the "done" message.
     */
    public void showNextElementMemorize() {
        int index;
        Random r = new Random();
        
        Progress.setProgress(progress);
        
        if (!lessonComponents.isEmpty()) {
           /* Defines new random lesson component */
            index = r.nextInt(lessonComponents.size());
            /* In case of the lessonsController set up the video */
            setVideo(lessonComponents.get(index).getVideo());
            currentComponent = lessonComponents.get(index).getLessonComponentName();
            lessonComponents.remove(index); 
        }
        else {
            /* Part one has finished */
            application.gotoReview(lessonName, false);
        }
    }
    
        
    /**
     * Sets up the memorize part of the lesson.
     * 
     * @param application responsible for the scene
     * @param lessonName lesson's name that needs to be loaded
     */
    public void setMemorize(LibrasProject application, String lessonName) throws SQLException {       
        this.application = application;
        this.lessonName = lessonName;
        progress = 0;
        
        /* Get the information from these components*/
        lessonComponents = getLessonInformation();
        total = lessonComponents.size();      
                
        Image1.setImage(new Image(LibrasProject.class.getClassLoader().getResourceAsStream(lessonComponents.get(0).getImages().get(0))));
        Image1.setId(lessonComponents.get(0).getLessonComponentName());
        Image2.setImage(new Image(LibrasProject.class.getClassLoader().getResourceAsStream(lessonComponents.get(1).getImages().get(0))));
        Image2.setId(lessonComponents.get(1).getLessonComponentName());
        Image3.setImage(new Image(LibrasProject.class.getClassLoader().getResourceAsStream(lessonComponents.get(2).getImages().get(0))));
        Image3.setId(lessonComponents.get(2).getLessonComponentName());
        Image4.setImage(new Image(LibrasProject.class.getClassLoader().getResourceAsStream(lessonComponents.get(3).getImages().get(0))));
        Image4.setId(lessonComponents.get(3).getLessonComponentName());
        Image5.setImage(new Image(LibrasProject.class.getClassLoader().getResourceAsStream(lessonComponents.get(4).getImages().get(0))));
        Image5.setId(lessonComponents.get(4).getLessonComponentName());
        
        showNextElementMemorize();
               
        memorize = new MemorizeThread(this);
        Thread th = new Thread(memorize);
        th.setDaemon(true);
        th.start();
        
    }
      
       
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO
    } 
}
<file_sep>/librasProject/librasproject/selection/SelectionController.java
package selection;

import java.net.URL;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Calendar;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.input.InputEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import application.LibrasProject;
import java.util.ArrayList;
import learning.LearningController;

/**
 * This class is responsible for the control of the Selection scene
 * 
 * @author <NAME>
 */
public class SelectionController extends AnchorPane implements Initializable {
    
    /* Class variables */
    private LibrasProject application; // relates to the responsible application
    
    /* FXML id for the different ui components */
    @FXML
    public AnchorPane anchorPane;
     
    
    /**
     * Performs the proper actions for when the close button receives an action.
     * @param event the action event information
     */
    @FXML
    private void handleCloseButtonAction(ActionEvent event) {
        application.setUserName("");
        application.gotoLogin();
    }
    
    
    /**
     * Performs the proper actions for when the close button receives an action.
     * @param event the action event information
     */
    @FXML
    private void handleReview(String lessonName) {
        boolean inReview = false;
        try {
            Statement statement = application.getConnection().createStatement();
            ResultSet rs;
        
            rs = statement.executeQuery("SELECT c.component_id, mistakes, last_reviewed "
                + "FROM review_component AS rc, component AS c "
                + "WHERE user_id='" + application.getUserName() + "'"
                + "AND lesson_id='" + lessonName + "' "
                + "AND rc.component_id=c.component_id"); 

            long daysDiff;
            /* Iterate over every component */
            while(rs.next()) {
                daysDiff = (Calendar.getInstance().getTimeInMillis()-rs.getDate("last_reviewed").getTime())/(1000*60*60*24);
                if (rs.getInt("mistakes")*2 + daysDiff  > 6 && !inReview) {
                    application.gotoReview(lessonName, true);
                    inReview = true;
                }
            }
            if(!inReview) {
                (new LearningController()).showMessageBox("Parabéns!", "Não há mais nada para ser feito!");
            }            
        } catch (SQLException ex) {
            Logger.getLogger(SelectionController.class.getName()).log(Level.SEVERE, null, ex);
        }

    }
    
    
    /**
     * Performs the proper actions for when the different options of selection
     * receive mouse events
     * @param event the action event information
     */
    @FXML
    private void handleSelectionMouseAction(InputEvent event) {
        Statement statement;
        ResultSet rs;
        boolean complete = false;
        Group group = (Group)event.getSource();        
        
         /* If the mouse pointer clicks the group area */
        if (event.getEventType() == MouseEvent.MOUSE_CLICKED) {
            try {
                statement = application.getConnection().createStatement();
                rs = statement.executeQuery("SELECT complete "
                        + "FROM user_lesson WHERE user_id='" + application.getUserName()
                        + "' AND lesson_id='" + group.getId() + "'");
                while(rs.next()) {
                    complete = rs.getBoolean("complete");
                }     
            } catch (SQLException ex) {
                Logger.getLogger(SelectionController.class.getName()).log(Level.SEVERE, null, ex);
            }
            if (complete) {
                handleReview(group.getId());  // initiates the review
            }
            else {
                application.gotoLessons(group.getId());  // initiates the lesson with
                                        // the id of the group clicked  
            }
            
        }
       
        /* If the mouse pointer enters the group area */
        if (event.getEventType() == MouseEvent.MOUSE_ENTERED) {
            group.setOpacity(1.0);   // set the group opacity to fully visible          
        }
        /* If the mouse pointer exits the group area */
        else if (event.getEventType() == MouseEvent.MOUSE_EXITED) {
            group.setOpacity(0.5);   // set the group opacity to half visible    
        } 
    }
    
    
    /**
     * Sets up the application and any other work that needs to be done on start
     * up.
     * @param application application that's responsible for the scene
     */
    public void setApp(LibrasProject application){
        this.application = application;
        ResultSet rs;
        Statement statement;
        ObservableList<Node> children = anchorPane.getChildren();
        ArrayList<String> lessons = new ArrayList<>();
        ArrayList<String> complete = new ArrayList<>();
        
        try {
            statement = application.getConnection().createStatement();
            rs = statement.executeQuery("SELECT lesson_id FROM lesson");
            while(rs.next()) {
                lessons.add(rs.getString("lesson_id"));
            }
            
            statement = application.getConnection().createStatement();
            rs = statement.executeQuery("SELECT lesson_id FROM user_lesson WHERE "
                    + "complete=true AND user_id='" + this.application.getUserName()+"'");
            
            while(rs.next()) {
                complete.add(rs.getString("lesson_id"));
            }
            
            for (int i = 0; i < children.size(); i++) {
                if (children.get(i).getClass() == Group.class) {
                    if (!lessons.contains(children.get(i).getId())) {
                       children.get(i).setDisable(true);
                    }
                    if (complete.contains(children.get(i).getId())) {
                            ObservableList<Node> groupChildren = ((Group)children.get(i)).getChildren();
                            for (int j = 0; j < groupChildren.size(); j++) {
                               if ("done".equals(groupChildren.get(j).getId())) {
                                   groupChildren.get(j).setVisible(true);
                               }
                            }
                        }  
                    }
                    
                }
            } catch (SQLException ex) {
            Logger.getLogger(SelectionController.class.getName()).log(Level.SEVERE, null, ex);
        }
     }
    
    
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO
    }    
}
<file_sep>/librasProject/librasproject/registration/RegistrationController.java
package registration;

import login.LoginController;
import java.net.URL;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.beans.binding.BooleanBinding;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.PasswordField;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.AnchorPane;
import application.LibrasProject;
import javafx.scene.control.Label;
import validation.InputMaskValidation;

/**
 * This class is responsible for the control of the registration scene.
 * 
 * @author <NAME>
 */
public class RegistrationController extends AnchorPane implements Initializable {

    /* Class variables */
    private LibrasProject application;
    private BooleanBinding binding;
    private ToggleGroup sex;
    private ToggleGroup type;
    
    /* FXML id for the different ui components */
    @FXML
    TextField userId, age;
    @FXML
    PasswordField passw;
    @FXML
    RadioButton female, male, deaf, notDeaf;
    @FXML
    Button register;
    @FXML
    Label message;

    
    /**
     * Sets up the application and any other work that needs to be done on start
     * up.
     * 
     * @param application that's responsible for the scene
     */
    public void setApp(LibrasProject application){
        this.application = application;      
        final InputMaskValidation listener1 = new InputMaskValidation(InputMaskValidation.TEXTONLY, 15, userId);
        final InputMaskValidation listener2 = new InputMaskValidation(InputMaskValidation.PASSWORD, 20, passw);
        final InputMaskValidation listener3 = new InputMaskValidation(InputMaskValidation.NUMBERONLY, 3, age);

        userId.textProperty().addListener(listener1);
        passw.textProperty().addListener(listener2);
        age.textProperty().addListener(listener3);
        
        binding = new BooleanBinding() {
            {
            super.bind(listener1.erroneous, listener2.erroneous, listener3.erroneous);
            }

            @Override
            protected boolean computeValue() {
                return (listener1.erroneous.get() || listener2.erroneous.get() 
                     || listener3.erroneous.get());
            }
        };

        register.disableProperty().bind(binding);
        
        sex = new ToggleGroup();
        female.setToggleGroup(sex);
        female.setSelected(true);
        male.setToggleGroup(sex);
        
        type = new ToggleGroup();
        notDeaf.setToggleGroup(type);
        notDeaf.setSelected(true);
        deaf.setToggleGroup(type);
    }  
    
    
    /**
     * This function responds to the event of pressing the back button.
     * It returns to the login scene.
     * 
     * @param event information about the event
     */
    @FXML
    public void back2Login(ActionEvent event) {
        application.gotoLogin();
    }
    
    
    /**
     * This function responds to the event of pressing the register button.
     * It will add the user to the database as well as insert the values for this
     * user into other user related tables. 
     * 
     * @param event information about the event
     */
    @FXML
    public void addUser(ActionEvent event) {
        Statement statement;
        char gender;
        String type;

        /* Defines which options where selected */
        gender = female.isSelected() ? 'F' : 'M';
        type = deaf.isSelected() ? "surdo" : "ouvinte";   

        /* Insert user data into database */
        try {
            statement = application.getConnection().createStatement();
            statement.executeUpdate("INSERT INTO user_login"
                    + "(user_id, password, age, gender, type) VALUES ('" 
                    + userId.getText() + "','" + passw.getText() + "','"
                    + Integer.parseInt(age.getText()) + "','" + gender + "','"
                    + type + "')");
            
            /* Insert related information into database */
            insertUserLesson(userId.getText());
            insertReviewComponents(userId.getText());
            /* After it is done, return to the login page */
            application.gotoLogin();
            
        } catch (SQLException ex) {
            message.setText("Usuario ja cadastrado.");
            //Logger.getLogger(LoginController.class.getName()).log(Level.SEVERE, null, ex);
        } 
    }


    
    /**
     * This function inserts into the user_lesson table the necessary fields.
     * 
     * @param text contains the user_id
     */
    private void insertUserLesson(String text) {
        Statement statementSelect;
        Statement statement;
        ResultSet rs;
        
        try {
            statementSelect = application.getConnection().createStatement();
            statement = application.getConnection().createStatement();
            /* Obtain all lessons' ids */
            rs = statementSelect.executeQuery("SELECT lesson_id FROM lesson");
            while(rs.next()) {
               /* Insert a pair (lesson_id, user_id) for every lesson */
               statement.executeUpdate("INSERT INTO user_lesson"
                    + "(user_id, lesson_id) VALUES ('" 
                    + text + "','" + rs.getString("lesson_id") + "')"); 
            }
            
        } catch (SQLException ex) {
            message.setText("Problema na insercao dos dados do usuario. Tente novamente.");
            //Logger.getLogger(LoginController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    
    /**
     * This function inserts into the review_component table the necessary fields.
     * 
     * @param text contains the user_id
     */
    private void insertReviewComponents(String text) {
        Statement statementSelect;
        Statement statement;
        ResultSet rs;
        try {
            statementSelect = application.getConnection().createStatement();
            statement = application.getConnection().createStatement();
            /* Obtain all components' ids */
            rs = statementSelect.executeQuery("SELECT component_id FROM component");
            while(rs.next()) {
                /* Insert a pair (component_id, user_id) for every component */
               statement.executeUpdate("INSERT INTO review_component"
                    + "(user_id, component_id) VALUES ('" 
                    + text + "','" + rs.getString("component_id") + "')"); 
            }
            
        } catch (SQLException ex) {
            message.setText("Problema na insercao dos dados do usuario. Tente novamente.");
            //Logger.getLogger(LoginController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    
    @Override
    public void initialize(URL location, ResourceBundle resources) {
        
    }  
}
<file_sep>/librasProject/librasproject/application/LibrasProject.java
package application;

import learning.ReviewController;
import selection.SelectionController;
import registration.RegistrationController;
import learning.LearnController;
import login.LoginController;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.fxml.JavaFXBuilderFactory;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import lesson2DB.Lesson2DB;

/**
 * Project's main class
 * 
 * @author <NAME>
 */
public class LibrasProject extends Application {
    
    /* Class variables */
    private Stage stage;
    private String userName;
    private Connection connection = null;
    public Properties prop = new Properties();
    
    
    /**
     * Function responsible for establishing a connection to the desired 
     * database.
     */
    public void establishConnection() {
        
        // If there is a connection already, return.
        if (connection != null){ 
            return;
        }
            
        // Database url that determines the database to be connected to.
        try {
            Class.forName("org.postgresql.Driver");
               
            // Must determine database, user and password
            connection = DriverManager.getConnection(prop.getProperty("dbURL"),
                    prop.getProperty("dbUser"), prop.getProperty("dbPassword"));
               
            if (connection != null) {
                System.out.println("Connecting to database...");
            }
        } catch (ClassNotFoundException | SQLException ex) {
            Logger.getLogger(LibrasProject.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    
    /**
     * Function responsible for closing the connection previously established. 
     */
    public void closeConnection() {
        try {
            connection.close();
        }
        catch(Exception e) {
            System.out.println("Problem to close the connection to the database");
        }
    }
    
    
    /**
     * The main entry point for all JavaFX applications.
     * 
     * @param primaryStage the primary stage
     */
    @Override
    public void start(Stage primaryStage) throws Exception {
        /* load the properties file */
        
        prop.load(LibrasProject.class.getClassLoader().getResourceAsStream("lessonResources/config.properties"));
        establishConnection();
        
        (new Lesson2DB()).insertIntoDB(this);
               
        /* Initializes the application state and its properties */
        stage = primaryStage;
        stage.setTitle("Learning Libras");
        stage.setResizable(false);
        stage.centerOnScreen();
        
        gotoLogin();                // starts first Scene
        primaryStage.show();        // shows the stage
    }

    
    /**
     * The main() method is ignored in correctly deployed JavaFX application.
     * main() serves only as fallback in case the application can not be
     * launched through deployment artifacts, e.g., in IDEs with limited FX
     * support. NetBeans ignores main().
     *
     * @param args the command line arguments
     */
    public static void main(String[] args) {
       launch(args);
    }
    
    
    /**
     * Responsible for loading the new scene based on the .fxml file
     * 
     * @param fxml the fxml related to the scene that should be loaded
     * @return returns the controller for that scene
     */
    private Initializable replaceSceneContent(String fxml) throws Exception {
        FXMLLoader loader = new FXMLLoader();
        InputStream in = LibrasProject.class.getResourceAsStream(fxml);
        loader.setBuilderFactory(new JavaFXBuilderFactory());
        loader.setLocation(LibrasProject.class.getResource(fxml));
        AnchorPane page;
        try {
            page = (AnchorPane) loader.load(in);
        } finally {
            in.close();
        } 
        Scene scene = new Scene(page);
        stage.setScene(scene);
        stage.sizeToScene();
        return (Initializable) loader.getController();
    }
    
    
    /**
     * Loads the controller for the selection scene based on the .fxml file.
     */
    public void gotoSelection() {
        try {
            SelectionController selection = (SelectionController) replaceSceneContent("/selection/Selection.fxml");
            selection.setApp(this);
        } catch (Exception ex) {
            Logger.getLogger(LibrasProject.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    
    /**
     * Loads the controller for the Lessons scene based on the .fxml file.
     * 
     * @param lessonName the lesson name of the lesson to be initialized
     */
    public void gotoLessons(String lessonName) {
        try {
            LearnController lessons = (LearnController) replaceSceneContent("/learning/Learn.fxml");
            lessons.setApp(this, lessonName);
        } catch (Exception ex) {
            Logger.getLogger(LibrasProject.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    
    /**
     * Loads the controller for the Lessons scene based on the .fxml file.
     * 
     * @param lessonName the lesson name of the lesson to be initialized
     */
    public void gotoMemorize(String lessonName) {
        try {
            LearnController lessons = (LearnController) replaceSceneContent("/learning/Memorize.fxml");
            lessons.setMemorize(this, lessonName);
        } catch (Exception ex) {
            Logger.getLogger(LibrasProject.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    
    /**
     * Loads the controller for the review scene based on the .fxml file. 
     */
    public void gotoReview(String lessonName, boolean isReview) {
        try {
           ReviewController review = (ReviewController) replaceSceneContent("/learning/Review.fxml");
           review.setApp(this, lessonName, isReview);
        } catch (Exception ex) {
            Logger.getLogger(LibrasProject.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    
    /**
     * Loads the controller for the login scene based on the .fxml file.
     */
    public void gotoLogin() {
        try {
            LoginController login = (LoginController) replaceSceneContent("/login/Login.fxml");
            login.setApp(this);
        } catch (Exception ex) {
            Logger.getLogger(LibrasProject.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    
    /**
     * Loads the controller for the registration scene based on the .fxml file.
     */
    public void gotoRegistration() {
        try {
            RegistrationController registration = (RegistrationController) replaceSceneContent("/registration/Registration.fxml");
            registration.setApp(this);
        } catch (Exception ex) {
            Logger.getLogger(LibrasProject.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    
    /**
     * Gets the current user logged in.
     * 
     * @return the userName
     */
    public String getUserName() {
        return userName;
    }

    
    /**
     * Sets the current user logged in.
     * 
     * @param userName the userName to set
     */
    public void setUserName(String userName) {
        this.userName = userName;
    }
    
    
    /**
     * Returns the connection to the database
     * 
     * @return the connection
     */
    public Connection getConnection() {
        return connection;
    }
}<file_sep>/README.md
LibrasProject
=============
To use the LibrasProject you need to have the ListeningServer and GestureUI running as well as have created a postgresql database based on the LibrasProject/librasProject/database.backup file.  
  
  * On installing PostgreSQL on Ubuntu 12.04 and creating the database:  
  sudo apt-get install postgresql  

  // Change the PostgreSQL postgres user paswword  
  sudo -u postgres psql postgres  
  \password postgres  
  
  // Create DB  
  sudo -u postgres createdb librasProject  
  
  // restore DB  
  pg_restore -d librasProject -h localhost -p 5432 -U postgres -W database.backup  

You must also have JavaFX if you plan on developing more uis:  
  * http://www.wikihow.com/Install-JavaFX-on-Ubuntu-Linux

You must then set the values on the LibrasProject/librasProject/librasproject/lessonResources/config.properties accordingly.  
The server and port values are related to the ListeningServer.   

**These values must be the same for the GestureUI NetworkConfig tab.**  

    
ListeningServer
==============
To start the ListeningServer you must run the .jar file with the port number you wish to listen to.

GestureUI
=========
The GestureUI needs a couple of  steps to be ready for use:  
  * Pre-requisites  
    - Ubuntu 12.04 LTS amd64  
    - Synaptic Package Manager (sudo apt-get install synaptic)  

  * Using Synaptic  
    - Search for 'opencv' and select everything except: opecv-doc, python-opencv, libopencv-gpu-dev (this will deselect libopencv-dev)  
    - Search for 'wxwidgets' (2.8) and select: libwxbase, libwxgtk (for both select also the dev option) wx-common, wx2.8-headers  
    - Search for 'boost' and select: libboost-all-dev (1.48)  

  * Download   
    - All the files necessary for this process are inside the GestureUI-Installation folder.  

  * Kinect  
    - After connecting the kinect type on the terminal:  
        lsmod | grep kinect  
        sudo modprobe -r gspca_kinect (in case gspca_kinect was shown with the grep)  
        sudo echo "blacklist gspca_kinect" >> /etc/modprobe.d/blacklist.conf  

  * Openni  
    - Unzip openni tar (create a folder)  
    - Navigate to the folder and execute sudo ./install.sh  

  * Sensor  
    - Unzip sensor tar (create a folder)  
    - Navigate to the folder and execute sudo ./install.sh  

  * Terminal  
    - Execute:  
         sudo apt-get install libusb-1.0.0-dev  
         sudo apt-get install freeglut3  

  * NITE  
    - Unzip nite tar (create a folder)  
    - Navigate to the folder and execute sudo ./install.sh  

  * Extract the models on your home folder  
 
  * Extract the gestureUI folder on a folder of choice.  
  
------

Once you start the GestureUI software you should:  
  + Click on the Kinect icon.  
  + Click on the play button.  
  + Fill the server and port values on the NetworkConfig Tab.  
  + With the ListeningServer running click on "Connect to Gesture Interface" icon  
  + Since only two sets of gestures have been trained for the LibrasProject you must select for:  
    - Vogais(Vowels): go to "Gesture Recognition" tab and select "MLP_VivenciaAEIOU_5V_6_MLP" from Configuration>>Trained Model  
    - Consoantes(Consonants): go to "Gesture Recognition" tab and select "MLP_VivenciaBCFLV_2_MLP" from Configuration>>Trained Model  
  + Click on the "Start Gesture Recognition" icon  

Whenever the user wishes to change lesson (From "vogais" to "consoantes" or vice-versa) it is necessary to stop the gesture recognition and change the Trained Model. Then you must restart the recognition and can start the lesson.
