File indexing completed on 2024-04-28 15:07:54

0001 /* GCompris - letter-in-word.js
0002  *
0003  * SPDX-FileCopyrightText: 2014 Holger Kaelberer
0004  *               2016 Akshat Tandon
0005  *               2020 Timothée Giet
0006  *
0007  * Authors:
0008  *   Holger Kaelberer <holger.k@elberer.de> (Qt Quick port of click-on-letter)
0009  *   Akshat Tandon    <akshat.tandon@research.iiit.ac.in>
0010  *   Timothée Giet <animtim@gmail.com>
0011  *
0012  *   SPDX-License-Identifier: GPL-3.0-or-later
0013  */
0014 
0015 .pragma library
0016 .import QtQuick 2.12 as Quick
0017 .import GCompris 1.0 as GCompris //for ApplicationInfo
0018 .import "qrc:/gcompris/src/core/core.js" as Core
0019 .import "qrc:/gcompris/src/activities/lang/lang_api.js" as Lang
0020 
0021 var resUrl = "qrc:/gcompris/src/activities/braille_fun/resource/"
0022 
0023 var levels;
0024 var maxLevel;
0025 var currentLetter;
0026 var maxSubLevel;
0027 var questions;
0028 var words;
0029 var items;
0030 var dataset = null;
0031 var frequency;
0032 var locale;
0033 
0034 function start(_items) {
0035     items = _items;
0036     // register the voices for the locale
0037     locale = GCompris.ApplicationInfo.getVoicesLocale(items.locale);
0038     GCompris.DownloadManager.updateResource(GCompris.GCompris.VOICES, {"locale": locale})
0039     loadDataset();
0040     levels = Lang.getAllLessons(dataset);
0041     items.score.currentSubLevel = 0;
0042     maxLevel = levels.length;
0043     items.currentLevel = Core.getInitialLevel(maxLevel);
0044     initLevel();
0045 }
0046 
0047 function loadDataset() {
0048     var resourceUrl = "qrc:/gcompris/src/activities/lang/resource/";
0049     var data = Lang.loadDataset(items.parser, resourceUrl, locale);
0050     dataset = data["dataset"];
0051     items.background.englishFallback = data["englishFallback"];
0052     if(!items.background.englishFallback)
0053         Core.checkForVoices(items.activityPage);
0054 }
0055 
0056 function stop() {
0057     items.animateX.stop()
0058 }
0059 
0060 function shuffleString(s) {
0061     var a = s;
0062     var n = a.length;
0063 
0064     for(var i = n-1; i > 0; --i) {
0065         var j = Math.floor(Math.random() * (i + 1));
0066         var tmp = a[i];
0067         a[i] = a[j];
0068         a[j] = tmp;
0069     }
0070     return a.join("");
0071 }
0072 
0073 function initLevel() {
0074     items.errorRectangle.resetState();
0075     if (items.score.currentSubLevel == 0) {
0076         var level = levels[items.currentLevel];
0077         words = Lang.getLessonWords(dataset, level);
0078         Core.shuffle(words);
0079         var limit = Math.min(items.currentMode, words.length);
0080         words = words.slice(0, limit);
0081         frequency = calculateFrequency();
0082         var tempQuestions = generateQuestions();
0083         maxSubLevel = tempQuestions.length;
0084         items.score.numberOfSubLevels = maxSubLevel;
0085         questions = shuffleString(tempQuestions);
0086         items.wordsModel.clear();
0087         for (var i = 0; i < words.length; i++) {
0088             items.wordsModel.append({
0089                                         "spelling": words[i].translatedTxt,
0090                                         "imgurl": words[i].image,
0091                                         "voice": words[i].voice,
0092                                         "selected": false
0093                                     });
0094         }
0095     }
0096 
0097     for(var i = 0; i < words.length; i++) {
0098         items.wordsModel.setProperty(i, "selected", false);
0099     }
0100 
0101     currentLetter = questions[items.score.currentSubLevel];
0102     items.question = currentLetter;
0103     items.animateX.restart();
0104 
0105     if(items.currentLetterCase == Quick.Font.MixedCase) {
0106         items.questionItem.font.capitalization = (Math.floor(Math.random() * 2) < 1) ? Quick.Font.AllLowercase : Quick.Font.AllUppercase
0107     }
0108     else {
0109         items.questionItem.font.capitalization = items.currentLetterCase
0110     }
0111 
0112     if (GCompris.ApplicationSettings.isAudioVoicesEnabled &&
0113             GCompris.DownloadManager.haveLocalResource(
0114                 GCompris.DownloadManager.getVoicesResourceForLocale(locale))) {
0115         items.audioVoices.silence(100)
0116         playLetter(currentLetter)
0117     }
0118     items.buttonsBlocked = false;
0119 }
0120 
0121 function calculateFrequency() {
0122     var freq = [];
0123     for(var i = 0; i < words.length; i++) {
0124         var currentWord = words[i].translatedTxt;
0125         for(var j = 0; j < currentWord.length; j++) {
0126             var character = currentWord.charAt(j);
0127             //consider the character if it is not a space
0128             if(character != " ") {
0129                 if(freq[character]) {
0130                     freq[character]++;
0131                 }
0132                 else {
0133                     freq[character] = 1;
0134                 }
0135             }
0136         }
0137     }
0138     return freq;
0139 }
0140 
0141 function generateQuestions() {
0142     var freqArr = [];
0143     var ques = [];
0144 
0145     for(var character in frequency) {
0146         freqArr.push([character, frequency[character]]);
0147     }
0148 
0149     freqArr.sort(function(a, b) {return b[1] - a[1]});
0150 
0151     var limit = Math.min(10, freqArr.length);
0152     for(var i = 0; i < limit; i++) {
0153         ques.push(freqArr[i][0])
0154     }
0155     return ques;
0156 }
0157 
0158 function playLetter(letter) {
0159     items.audioVoices.append(GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/"+locale+"/alphabet/"
0160                                                                        + Core.getSoundFilenamForChar(letter)))
0161 }
0162 
0163 function nextLevel() {
0164     items.score.stopWinAnimation();
0165     items.audioVoices.clearQueue()
0166     items.currentLevel = Core.getNextLevel(items.currentLevel, maxLevel);
0167     items.score.currentSubLevel = 0;
0168     initLevel();
0169 }
0170 
0171 function previousLevel() {
0172     items.score.stopWinAnimation();
0173     items.audioVoices.clearQueue()
0174     items.currentLevel = Core.getPreviousLevel(items.currentLevel, maxLevel);
0175     items.score.currentSubLevel = 0;
0176     initLevel();
0177 }
0178 
0179 function nextSubLevel() {
0180     if( items.score.currentSubLevel >= maxSubLevel) {
0181         items.bonus.good("flower");
0182     } else {
0183         initLevel();
0184     }
0185 }
0186 
0187 function checkAnswer() {
0188     items.buttonsBlocked = true
0189     var allCorrectSelected = true
0190     var modelEntry;
0191     var letterIndex;
0192     for(var i = 0; i < words.length; i++) {
0193         modelEntry = items.wordsModel.get(i);
0194         letterIndex = modelEntry.spelling.indexOf(currentLetter);
0195         if(letterIndex != -1 && modelEntry.selected == false) {
0196             allCorrectSelected = false;
0197             break;
0198         }
0199         if(letterIndex == -1 && modelEntry.selected == true) {
0200             allCorrectSelected = false;
0201             break;
0202         }
0203     }
0204     if(allCorrectSelected == true) {
0205         items.score.currentSubLevel++;
0206         items.score.playWinAnimation();
0207         items.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/completetask.wav");
0208     }
0209     else {
0210         items.errorRectangle.startAnimation();
0211         items.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/crash.wav");
0212    }
0213 }
0214 
0215 function checkWord(index) {
0216     var itemStatus = !items.wordsModel.get(index).selected;
0217     items.wordsModel.setProperty(index, "selected", itemStatus);
0218     return itemStatus;
0219 }