<commit_before>package tatai;
 
import java.io.BufferedReader;

import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.concurrent.WorkerStateEvent;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
 
public class TataiController {
	// Stage to swap scenes in and out of.
	private Stage _stage = null;
	// Scenes.
	private TataiLoader _loader;
	// Current level.
	private int _level = 0;
	// Total number of questions.
	final static private int NUM_QUESTIONS = 10;
	// Current question number up to.
	private int _currentQuestionNumber = 0;
	// Number of correct answers this level.
	private int _numCorrect = 0;
	// Number of previous attempts.
	private int _tries = 0;
	// Player.
	private MediaPlayer _mediaPlayer;
	// Filename.
	final static private String FILENAME = "recording.mp3";
	// Filename.
	final static private String FILENAMEBASE = "recording";
	// List of statistics.
	private List<TataiStatistic> _statistics = new ArrayList<TataiStatistic>();
	// Statistics table to update.
	private TableView<TataiStatistic> _table = new TableView<TataiStatistic>();
	// Number that user has to pronounce in Maori
	private int _numToSay = 0;
	// Boolean to determine if sounds should stop loading. If not on the same page as it was when it started loading, it will not play the sound.
	private boolean _samePage = true;
	
	@FXML private Text number;
	@FXML private Button recordButton;
	@FXML private Button returnButton;
	@FXML private Button redoButton;
	@FXML private Button playButton;
	@FXML private Button nextButton;
	@FXML private Text announceRight;
	@FXML private Text announceWrong;
	@FXML private Text announceRecording;
	@FXML private Text numberCorrect;
	@FXML private Button nextLevelButton;
	@FXML private HBox statsPanel;
	@FXML private Text questionNumber;
	@FXML private ProgressBar progressBar;
	@FXML private ImageView imageRight;
	@FXML private ImageView imageWrong;
	@FXML private BorderPane root;
	
	public TataiController(Stage stage) {
		_stage = stage;
    	_loader = new TataiLoader(this);
	}
	
	// Executes some bash command received as an argument.
	private List<String> executeCommand(String cmd) {
		// Read output from the bash.
		List<String> output = new ArrayList<>();
		ProcessBuilder builder = new ProcessBuilder("/bin/bash", "-c", cmd);
		try {
			Process process = builder.start();
			InputStream stdout = process.getInputStream();
			BufferedReader stdoutBuffered = new BufferedReader(new InputStreamReader(stdout));
			String line = null;
			while ((line = stdoutBuffered.readLine()) != null ) {
				output.add(line);
			}
		} catch (Exception e) {
			
		}
		return output;
	}
	
	public void init() {
		// Initialize the statistics page with a table.
		
    	ObservableList<TataiStatistic> data = FXCollections.observableArrayList(_statistics);
    	TableColumn timeCol = new TableColumn("Time completed");
    	timeCol.setMinWidth(195);
    	timeCol.setCellValueFactory(new PropertyValueFactory<TataiStatistic,String>("time"));
    	TableColumn scoreCol = new TableColumn("Score");
    	scoreCol.setMinWidth(95);
		scoreCol.setCellValueFactory(new PropertyValueFactory<TataiStatistic,String>("score"));
		TableColumn levelCol = new TableColumn("Level");
		levelCol.setMinWidth(195);
		levelCol.setCellValueFactory(new PropertyValueFactory<TataiStatistic,String>("level"));
		
		_table.setItems(data);
        _table.getColumns().addAll(timeCol, scoreCol, levelCol);
        // Add placeholder text while empty.
        _table.setPlaceholder(new Label("No scores to display."));
        // Prevent horizontal scrollbars.
        _table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);

        // Add the table to the panel.
        statsPanel.getChildren().addAll(_table);
		
        // Show menu.
		Scene scene = _loader.getScene("menu");
	    
        _stage.setTitle("Welcome to Tatai!");
        _stage.setScene(scene);
        _stage.show();
	}
	    
    @FXML protected void showLevel1(ActionEvent event) {
    	_level = 1;
    	initLevel();
    }
    
    @FXML protected void showLevel2(ActionEvent event) {
    	_level = 2;
    	initLevel();
    }
    
    private void initLevel() {
    	_numCorrect = 0;
    	_currentQuestionNumber = 1;
    	_tries = 0;
    	showLevel();
    }
    
    @FXML protected void showMenu(ActionEvent event) {
    	stopSound();
    	Scene scene = _loader.getScene("menu");
    	_stage.setScene(scene);
        _stage.show();
    }
    
    @FXML protected void record(ActionEvent event) {
    	// Hide recording button, show recording dialog.
    	minimizeButtons();
		announceRecording.setVisible(true);
		announceRecording.setManaged(true);
    	// Ensure GUI concurrency by doing in background
		Task<Void> task = new Task<Void>() {
			@Override public Void call(){
				// Remove any previous recording files so overwrite prompt doesn't hold up thread
				executeCommand("rm "+FILENAMEBASE+".wav ");
				executeCommand("rm "+FILENAMEBASE+".mp3 ");
				// Record the user with ffmpeg.
				executeCommand("ffmpeg -f alsa -ar 44100 -i default -loglevel quiet -t 3 "+FILENAMEBASE+".wav ");
				executeCommand("ffmpeg -loglevel quiet -i "+FILENAMEBASE+".wav -f mp3 "+FILENAMEBASE+".mp3");
				// Wait for user to finish recording.
				/*
				try {
					TimeUnit.SECONDS.sleep(3);
				} catch (InterruptedException e) {
					;
				}*/
				return null;
		    }
		};
		new Thread(task).start();
		
		// When recording has finished:
		task.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
	        @Override
	        public void handle(WorkerStateEvent t) {
	        	minimizeButtons();
	        	
	        	// TODO Process here.
	        	
	        	// Equivalent of pseudo-randomly allocating a correctness. This is only for testing while the speech recognition is being developed.
	        	// TODO Finish speech recognition and remove this.
	        	boolean isCorrect = _numToSay % 2 == 0;
	        	
	        	// If correct, hide the redo button and increase the number correct.
	        	if (isCorrect) {
	        		_numCorrect++;
	        		announceRight.setVisible(true);
	        		announceRight.setManaged(true);
	        		imageRight.setVisible(true);
	        		imageRight.setManaged(true);
	        		root.setStyle("-fx-background-color:#388E3C;");
	        	}
	        	else {<commit_msg>Recrording Freeze, HVite Write to File<commit_after>package tatai;
 
import java.io.BufferedReader;

import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.concurrent.WorkerStateEvent;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
 
public class TataiController {
	// Stage to swap scenes in and out of.
	private Stage _stage = null;
	// Scenes.
	private TataiLoader _loader;
	// Current level.
	private int _level = 0;
	// Total number of questions.
	final static private int NUM_QUESTIONS = 10;
	// Current question number up to.
	private int _currentQuestionNumber = 0;
	// Number of correct answers this level.
	private int _numCorrect = 0;
	// Number of previous attempts.
	private int _tries = 0;
	// Player.
	private MediaPlayer _mediaPlayer;
	// Filename.
	final static private String FILENAME = "recording.mp3";
	// Filename.
	final static private String FILENAMEBASE = "recording";
	// List of statistics.
	private List<TataiStatistic> _statistics = new ArrayList<TataiStatistic>();
	// Statistics table to update.
	private TableView<TataiStatistic> _table = new TableView<TataiStatistic>();
	// Number that user has to pronounce in Maori
	private int _numToSay = 0;
	// Boolean to determine if sounds should stop loading. If not on the same page as it was when it started loading, it will not play the sound.
	private boolean _samePage = true;
	
	@FXML private Text number;
	@FXML private Button recordButton;
	@FXML private Button returnButton;
	@FXML private Button redoButton;
	@FXML private Button playButton;
	@FXML private Button nextButton;
	@FXML private Text announceRight;
	@FXML private Text announceWrong;
	@FXML private Text announceRecording;
	@FXML private Text numberCorrect;
	@FXML private Button nextLevelButton;
	@FXML private HBox statsPanel;
	@FXML private Text questionNumber;
	@FXML private ProgressBar progressBar;
	@FXML private ImageView imageRight;
	@FXML private ImageView imageWrong;
	@FXML private BorderPane root;
	
	public TataiController(Stage stage) {
		_stage = stage;
    	_loader = new TataiLoader(this);
	}
	
	// Executes some bash command received as an argument.
	private List<String> executeCommand(String cmd) {
		// Read output from the bash.
		List<String> output = new ArrayList<>();
		ProcessBuilder builder = new ProcessBuilder("/bin/bash", "-c", cmd);
		try {
			Process process = builder.start();
			InputStream stdout = process.getInputStream();
			BufferedReader stdoutBuffered = new BufferedReader(new InputStreamReader(stdout));
			String line = null;
			while ((line = stdoutBuffered.readLine()) != null ) {
				output.add(line);
			}
		} catch (Exception e) {
			
		}
		return output;
	}
	
	public void init() {
		// Initialize the statistics page with a table.
		
    	ObservableList<TataiStatistic> data = FXCollections.observableArrayList(_statistics);
    	TableColumn timeCol = new TableColumn("Time completed");
    	timeCol.setMinWidth(195);
    	timeCol.setCellValueFactory(new PropertyValueFactory<TataiStatistic,String>("time"));
    	TableColumn scoreCol = new TableColumn("Score");
    	scoreCol.setMinWidth(95);
		scoreCol.setCellValueFactory(new PropertyValueFactory<TataiStatistic,String>("score"));
		TableColumn levelCol = new TableColumn("Level");
		levelCol.setMinWidth(195);
		levelCol.setCellValueFactory(new PropertyValueFactory<TataiStatistic,String>("level"));
		
		_table.setItems(data);
        _table.getColumns().addAll(timeCol, scoreCol, levelCol);
        // Add placeholder text while empty.
        _table.setPlaceholder(new Label("No scores to display."));
        // Prevent horizontal scrollbars.
        _table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);

        // Add the table to the panel.
        statsPanel.getChildren().addAll(_table);
		
        // Show menu.
		Scene scene = _loader.getScene("menu");
	    
        _stage.setTitle("Welcome to Tatai!");
        _stage.setScene(scene);
        _stage.show();
	}
	    
    @FXML protected void showLevel1(ActionEvent event) {
    	_level = 1;
    	initLevel();
    }
    
    @FXML protected void showLevel2(ActionEvent event) {
    	_level = 2;
    	initLevel();
    }
    
    private void initLevel() {
    	_numCorrect = 0;
    	_currentQuestionNumber = 1;
    	_tries = 0;
    	showLevel();
    }
    
    @FXML protected void showMenu(ActionEvent event) {
    	stopSound();
    	Scene scene = _loader.getScene("menu");
    	_stage.setScene(scene);
        _stage.show();
    }
    
    @FXML protected void record(ActionEvent event) {
    	// Hide recording button, show recording dialog.
    	minimizeButtons();
		announceRecording.setVisible(true);
		announceRecording.setManaged(true);
    	// Ensure GUI concurrency by doing in background
		Task<Void> task = new Task<Void>() {
			@Override public Void call(){
				// Remove any previous recording files so overwrite prompt doesn't hold up thread
				executeCommand("rm "+FILENAMEBASE+".wav ");
				executeCommand("rm "+FILENAMEBASE+".mp3 ");
				// Record the user with ffmpeg.
				executeCommand("ffmpeg -f alsa -ar 22050 -i default -loglevel quiet -t 3 "+FILENAMEBASE+".wav ");
				// Run HVite and write output to file
				executeCommand("mv " + FILENAMEBASE + ".wav /home/se206/Documents/HTK/MaoriNumbers/");
				executeCommand("cd /home/se206/Documents/HTK/MaoriNumbers/; HVite -H HMMs/hmm15/macros -H HMMs/hmm15/hmmdefs -C user/configLR  -w user/wordNetworkNum -o SWT -l '*' -i recout.mlf -p 0.0 -s 5.0  user/dictionaryD user/tiedList " + FILENAMEBASE + ".wav ");
				// convert wav file to mp3
				executeCommand("cd -; ffmpeg -loglevel quiet -i "+FILENAMEBASE+".wav -f mp3 "+FILENAMEBASE+".mp3");
				
				
				return null;
		    }
		};
		new Thread(task).start();
		
		// When recording has finished:
		task.setOnSucceeded(new EventHandler<WorkerStateEvent>() {
	        @Override
	        public void handle(WorkerStateEvent t) {
	        	minimizeButtons();
	        	
	        	// TODO Process here.
	        	
	        	// Equivalent of pseudo-randomly allocating a correctness. This is only for testing while the speech recognition is being developed.
	        	// TODO Finish speech recognition and remove this.
	        	boolean isCorrect = _numToSay % 2 == 0;
	        	
	        	// If correct, hide the redo button and increase the number correct.
	        	if (isCorrect) {
	        		_numCorrect++;
	        		announceRight.setVisible(true);
	        		announceRight.setManaged(true);
	        		imageRight.setVisible(true);
	        		imageRight.setManaged(true);
	        		root.setStyle("-fx-background-color:#388E3C;");
	        	}
	        	else {
{'fraction_non_alphanumeric': 0.09988433013540178, 'fraction_numerical': 0.006259780907668232, 'mean_word_length': 3.448547215496368, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 9, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3472142', 'n_tokens_mistral': 4774, 'n_tokens_neox': 4382, 'n_words': 1213}