"use strict"; angular.module("vocabulary") .service("lessonService", ["$q", "userLessonApi", "wordApi", "premadeService", "premadeApi", "MessageBox", "messageHandler", "categoryApi", "categoryService", "topicService", "lessonTypeService", "accessRestriction", "lessonWordOrderApi", function ($q, userLessonApi, wordApi, premadeService, premadeApi, MessageBox, messageHandler, categoryApi, categoryService, topicService, lessonTypeService, accessRestriction, lessonWordOrderApi) { var MAX_WORD_COUNT = 12; var NEW_LESSON_STASH_KEY = "NEW_LESSON"; var memory = {}; var wordOrderId = null; var finalBatchEnteredWords = null; // todo - this isn't the correct way to initialize this object var lessonData = new LessonData(); return { saveLesson: saveLesson, updateExistingLessonOptions: updateExistingLessonOptions, validateLesson: validateLesson, initializeLessonData: initializeLessonData, initializeLessonDataFromUserLessonCopy: initializeLessonDataFromUserLessonCopy, initializeLessonFromPremadeId: initializeLessonFromPremadeId, initializeNewLessonFromPremadeOrigin: initializeNewLessonFromPremadeOrigin, userLessonAlreadyInitialized: userLessonAlreadyInitialized, copyLesson: copyLesson, deleteLesson: deleteLesson, moveLesson: moveLesson, setTypeSize: setTypeSize, getTypeSize: getTypeSize, getLessonId: getLessonId, getAvailableLessonOptions: getAvailableLessonOptions, setDefaultLessonOptions: setDefaultLessonOptions, setSelectedFiles: setSelectedFiles, getSelectedFiles: getSelectedFiles, setSelectedWwActivities: setSelectedWwActivities, getSelectedWwActivities: getSelectedWwActivities, toggleChosenWord: toggleChosenWord, chooseWordList: chooseWordList, discardWord: discardWord, getChosenWords: getChosenWords, wordIsChosen: wordIsChosen, replaceWordIfChosen: replaceWordIfChosen, countChosenWords: countChosenWords, chooseCategory: chooseCategory, getChosenCategoryId: getChosenCategoryId, categoryIsChosen: categoryIsChosen, getLessonName: getLessonName, setLessonName: setLessonName, getLessonData: getLessonData, getImagePath: getImagePath, setImagePath: setImagePath, getPremadeId: getPremadeId, setPremadeId: setPremadeId, stash: stash, unstash: unstash, clearStash: clearStash, getNewLessonStashKey: getNewLessonStashKey, doesLessonHaveResourceWords: doesLessonHaveResourceWords, getResourceWordData: getResourceWordData, isLessonCMSPremade: isLessonCMSPremade, isLessonVazEditorPremade: isLessonVazEditorPremade, setWordOrderId: setWordOrderId, clearWordOrderId: clearWordOrderId, getBatchEnteredWords: getBatchEnteredWords, setBatchEnteredWords: setBatchEnteredWords, getFinalBatchEnteredWords: getFinalBatchEnteredWords }; function getBatchEnteredWords(wordList){ return wordApi.getBatchEnteredWords(wordList) .then(function (returnedList) { setBatchEnteredWords(returnedList); return returnedList; }); } function setBatchEnteredWords(wordList){ finalBatchEnteredWords = wordList; } function getFinalBatchEnteredWords(){ return finalBatchEnteredWords; } function setWordOrderId(orderId) { wordOrderId = orderId; } function clearWordOrderId() { setWordOrderId(null); } function getLessonData(){ return lessonData; } function setTypeSize(size) { lessonData.typeSize = size; } function getTypeSize() { return lessonData.typeSize; } function setSelectedFiles(files) { lessonData.files = files; } function getSelectedFiles() { return lessonData.files; } function getLessonId() { return lessonData.id; } function setLessonType(type) { lessonData.type = type; } function isLessonUserDefined() { return lessonData.type === lessonTypeService.USER_DEFINED; } function doesLessonHaveResourceWords() { return premadeService.getPremadeTypesWithResourceWords().indexOf(lessonData.type) >= 0; } function isLessonCMSPremade() { return premadeService.getCMSPremadeTypes().indexOf(lessonData.type) >= 0; } function isLessonVazEditorPremade() { return !isLessonCMSPremade() && !isLessonUserDefined(); } function getAvailableLessonOptions() { var options = {}; return wordApi.generateWordWorkTypes(lessonData.words) .then(function (wwActivities) { options.wwActivities = wwActivities; options.files = ["lessonplan", "assessment"]; if(wwActivities.size() > 0) { options.files.push("worksheets") } if(chosenWordsHaveImages()) { options.files.push("photocard"); } return options; }); } function chosenWordsHaveImages() { var hasImages = false; lessonData.words.forEach(function(word) { if(word.imageName !== null) { hasImages = true; } }); return hasImages; } function setSelectedWwActivities(wwActivities) { lessonData.wwActivities = wwActivities; } function getSelectedWwActivities() { return lessonData.wwActivities; } function toggleChosenWord(word) { return accessRestriction.enforceRestriction({'word':word}) .then(function () { if (wordIsChosen(word)) { discardWord(word); } else if (maxWordsChosen()) { return showMaxWordsMessage(); } else { lessonData.words.push(word); } }).catch(function(e) {}); } function showMaxWordsMessage() { return MessageBox.show({ message: "Word limit reached. You must remove a word from your list in order to add another.", responses: [{action: true, label: 'OK'}] }); } function chooseWordList(words) { if (words.size() <= 12) { words.forEach(function (word) { lessonData.words.push(word); }); } } function getChosenWords() { return nullFillWordList(lessonData.words); } function maxWordsChosen() { return lessonData.words.size() >= MAX_WORD_COUNT; } function nullFillWordList(list) { var listCopy = list.clone(); while(listCopy.size() < MAX_WORD_COUNT) { listCopy.push(null); } return listCopy; } function wordIsChosen(word) { return lessonData.words.filter(function(item) { return areWordsTheSame(item, word); }).length !== 0; } function replaceWordIfChosen(word) { lessonData.words = lessonData.words.map(function(item) { if(item.wordId == word.wordId) { return word; } return item; }); } function countChosenWords() { return lessonData.words.size(); } function discardWord(word) { lessonData.words = lessonData.words.filter(function (item) { return !areWordsTheSame(item, word); }); } function areWordsTheSame(word1, word2) { return word1.wordId === word2.wordId && isMemberWord(word1) === isMemberWord(word2); } function isMemberWord(word) { return !word.hasOwnProperty('topicId'); } function chooseCategory(category) { lessonData.categoryId = category.categoryId; } function getChosenCategoryId() { return lessonData.categoryId; } function categoryIsChosen() { return lessonData.categoryId !== undefined; } function getLessonName() { return lessonData.name; } function setLessonName(name) { lessonData.name = name; } function saveLessonData() { return userLessonApi.create(lessonData) .then(saveWordOrderIdIfExists) .then(function (lessonId) { lessonData.id = lessonId; messageHandler.publishSuccess("Your lesson has been saved"); return lessonId; }) .catch(function () { messageHandler.publishError("There was a problem processing your request"); }); } function updateLessonData() { return userLessonApi.update(lessonData) .then(saveWordOrderIdIfExists) .then(function (lessonId) { messageHandler.publishSuccess("Your lesson has been updated"); return lessonId; }) .catch(function () { messageHandler.publishError("There was a problem processing your request"); }); } function saveWordOrderIdIfExists(lessonId) { if(wordOrderId) { return lessonWordOrderApi.setLessonWordOrder(lessonId, wordOrderId) .then(function() { return lessonId; }); } return $q.resolve(lessonId); } function saveLesson() { switch (lessonData.type) { case lessonTypeService.RAZ_PREMADE: case lessonTypeService.SAZ_PREMADE: case lessonTypeService.OTHER_PREMADE: return saveLessonFromPremade(); case lessonTypeService.USER_DEFINED: return saveUserLesson(); case lessonTypeService.TOPIC: default: return saveNewLesson(); } } function saveNewLesson() { return accessRestriction.enforceRestriction() .then(validateLesson) .then(validateNewLessonName) .then(setDefaultLessonOptions) .then(saveLessonData); } function saveLessonFromPremade() { return accessRestriction.enforceRestriction() .then(validateLesson) .then(validateNewLessonName) .then(reEvaluateLessonOptions) .then(saveLessonData); } function saveUserLesson() { if (lessonData.id) { return updateExistingLesson(); } return saveNewLesson(); } function updateExistingLesson() { return validateLesson() .then(validateNewLessonName) .then(reEvaluateLessonOptions) .then(updateLessonData); } function updateExistingLessonOptions(){ if(!isLessonUserDefined()) { return cachePremadeLessonData(); } else { return reEvaluateLessonOptions() .then(updateLessonData); } } function cachePremadeLessonData() { return premadeApi.cachePremadeLessonData(lessonData) .catch(function () { messageHandler.publishError("There was a problem processing your request"); }); } function validateLesson() { var lessonNameRegex = /^[-.a-zA-Z\d ?!<>,'/:()]+$/; var errors = {}; if(lessonData.words.size() <= 0) { errors.words = true; } if(!lessonData.name || lessonData.name.length <= 0 || lessonData.name.length > 75 || !lessonNameRegex.test(lessonData.name)) { errors.lessonName = true; } if (Object.keys(errors).size() > 0) { return $q.reject(errors); } return $q.resolve(); } function validateNewLessonName() { var errors = {}; return userLessonApi.isLessonNameUniqueInCategory(lessonData) .then(function (newLessonNameIsValid) { if (!newLessonNameIsValid) { errors.lessonNameExists = true; return $q.reject(errors); } }); } function reEvaluateLessonOptions() { return getAvailableLessonOptions() .then(function (options) { setSelectedFiles(intersectOptions(getSelectedFiles(), options.files)); setSelectedWwActivities(intersectOptions(getSelectedWwActivities(), options.wwActivities)); }); } function intersectOptions(selected, available) { return selected.filter(function (elem) { return available.indexOf(elem) !== -1; }); } function stash(key) { memory[key] = angular.copy(lessonData); } function unstash(key) { if(memory.hasOwnProperty(key)) { lessonData = angular.copy(memory[key]); return true; } else { return false; } } function clearStash(key) { if(key) { delete memory[key]; } else { memory = {}; } } function getNewLessonStashKey() { return NEW_LESSON_STASH_KEY; } function initializeLessonData(lessonId) { if(lessonId) { return userLessonApi.getLesson(lessonId) .then(function (lesson) { lessonData = new LessonData( lesson.lessonName, lesson.typeSize, lesson.words, lesson.selectedFileTypes, lesson.categoryId, lesson.selectedWwActivities, lesson.lessonId, lesson.lessonType, lesson.categoryName ); }); } initializeDefaultLessonData(); return $q.resolve(); } function initializeLessonDataFromUserLessonCopy(lessonId) { return $q.all([ userLessonApi.getLesson(lessonId), userLessonApi.getNameForLessonCopy(lessonId) ]) .then(function(response){ var lesson = response[0]; var lessonName = response[1]; lessonData = new LessonData( lessonName, lesson.typeSize, lesson.words, lesson.selectedFileTypes, 0, lesson.selectedWwActivities, null, lesson.lessonType, "" ) }); } function userLessonAlreadyInitialized(lessonId) { return parseInt(lessonId) === getLessonId(); } function initializeLessonFromPremadeId(lessonId, lessonType){ return premadeService.getPremadeLessonData(lessonId, lessonType) .then(function (premadeData) { lessonData = new LessonData( premadeData.lessonName, parseInt(premadeData.typeSize, 10), premadeData.words, premadeData.selectedFileTypes, 0, premadeData.selectedWwActivities, null, premadeData.lessonType, "" ); setPremadeId(premadeData.lessonId); if(premadeData.imagePath) { setImagePath(premadeData.imagePath); } if(premadeData.topicId){ setResourceTopicId(premadeData.topicId); } }); } function initializeLessonFromTopicId(topicId) { return topicService.getTopicData(topicId) .then(function (topicData) { lessonData = new LessonData(); setLessonName(topicData.title); setLessonType(lessonTypeService.TOPIC); setPremadeId(topicData.id); chooseWordList(topicData.words); setImagePath(topicData.imagePath); }); } function initializeNewLessonFromPremadeOrigin(origin, id) { switch (origin) { case lessonTypeService.RAZ_PREMADE: case lessonTypeService.SAZ_PREMADE: case lessonTypeService.OTHER_PREMADE: return initializeLessonFromPremadeId(id, origin); case lessonTypeService.TOPIC: return initializeLessonFromTopicId(id); } } function initializeDefaultLessonData() { lessonData = new LessonData(); } function setDefaultLessonOptions() { return getAvailableLessonOptions() .then(function (options) { setTypeSize(2); setSelectedFiles(deriveDefaultFiles(options.files)); }); } function deriveDefaultFiles(availableFiles) { var defaultFiles = []; defaultFiles.push("worksheets"); defaultFiles.push("assessment"); var imageWords = lessonData.words.filter(function (word) { return word.imageName !== null; }); if (availableFiles.indexOf("photocard") >= 0 && imageWords.size() >= 3) { defaultFiles.push("photocard"); } return defaultFiles; } function copyLesson(lessonId) { return userLessonApi.getNameForLessonCopy(lessonId) .then(function (name) { setLessonName(name); return saveLessonData(); }) .catch(function (error) { messageHandler.publishError("There was a problem processing your request: " + error); return false; }); } function deleteLesson(lessonId){ return userLessonApi.delete(lessonId) .then(function(lessonsAffected){ return lessonsAffected; }); } function moveLesson(){ return userLessonApi.updateLessonCategory(this.getLessonId(),this.getChosenCategoryId()) .catch(function(error){ messageHandler.publishError("There was a problem processing your request: " + error); return false; }); } function getImagePath() { return lessonData.imagePath; } function setImagePath(imagePath) { lessonData.imagePath = imagePath; } function getPremadeId() { return lessonData.premadeId; } function setPremadeId(premadeId) { lessonData.premadeId = premadeId; } function getResourceTopicId(){ return lessonData.topicId; } function setResourceTopicId(premadeTopicId){ lessonData.topicId = premadeTopicId; } function getResourceWordData(origin, id) { switch (origin) { case 'raz_premade': case 'saz_premade': return topicService.getWordsForTopic(getResourceTopicId()) .then(function(result){ return {storyCritical: getLessonData().words, topicWords: result.words}; }); case 'topic': return topicService.getWordsForTopic(id) .then(function (result) { return {storyCritical: [], topicWords: result.words}; }); } } function LessonData(name, typeSize, words, files, categoryId, wwactivities, lessonId, lessonType, categoryName) { this.words = words ? words : []; this.name = name ? name : ""; this.typeSize = typeSize; this.files = files ? files : []; this.categoryId = categoryId ? categoryId : 0; this.wwActivities = wwactivities ? wwactivities : []; this.id = lessonId ? lessonId : null; this.type = lessonType; this.categoryName = categoryName ? categoryName : ""; this.imagePath = null; this.premadeId = null; this.topicId = null; } }]);