"use strict"; angular.module("vocabulary") .service("topicService", ["$q", "topicApi", "wordApi", function ($q, topicApi, wordApi) { var topicMap = []; var topicTree = []; var premadeFiltersMap = new Map(); var LAZ_CONNECTIONS_TOPIC_ID = 629; var specialTopicDescriptions = { 1408: "The Dolch Sight Words list contains many of the most common written words in English. The Dolch Sight words were first published in 1936 and are still considered essential to early literacy.", 1409: "The Spache Words list contains words students commonly learn before completing grade three. The Spache Words are often used to determine text readability for primary grades.", 1415: "The Marzano Words list contains words students commonly use in academic reading and writing. The words were compiled by Marzano Research from several popular word lists and other sources.", 1427: "The Fry 1000 Words list contains many of the most common written words in English. The Fry 1000 Words were published in 1996 as an update to the Dolch Sight Words.", 1485: "The High-Frequency Words list contains many of the most common words in English. The words were compiled from several popular word lists, including Dolch and Fry.", 1703: "The Common Core Academic Vocabulary list contains words students are expected to use in academic reading and writing, according to the Common Core State Standards for English-language literacy." }; return { getTopicsWithoutLazConnections: getTopicsWithoutLazConnections, getTopicById: getTopicById, getWordsForTopic: getWordsForTopic, getRazTopicFilter: getRazTopicFilter, getEllTopicSummary : getEllTopicSummary, getTopicData: getTopicData, getSpecialTopicDescription: getSpecialTopicDescription }; function getSpecialTopicDescription(topicId) { return specialTopicDescriptions[topicId]; } function getEllTopicSummary(topicId){ return topicApi.getEllTopicSummary(topicId); } function getTopicData(topicId) { return topicApi.getTopicData(topicId); } function getRazTopicFilter(topicId){ if(premadeFiltersMap.has(topicId) === false) { return topicApi.premadeTopicFilter(topicId).then(function (data) { premadeFiltersMap.set(topicId, data); return premadeFiltersMap.get(topicId); }); }else{ return $q.resolve(premadeFiltersMap.get(topicId)); } } function getWordsForTopic(topicId, letter) { if (letter) { return wordApi.getWordsForTopicByLetter(topicId, letter); } return wordApi.getWordsForTopic(topicId); } function getTopicById(topicId) { return topicMap[topicId]; } function getTopics() { if(topicTree.size() > 0) { return $q.resolve(topicTree); } return initializeTopicData() .then(function () { return topicTree; }); } function getTopicsWithoutLazConnections() { return getTopics() .then(function (topics) { return topics.filter(function (rootLevelTopic) { return parseInt(rootLevelTopic.topicId) !== LAZ_CONNECTIONS_TOPIC_ID; }); }); } function initializeTopicData() { return topicApi.get() .then(function (topics) { if (Array.isArray(topics) && topics.length >= 1) { topics = buildTree(topics); topics.forEach(function (topic) {topic.isOpen = true;}); } else { topics = []; } topicTree.splice(0); Array.prototype.push.apply(topicTree, topics); }) .catch(function(reason) { console.debug(reason); }); } function buildTree(topics) { var tempRootTopic = {topicId: 0, children: [], superTopicId: null, level: 0}; addChildren(tempRootTopic, topics); return tempRootTopic.children; } function addChildren(topic, topics) { topicMap[parseInt(topic.topicId)] = topic; topic.children = findChildren(topic.topicId, topics); for (var i = 0; i < topic.children.length; i ++) { topic.children[i].level = topic.level + 1; if (topic.superTopicId) { topic.children[i].parentTopic = topic; } addChildren(topic.children[i], topics); } } function findChildren(topicId, topics) { var children = []; var childIdx = findFirstChild(topicId, topics); if (childIdx > -1) { do { if (!topics[childIdx].level) { children.push(topics[childIdx]); } childIdx ++; } while (childIdx < topics.length - 1 && topics[childIdx].superTopicId == topicId); } return children; } function findFirstChild(superTopicId, topics) { var key = -1; var high = topics.length - 1; var low = 0; var mid, currSuperTopicId, cmp; superTopicId = parseInt(superTopicId); while (high >= low) { mid = Math.floor((high + low) / 2); currSuperTopicId = parseInt(topics[mid].superTopicId); if (superTopicId < currSuperTopicId) { cmp = -1; } else if (superTopicId > currSuperTopicId) { cmp = 1; } else { cmp = 0; } if (cmp < 0) { high = mid - 1; } else if (cmp > 0) { low = mid + 1; } else { while (mid > 0 && parseInt(topics[mid-1].superTopicId) == superTopicId) { mid --; } key = mid; break; } } return key; } }]);