/** @module controls */
const {ipcRenderer} = require('electron');
const {npages, text} = require('./readings.js');
document.activeElement.blur();
var before_word = document.getElementById('before-word');
var word = document.getElementById('word');
var after_word = document.getElementById('after-word');
var bPlay = document.getElementById('btn-play');
var label_rate = document.getElementById('rate-value');
var label_page = document.getElementById('page-index');
var range_bar = document.getElementById('range-bar');
var data = {index: 0, text: text, rate: 180};
/**
* Creates a new PlayPauseWorker.
* @class
*/
class PlayPauseWorker {
/**
* @constructs PlayPauseWorker
* @param {string} script To be run by the Worker
* @param {array} text List of words
* @param {int} rate Velocity of update for the words on the screen
* @param {array} npages List of word indexes corresponding to new pages
*/
constructor(script, text, rate, npages) {
this.script = script;
this.data = {index: 0, text: text, rate: rate, npages: npages};
this.w = undefined;
this.setText();
range_bar.step = 1;
range_bar.min = 1;
range_bar.max = this.data.npages.length - 1;
range_bar.value = 1;
}
/**
* Initiates the worker, either by defining it for the first time,
* or by terminating it, redefining it again.
* The first corresponds to the play state,
* The second, to the restart state.
* If @param restart is false, and on a playing state,
* the worker is set on a pause state
* @param restart If true, it restarts the worker, otherwise, it terminates it
*/
initWorker = function(restart) {
if (this.w == undefined) {
this.w = new Worker(this.script);
this.onmessage();
this.postMessage();
}
else {
this.terminate();
if (restart)
this.initWorker(false);
else
range_bar.style = "pointer-events: auto;";
}
};
/**
* Sends the message with the data to the module called by the worker
* @fires message
*/
postMessage = function() {
range_bar.style = "pointer-events: none;";
this.w.postMessage(this.data);
};
/**
* Terminates the worker, setting it on a pause state
*/
terminate = function() {
bPlay.textContent = "l>";
if (this.w != undefined)
this.w.terminate();
this.w = undefined;
};
/**
* Sets the listener for receiving messages from the module called by the worker
* The listener @callback this.w.onmessage is responsible for updating the ui
* with the new words, and also the current index.
* @event message
*/
onmessage = function() {
let currWorker = this;
this.w.onmessage = function(event) {
bPlay.textContent = "ll";
before_word.textContent = event.data.before_word;
after_word.textContent = event.data.after_word;
word.textContent = event.data.word;
currWorker.setIndex(event.data.index - 1,false);
if (currWorker.getIndex() == currWorker.getTextLength() - 1) {
bPlay.textContent = "l>";
}
}
};
/**
* @returns The text length
*/
getTextLength = function() {
return this.data.text.length;
}
/**
* Sets the current page index based on the @param index
* @param index The word index to calculate the current page index
*/
setPageIndex = function(index) {
var elem = this.data.npages.find( function(val) {
if (index > 0)
return val > index - 1;
return val > index;
});
if (elem > -1) {
label_page.textContent = "Page: " + (this.data.npages.indexOf(elem));
range_bar.value = (this.data.npages.indexOf(elem));
}
}
/**
* Sets the current page index
* @param pageIndex The new current page index to be set
*/
setPage = function(pageindex) {
label_page.textContent = "Page: " + (pageindex);
var index = this.data.npages[pageindex - 1] + 1;
if (this.data.text[index] != undefined && index > 1)
this.setIndex(index,false);
else
this.setIndex(index - 1,false);
this.setText();
}
/**
* @returns The current page index
*/
getPageIndex = function() {
return range_bar.value;
}
/**
* Sets the current word index
* @param index The new index to be set
*/
setIndex = function(index) {
this.data.index = index;
this.setPageIndex(index);
}
/**
* @returns The current word index
*/
getIndex = function() {
return this.data.index;
}
/**
* Sets the next word index
*/
increaseIndex = function() {
this.setIndex(this.data.index + 1,false);
}
/**
* Sets the previous word index
*/
decreaseIndex = function() {
this.setIndex(this.data.index - 1,false);
}
/**
* Sets the current rate
* @param index The new rate to be set
*/
setRate = function(rate) {
this.data.rate = rate;
if (this.w != undefined)
this.postMessage();
}
/**
* @returns The current rate
*/
getRate = function() {
return this.data.rate;
}
/**
* Sets the next rate, increasing the current one by 10
*/
increaseRate = function() {
if (this.data.rate > 10) {
this.data.rate -= 10;
label_rate.textContent = "Rate: " + playPauseWorker.getRate();
if (this.w != undefined)
this.postMessage();
}
}
/**
* Sets the previous rate, decreasing the current one by 10
*/
decreaseRate = function() {
if (this.data.rate < 300) {
this.data.rate += 10;
label_rate.textContent = "Rate: " + playPauseWorker.getRate();
if (this.w != undefined)
this.postMessage();
}
}
/**
* Sets the words on the screen
*/
setText = function() {
var i = this.data.index
if (i > 0)
before_word.textContent = this.data.text[i - 1];
else
before_word.textContent = "";
word.textContent = this.data.text[i];
if (i < this.getTextLength() - 1)
after_word.textContent = this.data.text[i + 1];
else
after_word.textContent = "";
}
/**
* @returns true if on Pause, false otherwise
*/
onPause = function() {
return bPlay.textContent == "l>";
}
}
let playPauseWorker = new PlayPauseWorker("play-pause.js",text,180,npages);
/**
* Called when play button is pressed, playing it or pausing the reader
* @event button-play
*/
function buttonPlay() {
var onbeginning = playPauseWorker.getIndex() == 0;
var onend = playPauseWorker.getIndex() == playPauseWorker.getTextLength() - 1;
if ( onbeginning || onend ) { // It means that text has not STARTed
playPauseWorker.setIndex(0);
playPauseWorker.initWorker(true);
}
else {
playPauseWorker.initWorker(false);
}
document.activeElement.blur();
}
/**
* Called when increment-rate button is pressed, incrementing the rate
* @event button-increment-rate
*/
function buttonIncRate() {
playPauseWorker.increaseRate();
document.activeElement.blur();
}
/**
* Called when decrement-rate button is pressed, decrementing the rate
* @event button-decrement-rate
*/
function buttonDecRate() {
playPauseWorker.decreaseRate();
document.activeElement.blur();
}
/**
* Called when next-word button is pressed, presenting the next words on the screen
* @event button-next-word
*/
function buttonNextWord() {
if (playPauseWorker.onPause()) {
if (playPauseWorker.getIndex() < playPauseWorker.getTextLength() - 1) {
playPauseWorker.increaseIndex();
}
else {
playPauseWorker.setIndex(0);
}
playPauseWorker.setText();
}
document.activeElement.blur();
}
/**
* Called when previous-word button is pressed, presenting the previous words on the screen
* @event button-previous-word
*/
function buttonPreviousWord() {
if (playPauseWorker.onPause()) {
if (playPauseWorker.getIndex() > 0) {
playPauseWorker.decreaseIndex();
}
else {
playPauseWorker.setIndex(playPauseWorker.getTextLength() - 1);
}
playPauseWorker.setText();
}
document.activeElement.blur();
}
/**
* Range Bar Listener
* @event oninput
*/
range_bar.oninput = function() {
if (playPauseWorker.onPause()) {
playPauseWorker.setPage(this.value);
}
document.activeElement.blur();
}
/**
* Keyboard Listener
* @event keyup
*/
document.addEventListener('keyup', (e) => {
if (e.key === " " || e.code == "Space")
buttonPlay();
});
/**
* Keyboard Listener
* @event keypress
*/
document.addEventListener('keypress', (e) => {
e.preventDefault();
if (e.key === "+")
buttonIncRate();
else if (e.key === "-")
buttonDecRate();
});
/**
* Keyboard Listener
* @event keydown
*/
document.onkeydown = function checkKey(e) {
e = e || window.event;
if (e.keyCode == '37') {
// left arrow
buttonPreviousWord();
}
else if (e.keyCode == '39') {
// right arrow
buttonNextWord();
}
};
/**
* @fires resize
*/
function resize() {
ipcRenderer.send('resize');
}
/**
* @fires main-menu
*/
function goToMainMenu() {
ipcRenderer.send('main-menu');
}