File indexing completed on 2024-04-21 14:43:30

0001 /* GCompris - categorization.js
0002     *
0003     * SPDX-FileCopyrightText: 2016 Divyam Madaan <divyam3897@gmail.com>
0004     *
0005     * Authors:
0006     *   Divyam Madaan <divyam3897@gmail.com>
0007     *
0008     *   SPDX-License-Identifier: GPL-3.0-or-later
0009     */
0010 .pragma library
0011 .import QtQuick 2.12 as Quick
0012 .import GCompris 1.0 as GCompris
0013 .import "qrc:/gcompris/src/core/core.js" as Core
0014 
0015 var categoryModelIndex = 0;
0016 var currentSubLevel = 0;
0017 var items
0018 var lessons
0019 var categories
0020 var images
0021 var numberOfLevel
0022 var index
0023 var imagesData = []
0024 var categoriesData = []
0025 var expertCategories = []
0026 var answerTable = {}
0027 var totalImages
0028 var fileName = ":/gcompris/data/words-webp/animals/camel.webp"
0029 
0030 function init(items_) {
0031     items = items_
0032     items.menuModel.clear()
0033     currentSubLevel = 0
0034 }
0035 
0036 function start() {
0037     categoriesData = []
0038     items.categoryReview.stop()
0039 
0040     var isEmbeddedMode = items.file.exists(fileName) ? true : false
0041 
0042     items.categoriesFallback = !isEmbeddedMode
0043 
0044     var categoriesFilename;
0045     var categoryDataset = items.categoryReview.categoryDataset
0046     var categoryLists = items.categories
0047     for(var i = 0; i < categoryLists.length; i++) {
0048         categoriesFilename = categoryLists[i][0]
0049         categoryDataset.source = categoriesFilename
0050         if(isEmbeddedMode || categoryDataset.item.isEmbedded) {
0051             categoriesData.push(categoryDataset.item)
0052         }
0053     }
0054     lessons = getAllLessons(categoriesData)
0055     categories = getCategoryModel(categoriesData)
0056     addPropertiesToCategories(categories)
0057     items.menuModel.append(categories)
0058     savedPropertiesToCategories(items.dialogActivityConfig.activityData)
0059     sortByFavorites()
0060     items.menuScreen.start()
0061 }
0062 
0063 // Inserts specific properties to the categories
0064 function addPropertiesToCategories(categories) {
0065     for (var i = 0; i < categories.length; i++) {
0066         categories[i]['name'] = categories[i].name
0067         categories[i]['image'] = categories[i].image
0068         categories[i]['favorite'] = false
0069         categories[i]['categoryIndex'] = i
0070     }
0071 }
0072 
0073 // Return all the properties we have to save
0074 function categoriesToSavedProperties() {
0075     if(!items)
0076         return;
0077     var props = {}
0078     for(var i = 0; i < items.menuModel.count; i++) {
0079         var category = items.menuModel.get(i)
0080         props[category.name] = {
0081             'favorite': category['favorite']
0082         }
0083     }
0084     return props
0085 }
0086 
0087 // Update the categories based on a previous saving
0088 function savedPropertiesToCategories(dataToSave) {
0089     var props = dataToSave["data"]
0090     for(var i = 0; i < items.menuModel.count; i++) {
0091         var category = items.menuModel.get(i)
0092         var categoryname = category.name
0093         if(props && props[category.name]) {
0094             category['favorite'] = props[category.name].favorite
0095         }
0096         else {
0097             category['favorite'] = false
0098         }
0099     }
0100 }
0101 
0102 function sortByFavorites() {
0103     for(var i = 0; i < items.menuModel.count; i++) {
0104         if(items.menuModel.get(i)['favorite']) {
0105             items.menuModel.move(i, 0, 1);
0106         }
0107     }
0108 }
0109 
0110 function launchMenuScreen() {
0111     items.categoryReview.stop()
0112     items.menuScreen.start()
0113 }
0114 
0115 function startCategory() {
0116     items.categoryReview.start()
0117     items.menuScreen.stop()
0118     items.currentLevel = 0
0119     initLevel()
0120 }
0121 
0122 function storeCategoriesLevels(index_) {
0123     index = index_
0124     items.currentLevel = 0
0125     numberOfLevel = 0
0126     initLevel()
0127 }
0128 
0129 function initLevel() {
0130     items.categoryReview.score.currentSubLevel = 0
0131     items.instructionsVisible = true
0132     getCategoryLevels(index);
0133     numberOfLevel = items.details.length;
0134     items.categoryReview.leftZone.clear();
0135     items.categoryReview.rightZone.clear();
0136     items.categoryReview.start();
0137     items.menuScreen.stop()
0138 }
0139 
0140 function nextLevel() {
0141     items.currentLevel = Core.getNextLevel(items.currentLevel, numberOfLevel);
0142     items.categoryReview.score.currentSubLevel = 0
0143     initLevel(index);
0144     getCategoryLevels();
0145 }
0146 
0147 function previousLevel() {
0148     items.currentLevel = Core.getPreviousLevel(items.currentLevel, numberOfLevel);
0149     initLevel(index);
0150     getCategoryLevels();
0151 }
0152 
0153 // Checks if all the items are dragged and dropped in the correct or incorrect area.
0154 function allPlaced() {
0155     items.categoryReview.score.currentSubLevel = 0;
0156     for(var i = 0 ; i < items.categoryReview.leftZone.count; ++i) {
0157         for(var answer in answerTable) {
0158             var droppedZoneItem = items.categoryReview.leftZone.get(i)
0159             if(answer === droppedZoneItem.name &&
0160                     ((droppedZoneItem.droppedZone === "right" && answerTable[answer])
0161                      || (droppedZoneItem.droppedZone === "left" && !answerTable[answer])))
0162                 items.categoryReview.score.currentSubLevel ++
0163         }
0164     }
0165     for(var i = 0 ; i < items.categoryReview.rightZone.count; ++i) {
0166         for(var answer in answerTable) {
0167             var droppedZoneItem = items.categoryReview.rightZone.get(i)
0168             if(answer === droppedZoneItem.name &&
0169                     ((droppedZoneItem.droppedZone === "right" && answerTable[answer])
0170                      || (droppedZoneItem.droppedZone === "left" && !answerTable[answer])))
0171                 items.categoryReview.score.currentSubLevel ++
0172         }
0173     }
0174     if(items.categoryReview.score.currentSubLevel === totalImages)
0175         items.bonus.good("flower")
0176     else
0177         items.bonus.bad("flower", items.bonus.checkAnswer)
0178 }
0179 
0180 // Save properties to lessons
0181 function getCategoryLevels() {
0182     var randomGood = 0;
0183     var randomBad = 0;
0184     items.categoryReview.middleZone.clear()
0185     /* If easy or medium mode is selected, store the details of levels of category of that respective index in items.details. */
0186     if(items.mode !== "expert") {
0187         items.details = lessons[index].map(function(ele) {
0188             return { "instructions": ele.instructions, "image": ele.image,
0189                 "numberOfGood": ele.maxNumberOfGood, "numberofBad": ele.maxNumberOfBad,
0190                 "categoryImages": ele.levelImages ,"good": ele.good,
0191                 "bad": ele.bad ,"prefix": ele.prefix }
0192         });
0193     }
0194     // If expert mode is selected, select a random level (selectedLevel) from a random category (selectedCategory)
0195     else if(items.mode === "expert") {
0196         var selectedCategory = Math.floor(Math.random() * expertCategories.length)
0197         var selectedLevel = []
0198         selectedLevel[0] = expertCategories[selectedCategory][Math.floor(Math.random() * expertCategories[selectedCategory].length)]
0199         items.details = selectedLevel.map(function(ele) {
0200             return { "instructions": ele.instructions,  "image": ele.image,
0201                 "numberOfGood": ele.maxNumberOfGood, "numberofBad": ele.maxNumberOfBad,
0202                 "categoryImages": ele.levelImages ,"good": ele.good,
0203                 "bad": ele.bad, "prefix": ele.prefix }
0204         });
0205     }
0206 
0207     var imagesPrefix = items.details[items.currentLevel].prefix
0208     // Good set of images
0209     var goodImages = items.details[items.currentLevel].good
0210     var numberOfGood = Math.min(goodImages.length,items.details[items.currentLevel].numberOfGood);
0211     var goodZoneImages = goodImages.map(function(obj) {
0212         obj = imagesPrefix + obj
0213         return { "name": obj, "isRight": true }
0214     });
0215     goodZoneImages = goodZoneImages.splice(0, numberOfGood);
0216 
0217     // Bad set of images
0218     var badImages = items.details[items.currentLevel].bad
0219     var badZoneImages = badImages.map(function(obj) {
0220         obj = imagesPrefix + obj
0221         return { "name": obj, "isRight": false }
0222     });
0223     var numberOfBad = Math.min(badImages.length,items.details[items.currentLevel].numberofBad);
0224     badZoneImages = badZoneImages.splice(0, numberOfBad);
0225 
0226     // Concat both set of images(good and bad) in allImages and store in middleZone model
0227     var allImages = goodZoneImages.concat(badZoneImages);
0228     Core.shuffle(allImages);
0229     for(var i = 0; i < allImages.length; i++) {
0230         answerTable[allImages[i].name] = allImages[i].isRight
0231         items.categoryReview.middleZone.append({"isRight": allImages[i].isRight,"name": allImages[i].name})
0232     }
0233     totalImages = allImages.length
0234     items.categoryReview.score.numberOfSubLevels = totalImages
0235 }
0236 
0237 // get categories details from the complete dataset
0238 function getCategoryModel(dataset) {
0239     var categories = []
0240     for (var c = 0; c < dataset.length; c++) {
0241         categories.push({
0242                             'name': dataset[c].levels[0].name,
0243                             'image': dataset[c].levels[0].image,
0244                             'index': c
0245                         })
0246     }
0247     return categories
0248 }
0249 
0250 // get all the content (levels) from the category in dataset
0251 function getAllLessons(dataset) {
0252     var lessons = []
0253     for(var c = 0; c < dataset.length; c++) {
0254         lessons.push(dataset[c].levels[0].content)
0255         if(dataset[c].allowExpertMode) {
0256             expertCategories.push(dataset[c].levels[0].content)
0257         }
0258     }
0259     return lessons
0260 }
0261 
0262 function setValues() {
0263     items.categoryReview.leftAreaContainsDrag = false
0264     items.categoryReview.rightAreaContainsDrag = false
0265 }
0266 
0267 function isDragInLeftArea(leftAreaRightBorderPos, elementRightPos) {
0268     if(elementRightPos <= leftAreaRightBorderPos)
0269         return true;
0270     else
0271         return false;
0272 }
0273 function isDragInRightArea(rightAreaLeftBorderPos, elementLeftPos) {
0274     if((rightAreaLeftBorderPos <= elementLeftPos))
0275         return true;
0276     else
0277         return false;
0278 }
0279 
0280 function dropControl(sourcePosition, destinationPosition, image, index) {
0281     var destinationZone = destinationPosition === "left" ? items.categoryReview.leftZone : destinationPosition === "right" ? items.categoryReview.rightZone : items.categoryReview.middleZone
0282     var sourceZone = sourcePosition === "left" ? items.categoryReview.leftZone : sourcePosition === "right" ? items.categoryReview.rightZone : items.categoryReview.middleZone
0283     destinationZone.append({"name": image, "droppedZone": destinationPosition})
0284     sourceZone.remove(index)
0285 }