package net.mezimmah.wkt9.keypad import net.mezimmah.wkt9.exception.MissingLetterCode import java.lang.StringBuilder class Keypad( private val keyCodeMapping: KeyCodeMapping, private val letterLayout: Map> ) { private lateinit var letterKeyMap: Map private lateinit var keyIsLetterMap: Map private var emojiCodes = mapOf( "❤️" to "143278", "\uD83D\uDE18" to "15477" ) init { initKeyMaps(letterLayout) } fun getKey(keyCode: Int): Key? { return keyCodeMapping.key(keyCode) } fun getCharacter(key: Key, idx: Int): Char { val chars = letterLayout[key]!! val length = chars.size val wrappedIdx = idx % (length - 1) + 1 return chars[wrappedIdx] } fun getDigit(key: Key): Char? { val letters = letterLayout[key] ?: return null return if (letters.isNotEmpty() && letters[0].isDigit()) letters[0] else null } fun getCodeForWord(word: String): String { if (emojiCodes.keys.contains(word)) return emojiCodes[word]!! val builder = StringBuilder() for (letter in word) { val code = codeForLetter(letter) ?: throw MissingLetterCode("No code found for '$letter'") builder.append(code) } return builder.toString() } private fun codeForLetter(letter: Char): Char? { return letterKeyMap[letter]?.code } private fun initKeyMaps(layout: Map>): Map { val letterKeyMap = HashMap() val keyIsLetterMap = HashMap() this.letterKeyMap = letterKeyMap this.keyIsLetterMap = keyIsLetterMap for ((key, characters) in layout) { for (char in characters) { letterKeyMap[char] = key if (!KeyLayout.nonAlphaNumeric.contains(char)) { letterKeyMap[char.uppercaseChar()] = key keyIsLetterMap[key] = true } else if (keyIsLetterMap[key] == null) keyIsLetterMap[key] = false } } return letterKeyMap } }