import 'dart:developer'; import 'package:flutter/foundation.dart'; import 'package:fluffychat/pangea/analytics/enums/construct_type_enum.dart'; import 'package:fluffychat/pangea/analytics/enums/morph_categories_enum.dart'; import 'package:fluffychat/pangea/common/utils/error_handler.dart'; import 'package:fluffychat/pangea/events/models/pangea_token_model.dart'; import 'package:fluffychat/pangea/toolbar/enums/activity_type_enum.dart'; import 'package:fluffychat/pangea/toolbar/models/message_activity_request.dart'; import 'package:fluffychat/pangea/toolbar/models/multiple_choice_activity_model.dart'; import 'package:fluffychat/pangea/toolbar/models/practice_activity_model.dart'; import 'package:fluffychat/widgets/matrix.dart'; typedef MorphActivitySequence = Map; typedef POSActivitySequence = List; class MorphActivityGenerator { // TODO we want to define this on the server and have the client pull it down final Map sequence = { "en": { "ADJ": ["AdvType", "Aspect"], "ADP": [], "ADV": [], "AUX": ["Tense", "Number"], "CCONJ": [], "DET": [], "NOUN": ["Number"], "NUM": [], "PRON": ["Number", "Person"], "SCONJ": [], "PUNCT": [], "VERB": ["Tense", "Aspect"], "X": [], }, }; /// Get the sequence of activities for a given part of speech /// The sequence is a list of morphological features that should be practiced /// in order for the given part of speech POSActivitySequence getSequence(String? langCode, String pos) { if (langCode == null || !sequence.containsKey(langCode)) { langCode = "en"; } final MorphActivitySequence morphActivitySequence = sequence[langCode]!; if (!morphActivitySequence.containsKey(pos)) { debugger(when: kDebugMode); ErrorHandler.logError( m: "No sequence defined", data: {"langCode": langCode, "pos": pos}, ); return []; } return morphActivitySequence[pos]!; } /// Generate a morphological activity for a given token and morphological feature Future get( MessageActivityRequest req, ) async { debugger(when: kDebugMode && req.targetTokens.length != 1); debugger(when: kDebugMode && req.targetMorphFeature == null); final PangeaToken token = req.targetTokens.first; final String morphFeature = req.targetMorphFeature!; final String? morphTag = token.getMorphTag(morphFeature); if (morphTag == null) { debugger(when: kDebugMode); throw "No morph tag found for morph feature"; } final List distractors = token.morphActivityDistractors(morphFeature, morphTag); return MessageActivityResponse( activity: PracticeActivityModel( tgtConstructs: [ ConstructIdentifier( lemma: morphTag, type: ConstructTypeEnum.morph, category: morphFeature, ), ], targetTokens: req.targetTokens, langCode: req.userL2, activityType: ActivityTypeEnum.morphId, content: ActivityContent( question: getMorphologicalCategoryCopy( morphFeature, MatrixState.pangeaController.matrixState.context, ) ?? morphFeature, choices: distractors + [morphTag], answers: [morphTag], spanDisplayDetails: null, ), ), ); } }