diff --git a/Source/Models/Word.swift b/Source/Models/Word.swift index fb45c8c..651a406 100644 --- a/Source/Models/Word.swift +++ b/Source/Models/Word.swift @@ -427,12 +427,30 @@ struct Word: Codable, Identifiable { } } + func generateImperativeReflexive(number: Number) -> String? { + switch number { + case .singular: + if let imp = generateImperative(number: number) { + return imp + "sk" + } + case .dual, .plural: + if var imp = generateImperative(number: number) { + imp.removeLast() + return imp + "zk" + } + } + + return oldNorseWord + } + func generateImperative(number: Number) -> String? { switch number { case .singular: if var inf = generateInfinitive() { if inf.hasSuffix("ja") { inf.removeLast(2) + } else if inf == "bana" { + return inf } else { inf.removeLast() } @@ -1678,6 +1696,82 @@ struct Word: Codable, Identifiable { return genitiveCase } + func generateConjugationReflexive(person: Person, number: Number, tense: Tense) -> String? { + switch tense { + case .past: + return generateConjugationPastReflexive(person: person, number: number) + case .present: + return generateConjugationPresentReflexive(person: person, number: number) + } + } + + func generateConjugationPresentReflexive(person: Person, number: Number) -> String? { + var verb = generateConjugationPresent(person: person, number: number) + + switch person { + case .first: + switch number { + case .singular: + if verb?.last == "a" { + verb?.removeLast() + } + return verb! + "umk" + case .dual, .plural: + return verb! + "sk" + } + case .second: + switch number { + case .singular: + verb?.removeLast() + return verb! + "sk" + case .dual, .plural: + verb?.removeLast() + return verb! + "zk" + } + case .third: + switch number { + case .singular: + verb?.removeLast() + return verb! + "sk" + case .dual, .plural: + return verb! + "sk" + } + } + } + + func generateConjugationPastReflexive(person: Person, number: Number) -> String? { + var verb = generateConjugationPast(person: person, number: number) + + switch person { + case .first: + switch number { + case .singular: + if verb?.last == "a" { + verb?.removeLast() + } + return verb! + "umk" + case .dual, .plural: + return verb! + "sk" + } + case .second: + switch number { + case .singular: + verb?.removeLast() + return verb! + "zk" + case .dual, .plural: + verb?.removeLast() + return verb! + "zk" + } + case .third: + switch number { + case .singular: + return verb! + "sk" + case .dual, .plural: + return verb! + "sk" + } + } + } + func generateConjugation(person: Person, number: Number, tense: Tense) -> String? { switch tense { diff --git a/Source/Services/WordService.swift b/Source/Services/WordService.swift index da62a71..9adb5be 100644 --- a/Source/Services/WordService.swift +++ b/Source/Services/WordService.swift @@ -107,6 +107,7 @@ class WordService { // This function checks if a word matches a query func wordMatchesQuery(_ word: Word, query: String) -> Bool { + // nouns let wordMatchesQuery = word.oldNorseWord.lowercased().contains(query) let nominativeSingularMatchesQuery = word.generateNounNominative(number: Number.singular, article: false)?.lowercased().contains(query) == true let nominativeDualMatchesQuery = word.generateNounNominative(number: Number.dual, article: false)?.lowercased().contains(query) == true @@ -122,6 +123,7 @@ class WordService { let genitivePluralMatchesQuery = word.generateNounGenitive(number: Number.plural, article: false)?.lowercased().contains(query) == true + // verbs let firstSingularMatchesQuery = word.generateConjugation(person: .first, number: .singular, tense: .present)?.lowercased().contains(query) == true let secondSingularMatchesQuery = word.generateConjugation(person: .second, number: .singular, tense: .present)?.lowercased().contains(query) == true let thirdSingularMatchesQuery = word.generateConjugation(person: .third, number: .singular, tense: .present)?.lowercased().contains(query) == true @@ -136,6 +138,21 @@ class WordService { let secondPluralMatchesQueryPast = word.generateConjugation(person: .second, number: .plural, tense: .past)?.lowercased().contains(query) == true let thirdPluralMatchesQueryPast = word.generateConjugation(person: .third, number: .plural, tense: .past)?.lowercased().contains(query) == true + // reflexive verbs + let firstSingularMatchesQueryR = word.generateConjugationReflexive(person: .first, number: .singular, tense: .present)?.lowercased().contains(query) == true + let secondSingularMatchesQueryR = word.generateConjugationReflexive(person: .second, number: .singular, tense: .present)?.lowercased().contains(query) == true + let thirdSingularMatchesQueryR = word.generateConjugationReflexive(person: .third, number: .singular, tense: .present)?.lowercased().contains(query) == true + let firstPluralMatchesQueryR = word.generateConjugationReflexive(person: .first, number: .plural, tense: .present)?.lowercased().contains(query) == true + let secondPluralMatchesQueryR = word.generateConjugationReflexive(person: .second, number: .plural, tense: .present)?.lowercased().contains(query) == true + let thirdPluralMatchesQueryR = word.generateConjugationReflexive(person: .third, number: .plural, tense: .present)?.lowercased().contains(query) == true + + let firstSingularMatchesQueryPastR = word.generateConjugationReflexive(person: .first, number: .singular, tense: .past)?.lowercased().contains(query) == true + let secondSingularMatchesQueryPastR = word.generateConjugationReflexive(person: .second, number: .singular, tense: .past)?.lowercased().contains(query) == true + let thirdSingularMatchesQueryPastR = word.generateConjugationReflexive(person: .third, number: .singular, tense: .past)?.lowercased().contains(query) == true + let firstPluralMatchesQueryPastR = word.generateConjugationReflexive(person: .first, number: .plural, tense: .past)?.lowercased().contains(query) == true + let secondPluralMatchesQueryPastR = word.generateConjugationReflexive(person: .second, number: .plural, tense: .past)?.lowercased().contains(query) == true + let thirdPluralMatchesQueryPastR = word.generateConjugationReflexive(person: .third, number: .plural, tense: .past)?.lowercased().contains(query) == true + // nominative let accNominativeSingularMasculine = word.generateCase(wordCase: .nominative, number: .singular, gender: .masculine)?.lowercased().contains(query) == true let accNominativeSingularFemenine = word.generateCase(wordCase: .nominative, number: .singular, gender: .feminine)?.lowercased().contains(query) == true @@ -225,6 +242,6 @@ class WordService { let accImerativePlural = word.generateImperative(number: .plural)?.lowercased().contains(query) == true - return wordMatchesQuery || nominativeSingularMatchesQuery || nominativeDualMatchesQuery || nominativePluralMatchesQuery || accusativeSingularMatchesQuery || accusativeDualMatchesQuery || accusativePluralMatchesQuery || dativeSingularMatchesQuery || dativeDualMatchesQuery || dativePluralMatchesQuery || firstSingularMatchesQuery || secondSingularMatchesQuery || thirdSingularMatchesQuery || firstPluralMatchesQuery || secondPluralMatchesQuery || thirdPluralMatchesQuery || firstSingularMatchesQueryPast || secondSingularMatchesQueryPast || thirdSingularMatchesQueryPast || firstPluralMatchesQueryPast || secondPluralMatchesQueryPast || thirdPluralMatchesQueryPast || genitiveSingularMatchesQuery || genitiveDualMatchesQuery || genitivePluralMatchesQuery || accNominativeSingularMasculine || accNominativeSingularFemenine || accNominativeSingularNeuter || accNominativeDualMasculine || accNominativeDualFemenine || accNominativeDualNeuter || accNominativePluralMasculine || accNominativePluralFemenine || accAccusativePluralNeuter || accAccusativeSingularMasculine || accAccusativeSingularFemenine || accAccusativeSingularNeuter || accAccusativeDualMasculine || accAccusativeDualFemenine || accAccusativeDualNeuter || accAccusativePluralMasculine || accDativePluralFemenine || accDativePluralNeuter || accGenitiveSingularMasculine || accGenitiveSingularFemenine || accGenitiveSingularNeuter || accGenitiveDualMasculine || accGenitiveDualFemenine || accGenitiveDualNeuter || accGenitivePluralMasculine || accGenitivePluralFemenine || accGenitivePluralNeuter || accNominativePluralNeuter || accDativeSingularMasculine || accDativePluralMasculine || accDativeDualNeuter || accDativeDualFemenine || accDativeDualMasculine || accDativeSingularFemenine || accDativeSingularNeuter || accAccusativePluralFemenine || accComparative || accInfinitive || accImerativeSingular || accImerativePlural || accComparativeAdjective1 || accComparativeAdjective2 || accComparativeAdjective3 || accComparisonWeakAdjective1 || accComparisonWeakAdjective2 || accComparisonWeakAdjective3 || accComparisonStrongAdjective1 || accComparisonStrongAdjective2 || accComparisonStrongAdjective3 || accComparisonStrongAdjective4 || accComparisonStrongAdjective5 || accComparisonStrongAdjective6 || accComparisonStrongAdjective7 || accComparisonStrongAdjective8 || accComparisonStrongAdjective9 || accComparisonStrongAdjective10 || accComparisonStrongAdjective11 || accComparisonStrongAdjective12 || accComparisonStrongAdjective13 || accComparisonStrongAdjective14 || accComparisonStrongAdjective15 || accComparisonStrongAdjective16 || accComparisonStrongAdjective17 || accComparison + return wordMatchesQuery || nominativeSingularMatchesQuery || nominativeDualMatchesQuery || nominativePluralMatchesQuery || accusativeSingularMatchesQuery || accusativeDualMatchesQuery || accusativePluralMatchesQuery || dativeSingularMatchesQuery || dativeDualMatchesQuery || dativePluralMatchesQuery || firstSingularMatchesQuery || secondSingularMatchesQuery || thirdSingularMatchesQuery || firstPluralMatchesQuery || secondPluralMatchesQuery || thirdPluralMatchesQuery || firstSingularMatchesQueryPast || secondSingularMatchesQueryPast || thirdSingularMatchesQueryPast || firstPluralMatchesQueryPast || secondPluralMatchesQueryPast || thirdPluralMatchesQueryPast || genitiveSingularMatchesQuery || genitiveDualMatchesQuery || genitivePluralMatchesQuery || accNominativeSingularMasculine || accNominativeSingularFemenine || accNominativeSingularNeuter || accNominativeDualMasculine || accNominativeDualFemenine || accNominativeDualNeuter || accNominativePluralMasculine || accNominativePluralFemenine || accAccusativePluralNeuter || accAccusativeSingularMasculine || accAccusativeSingularFemenine || accAccusativeSingularNeuter || accAccusativeDualMasculine || accAccusativeDualFemenine || accAccusativeDualNeuter || accAccusativePluralMasculine || accDativePluralFemenine || accDativePluralNeuter || accGenitiveSingularMasculine || accGenitiveSingularFemenine || accGenitiveSingularNeuter || accGenitiveDualMasculine || accGenitiveDualFemenine || accGenitiveDualNeuter || accGenitivePluralMasculine || accGenitivePluralFemenine || accGenitivePluralNeuter || accNominativePluralNeuter || accDativeSingularMasculine || accDativePluralMasculine || accDativeDualNeuter || accDativeDualFemenine || accDativeDualMasculine || accDativeSingularFemenine || accDativeSingularNeuter || accAccusativePluralFemenine || accComparative || accInfinitive || accImerativeSingular || accImerativePlural || accComparativeAdjective1 || accComparativeAdjective2 || accComparativeAdjective3 || accComparisonWeakAdjective1 || accComparisonWeakAdjective2 || accComparisonWeakAdjective3 || accComparisonStrongAdjective1 || accComparisonStrongAdjective2 || accComparisonStrongAdjective3 || accComparisonStrongAdjective4 || accComparisonStrongAdjective5 || accComparisonStrongAdjective6 || accComparisonStrongAdjective7 || accComparisonStrongAdjective8 || accComparisonStrongAdjective9 || accComparisonStrongAdjective10 || accComparisonStrongAdjective11 || accComparisonStrongAdjective12 || accComparisonStrongAdjective13 || accComparisonStrongAdjective14 || accComparisonStrongAdjective15 || accComparisonStrongAdjective16 || accComparisonStrongAdjective17 || accComparison || firstSingularMatchesQueryR || secondSingularMatchesQueryR || thirdSingularMatchesQueryR || firstPluralMatchesQueryR || secondPluralMatchesQueryR || thirdPluralMatchesQueryR || firstSingularMatchesQueryPastR || secondSingularMatchesQueryPastR || thirdSingularMatchesQueryPastR || firstPluralMatchesQueryPastR || secondPluralMatchesQueryPastR || thirdPluralMatchesQueryPastR } } diff --git a/Source/Views/DynamicTableVerbs.swift b/Source/Views/DynamicTableVerbs.swift index 07954ab..a95bc8d 100644 --- a/Source/Views/DynamicTableVerbs.swift +++ b/Source/Views/DynamicTableVerbs.swift @@ -7,6 +7,21 @@ struct DynamicTableVerbs: View { ScrollView(.horizontal, showsIndicators: true) { VStack(alignment: .leading) { // Main Headers + + HStack(spacing: 0) { + Text("") + .frame(minWidth: 87, minHeight: 0, maxHeight: .infinity, alignment: .center) + .padding(.vertical, 10) + .background(Color.gray.opacity(0.2)) + .border(Color.black, width: 1) + + Text("Present Tense") + .frame(minWidth: 522, minHeight: 0, maxHeight: .infinity, alignment: .center) + .padding(.vertical, 10) + .background(Color.gray.opacity(0.2)) + .border(Color.black, width: 1) + } + HStack(spacing: 0) { Text("") .frame(minWidth: 87, minHeight: 0, maxHeight: .infinity, alignment: .center) @@ -26,6 +41,47 @@ struct DynamicTableVerbs: View { } } + HStack(spacing: 0) { + Text("Imperative") + .frame(minWidth: 87, maxWidth: 87) + .padding(.vertical, 10) + .border(Color.black, width: 1) + .background(Color.gray.opacity(0.2)) + + ForEach(Number.allCases, id: \.rawValue) { num in + if word.shouldShowNumber(number: num) { + if let wordWithConjunction = word.generateImperative(number: num) { + Text(wordWithConjunction) + .frame(minWidth: headerWidth(for: num), maxWidth: .infinity) + .padding(.vertical, 10) + .border(Color.black, width: 1) + } + } + } + } + + // Rows + ForEach(Person.allCases, id: \.rawValue) { p in + HStack(spacing: 0) { + Text(p.rawValue.capitalized) + .frame(minWidth: 87, maxWidth: 87) + .padding(.vertical, 10) + .border(Color.black, width: 1) + .background(Color.gray.opacity(0.2)) + + ForEach(Number.allCases, id: \.rawValue) { num in + if word.shouldShowNumber(number: num) { + if let wordWithConjunction = word.generateConjugation(person: p, number: num, tense: .present) { + Text(wordWithConjunction) + .frame(minWidth: headerWidth(for: num), maxWidth: .infinity) + .padding(.vertical, 10) + .border(Color.black, width: 1) + } + } + } + } + } + HStack(spacing: 0) { Text("") .frame(minWidth: 87, minHeight: 0, maxHeight: .infinity, alignment: .center) @@ -33,13 +89,88 @@ struct DynamicTableVerbs: View { .background(Color.gray.opacity(0.2)) .border(Color.black, width: 1) - Text("Present Tense") + Text("Past Tense") .frame(minWidth: 522, minHeight: 0, maxHeight: .infinity, alignment: .center) .padding(.vertical, 10) .background(Color.gray.opacity(0.2)) .border(Color.black, width: 1) } + HStack(spacing: 0) { + Text("") + .frame(minWidth: 87, minHeight: 0, maxHeight: .infinity, alignment: .center) + .padding(.vertical, 10) + .background(Color.gray.opacity(0.2)) + .border(Color.black, width: 1) + + ForEach(Number.allCases, id: \.rawValue) { num in + if word.shouldShowNumber(number: num) { + let headerWidthValue = headerWidth(for: num) + Text(num.rawValue.capitalized) + .frame(minWidth: headerWidthValue, minHeight: 0, maxHeight: .infinity, alignment: .center) + .padding(.vertical, 10) + .background(Color.gray.opacity(0.2)) + .border(Color.black, width: 1) + } + } + } + + // Rows + ForEach(Person.allCases, id: \.rawValue) { p in + HStack(spacing: 0) { + Text(p.rawValue.capitalized) + .frame(minWidth: 87, maxWidth: 87) + .padding(.vertical, 10) + .border(Color.black, width: 1) + .background(Color.gray.opacity(0.2)) + + ForEach(Number.allCases, id: \.rawValue) { num in + if word.shouldShowNumber(number: num) { + if let wordWithConjunction = word.generateConjugation(person: p, number: num, tense: .past) { + Text(wordWithConjunction) + .frame(minWidth: headerWidth(for: num), maxWidth: .infinity) + .padding(.vertical, 10) + .border(Color.black, width: 1) + } + } + } + } + } + // Main Headers + + HStack(spacing: 0) { + Text("") + .frame(minWidth: 87, minHeight: 0, maxHeight: .infinity, alignment: .center) + .padding(.vertical, 10) + .background(Color.gray.opacity(0.2)) + .border(Color.black, width: 1) + + Text("Reflexive Present Tense") + .frame(minWidth: 522, minHeight: 0, maxHeight: .infinity, alignment: .center) + .padding(.vertical, 10) + .background(Color.gray.opacity(0.2)) + .border(Color.black, width: 1) + } + + HStack(spacing: 0) { + Text("") + .frame(minWidth: 87, minHeight: 0, maxHeight: .infinity, alignment: .center) + .padding(.vertical, 10) + .background(Color.gray.opacity(0.2)) + .border(Color.black, width: 1) + + ForEach(Number.allCases, id: \.rawValue) { num in + if word.shouldShowNumber(number: num) { + let headerWidthValue = headerWidth(for: num) + Text(num.rawValue.capitalized) + .frame(minWidth: headerWidthValue, minHeight: 0, maxHeight: .infinity, alignment: .center) + .padding(.vertical, 10) + .background(Color.gray.opacity(0.2)) + .border(Color.black, width: 1) + } + } + } + HStack(spacing: 0) { Text("Imperative") .frame(minWidth: 87, maxWidth: 87) @@ -49,7 +180,7 @@ struct DynamicTableVerbs: View { ForEach(Number.allCases, id: \.rawValue) { num in if word.shouldShowNumber(number: num) { - if let wordWithConjunction = word.generateImperative(number: num) { + if let wordWithConjunction = word.generateImperativeReflexive(number: num) { Text(wordWithConjunction) .frame(minWidth: headerWidth(for: num), maxWidth: .infinity) .padding(.vertical, 10) @@ -70,7 +201,7 @@ struct DynamicTableVerbs: View { ForEach(Number.allCases, id: \.rawValue) { num in if word.shouldShowNumber(number: num) { - if let wordWithConjunction = word.generateConjugation(person: p, number: num, tense: .present) { + if let wordWithConjunction = word.generateConjugationReflexive(person: p, number: num, tense: .present) { Text(wordWithConjunction) .frame(minWidth: headerWidth(for: num), maxWidth: .infinity) .padding(.vertical, 10) @@ -88,13 +219,32 @@ struct DynamicTableVerbs: View { .background(Color.gray.opacity(0.2)) .border(Color.black, width: 1) - Text("Past Tense") + Text("Reflexive Past Tense") .frame(minWidth: 522, minHeight: 0, maxHeight: .infinity, alignment: .center) .padding(.vertical, 10) .background(Color.gray.opacity(0.2)) .border(Color.black, width: 1) } + HStack(spacing: 0) { + Text("") + .frame(minWidth: 87, minHeight: 0, maxHeight: .infinity, alignment: .center) + .padding(.vertical, 10) + .background(Color.gray.opacity(0.2)) + .border(Color.black, width: 1) + + ForEach(Number.allCases, id: \.rawValue) { num in + if word.shouldShowNumber(number: num) { + let headerWidthValue = headerWidth(for: num) + Text(num.rawValue.capitalized) + .frame(minWidth: headerWidthValue, minHeight: 0, maxHeight: .infinity, alignment: .center) + .padding(.vertical, 10) + .background(Color.gray.opacity(0.2)) + .border(Color.black, width: 1) + } + } + } + // Rows ForEach(Person.allCases, id: \.rawValue) { p in HStack(spacing: 0) { @@ -106,7 +256,7 @@ struct DynamicTableVerbs: View { ForEach(Number.allCases, id: \.rawValue) { num in if word.shouldShowNumber(number: num) { - if let wordWithConjunction = word.generateConjugation(person: p, number: num, tense: .past) { + if let wordWithConjunction = word.generateConjugationReflexive(person: p, number: num, tense: .past) { Text(wordWithConjunction) .frame(minWidth: headerWidth(for: num), maxWidth: .infinity) .padding(.vertical, 10)