package net.taehui.twilight.system import com.fasterxml.jackson.core.type.TypeReference import com.fasterxml.jackson.databind.ObjectMapper import net.taehui.twilight.JSON import net.taehui.twilight.Logger import net.taehui.twilight.TwilightComponent import java.io.IOException import java.nio.file.Files import java.util.* import java.util.concurrent.ConcurrentHashMap import java.util.stream.Collectors object TitleSystem : Logger { class TitleItem : Comparable<TitleItem> { var title = "" var title1042 = "" var titleColor = "" var wwwLevel = "" var avatarLevel = 0 var noteIDs: Array<String>? = null var titleLevel = 0 override fun compareTo(other: TitleItem): Int { val avatarLevelData = avatarLevel.compareTo(other.avatarLevel) if (avatarLevelData != 0) { return avatarLevelData } val levelItem0 = LevelSystem.getLevelItem(wwwLevel) val levelItem1 = LevelSystem.getLevelItem(other.wwwLevel) if (levelItem0 != null && levelItem1 != null) { val levelData = levelItem0.compareTo(levelItem1) if (levelData != 0) { return levelData } } val titleData = title.compareTo(other.title) return if (titleData != 0) { titleData } else { titleLevel.compareTo(other.titleLevel) } } } private val titleIDTitleItemMap = ConcurrentHashMap<String, TitleItem>() fun loadTitle() { try { titleIDTitleItemMap.clear() Files.list(TwilightComponent.TITLE_ENTRY_PATH).use { titleFilePaths -> titleFilePaths.forEach { titleFilePath -> try { val jm = ObjectMapper() val titleItems = jm.readValue( titleFilePath.toFile().absoluteFile, object : TypeReference<Map<String, TitleItem>>() {}) val titleIDTitleItems = TreeMap<String, TitleItem>(Comparator.comparing { titleItems[it]!! }) titleIDTitleItems.putAll(titleItems) titleIDTitleItemMap.putAll(titleIDTitleItems) logInfo("Loaded Title (${titleFilePath.fileName})") jm.writerWithDefaultPrettyPrinter().writeValue(titleFilePath.toFile().absoluteFile, titleIDTitleItems) logInfo("Saved Title (${titleFilePath.fileName})") } catch (e: IOException) { logFault(e) } } } } catch (e: IOException) { logFault(e) } } fun getTitle(language: String, titleID: String): JSON.TwilightWwwTitle? { val titleItem = titleIDTitleItemMap[titleID] return if (titleItem != null) JSON.TwilightWwwTitle( when (language) { "ko-KR" -> titleItem.title1042 else -> titleItem.title }, titleItem.titleColor ) else null } fun getTitles( levelIDs: Collection<String>, noteIDs: Collection<String>, avatarLevel: Int, language: String ): Collection<Any> { return getTitleIDs(levelIDs, noteIDs, avatarLevel).stream().sorted { o1, o2 -> val titleItem1 = titleIDTitleItemMap[o1]!! val titleItem2 = titleIDTitleItemMap[o2]!! val titleColorData = titleItem1.titleColor.compareTo(titleItem2.titleColor) if (titleColorData != 0) titleColorData else titleItem1.compareTo(titleItem2) }.map { val titleItem = titleIDTitleItemMap[it]!! object { val titleID = it val title = when (language) { "ko-KR" -> titleItem.title1042 else -> titleItem.title } val titleColor = titleItem.titleColor } }.toList() } fun getTitleItems( levelIDs: Collection<String>, noteIDs: Collection<String>, avatarLevel: Int ): Collection<TitleItem> { return getTitleIDs(levelIDs, noteIDs, avatarLevel).mapNotNull { titleIDTitleItemMap[it] } } fun getTitleIDs(levelIDs: Collection<String>, noteIDs: Collection<String>, avatarLevel: Int): Collection<String> { val titleIDs = mutableListOf<String>() titleIDTitleItemMap.entries.stream().filter { (_, titleItem) -> titleItem.avatarLevel <= avatarLevel && (titleItem.wwwLevel.isEmpty() || levelIDs.any { it == titleItem.wwwLevel }) && titleItem.noteIDs?.all { noteID -> noteIDs.any { it == noteID } } != false }.collect(Collectors.groupingBy { it.value.title }).values.forEach { titleItems -> if (titleItems.size > 1) { titleIDs.add(titleItems.maxBy { it.value.titleLevel }.key) } else { titleIDs.add(titleItems[0].key) } } return titleIDs } fun getTitles(levelID: String, language: String): Array<Any> { val titleIDs = mutableListOf<String>() titleIDTitleItemMap.entries.stream().filter { (_, titleItem) -> levelID == titleItem.wwwLevel } .collect(Collectors.groupingBy { it.value.title }).values.forEach { titleItems -> if (titleItems.size > 1) { titleIDs.add(titleItems.maxBy { it.value.titleLevel }.key) } else { titleIDs.add(titleItems[0].key) } } return titleIDs.map { val titleItem = titleIDTitleItemMap[it]!! object { val titleID = it val title = when (language) { "ko-KR" -> titleItem.title1042 else -> titleItem.title } val titleColor = titleItem.titleColor } }.toTypedArray() } }