package sk.baka.aedict.kanji;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import sk.baka.aedict.dict.DictTypeEnum;
import sk.baka.aedict.dict.MatcherEnum;
import sk.baka.aedict.dict.SearchQuery;
import sk.baka.aedict.kanji.Deinflections.Deinflection;
import sk.baka.aedict.kanji.VerbInflection.Form;
super(inflected, true, true, form, base);
}
}
private final String endsWith;
private final String[] replaceBy;
private final boolean isAllowEntireWordMatch;
private final boolean isStopIfMatch;
private final Form form;
public EndsWithDeinflector(
final String endsWith,
final Form form,
final String... replaceBy) {
this(endsWith, false, false, form, replaceBy);
}
public EndsWithDeinflector(
final String endsWith,
final boolean isAllowEntireWordMatch,
final boolean isStopIfMatch,
final Form form,
final String... replaceBy) {
this.endsWith = endsWith;
this.replaceBy = replaceBy;
this.isAllowEntireWordMatch = isAllowEntireWordMatch;
this.isStopIfMatch = isStopIfMatch;
this.form = form;
}
@Override
public Set<String>
deinflect(String romaji) {
final String ending = isMatch(romaji);
if (ending == null) {
return null;
}
final Set<String> result = new HashSet<String>(replaceBy.length);
final String verbPart = romaji.substring(0, romaji.length() - ending.length());
for (final String rb : replaceBy) {
result.add(verbPart + rb);
}
return result;
}
private String
isMatch(
final String romaji) {
final String ending = endsWith;
if (isAllowEntireWordMatch && romaji.equals(ending)) {
return ending;
}
if (!isAllowEntireWordMatch) {
if (romaji.endsWith(ending) && !romaji.equals(ending)) {
return ending;
}
}
return null;
}
@Override
return isStopIfMatch;
}
@Override
return form;
}
}
private final AbstractDeinflector eruDeinflector = new EndsWithDeinflector("eru", Form.ABLE_TO_DO2, "eru", "u");
@Override
public Set<String>
deinflect(String romaji) {
if (romaji.endsWith("rareru")) {
return null;
}
return eruDeinflector.deinflect(romaji);
}
@Override
return true;
}
@Override
return Form.ABLE_TO_DO2;
}
}
public abstract Set<String>
deinflect(String romaji);
}
private static AbstractDeinflector
basicSuffix(
final String endsWith,
final Form form,
final String... replaceBy) {
return new EndsWithDeinflector(endsWith, false, true, form, replaceBy);
}
private static List<IrregularDeinflector>
irregular(String[] endsWith,
final Form form,
final String replaceBy) {
final List<IrregularDeinflector> result=new ArrayList<VerbDeinflection.IrregularDeinflector>();
for(final String ew:endsWith){
result.add(new IrregularDeinflector(ew, form, replaceBy));
}
return result;
}
private final static List<? extends AbstractDeinflector> DEINFLECTORS;
static {
final List<AbstractDeinflector> d = new ArrayList<AbstractDeinflector>();
d.addAll(irregular(new String[]{"dewaarimasen", "dehaarimasen", "de wa arimasen", "de ha arimasen", "zya arimasen", "zyaarimasen"}, Form.POLITE_NEGATIVE, "desu"));
d.addAll(irregular(new String[]{"dewaarimasendesita", "dehaarimasendesita", "de wa arimasen desita", "de ha arimasen desita", "zya arimasen desita", "zyaarimasendesita"}, Form.POLITE_PAST_NEGATIVE, "desu"));
d.add(new EndsWithDeinflector("masen", Form.POLITE_NEGATIVE, "masu"));
d.add(new EndsWithDeinflector("masita", Form.POLITE_PAST, "masu"));
d.add(new EndsWithDeinflector("masendesita", Form.POLITE_PAST_NEGATIVE, "masu"));
d.add(new EndsWithDeinflector("masen desita", Form.POLITE_PAST_NEGATIVE, "masu"));
d.add(new EndsWithDeinflector("nakatta", Form.NEGATIVE_PAST, "nai"));
d.add(new IrregularDeinflector("sinai", Form.NEGATIVE, "suru"));
d.add(new IrregularDeinflector("sita", Form.PAST_TENSE, "suru"));
d.add(new IrregularDeinflector("site", Form.CONTINUATION , "suru"));
d.add(new IrregularDeinflector("simasu", Form.POLITE, "suru"));
d.add(new IrregularDeinflector("siyou", Form.LET_S2, "suru"));
d.add(new IrregularDeinflector("sareru", Form.PLAIN, "sareru"));
d.add(new IrregularDeinflector("sarenai", Form.NEGATIVE, "sareru"));
d.add(new IrregularDeinflector("sareta", Form.PAST_TENSE, "sareru"));
d.add(new IrregularDeinflector("konai", Form.NEGATIVE, "kuru"));
d.add(new IrregularDeinflector("kita",Form.PAST_TENSE, "kuru"));
d.add(new IrregularDeinflector("kite", Form.CONTINUATION, "kuru"));
d.add(new IrregularDeinflector("kimasu", Form.POLITE, "kuru"));
d.add(new IrregularDeinflector("koyou",Form.LET_S2, "kuru"));
d.add(new IrregularDeinflector("da", Form.PLAIN, "desu"));
d.addAll(irregular(new String[]{"dewanai", "zyanai"},Form.NEGATIVE, "desu"));
d.add(new IrregularDeinflector("datta", Form.PAST_TENSE , "desu"));
d.add(new IrregularDeinflector("desita", Form.POLITE_PAST, "desu"));
d.add(new IrregularDeinflector("de", null, "desu"));
d.addAll(irregular(new String[]{"dehanai", "de ha nai", "dewanai", "de wa nai"}, Form.NEGATIVE, "desu"));
d.addAll(irregular(new String[]{"dehaaru", "de ha aru", "de wa aru", "dewaaru"}, Form.PLAIN, "desu"));
d.add(new IrregularDeinflector("itta", Form.PAST_TENSE, "iku"));
d.add(new IrregularDeinflector("itte", Form.CONTINUATION, "iku"));
d.add(new IrregularDeinflector("ikimasu", Form.POLITE, "iku"));
d.add(new IrregularDeinflector("ikareru", Form.PLAIN, "ikareru"));
d.add(new IrregularDeinflector("ikarenai", Form.NEGATIVE, "ikareru"));
d.add(new IrregularDeinflector("ikareta",Form.PAST_TENSE, "ikareru"));
d.add(new IrregularDeinflector("nai", Form.NEGATIVE, "aru"));
d.add(new IrregularDeinflector("nakatta", Form.NEGATIVE_PAST, "aru"));
d.add(new IrregularDeinflector("arimasu",Form.POLITE, "aru"));
d.add(new IrregularDeinflector("atte", Form.CONTINUATION, "aru", "au"));
d.add(new IrregularDeinflector("atta", Form.PAST_TENSE, "aru", "au"));
d.add(basicSuffix("kereba", Form.NEGATIVE_CONDITIONAL, "i"));
d.add(basicSuffix("arenai", Form.NEGATIVE, "areru"));
d.add(basicSuffix("areta", Form.PAST_TENSE, "areru"));
d.add(basicSuffix("areru", Form.PLAIN, "areru"));
d.add(basicSuffix("wanai", Form.NEGATIVE, "u"));
d.add(basicSuffix("anai", Form.NEGATIVE, "u"));
d.add(new EndsWithDeinflector("enai", Form.NEGATIVE, "eru"));
d.add(basicSuffix("inai", Form.NEGATIVE, "iru"));
d.add(basicSuffix("itai", Form.WANT, "u"));
d.add(new EndsWithDeinflector("etai", Form.WANT, "eru"));
d.add(basicSuffix("eba", Form.IF2, "u"));
d.add(new EndsWithDeinflector("emasu", Form.ABLE_TO_DO2, "u", "eru"));
d.add(new EndsWithDeinflector("imasu", Form.POLITE, "u", "iru"));
d.add(basicSuffix("outosuru", null, "u"));
d.add(basicSuffix("ou to suru",null, "u"));
d.add(new EruDeinflector());
d.add(basicSuffix("sita", Form.PAST_TENSE, "su"));
d.add(basicSuffix("site",Form.CONTINUATION, "su"));
d.add(basicSuffix("ita", Form.PAST_TENSE, "ku", "iru"));
d.add(basicSuffix("ite",Form.CONTINUATION, "ku", "iru"));
d.add(basicSuffix("eta", Form.PAST_TENSE, "eru"));
d.add(basicSuffix("ete",Form.CONTINUATION, "eru"));
d.add(basicSuffix("ida", Form.PAST_TENSE, "gu"));
d.add(basicSuffix("ide",Form.CONTINUATION, "gu"));
d.add(basicSuffix("tta", Form.PAST_TENSE, "tu", "u", "ru"));
d.add(basicSuffix("tte",Form.CONTINUATION, "tu", "u", "ru"));
d.add(basicSuffix("nda", Form.PAST_TENSE, "nu", "bu", "mu"));
d.add(basicSuffix("nde",Form.CONTINUATION, "nu", "bu", "mu"));
DEINFLECTORS = d;
}
public static Deinflections
deinflect(
final String japanese) {
final Deinflections result = new Deinflections();
result.deinflections=new ArrayList<Deinflection>();
result.deinflectedVerbs = new HashSet<String>();
Set<String> finalDeinflect = new HashSet<String>();
result.deinflectedVerbs.add(RomanizationEnum.NihonShiki.toRomaji(japanese).trim());
for (final AbstractDeinflector deinflector : DEINFLECTORS) {
final Set<String> newResult = new HashSet<String>(result.deinflectedVerbs);
for (final String romaji : result.deinflectedVerbs) {
final Set<String> deinflected = deinflector.deinflect(romaji);
if (deinflected != null && !deinflected.isEmpty()) {
newResult.remove(romaji);
if (deinflector.stopIfMatch()) {
finalDeinflect.addAll(deinflected);
} else {
newResult.addAll(deinflected);
}
result.deinflections.add(new Deinflection(romaji, deinflector.getForm(), deinflected.toArray(new String[0])));
}
}
result.deinflectedVerbs = newResult;
}
result.deinflectedVerbs.addAll(finalDeinflect);
return result;
}
throw new AssertionError();
}
public static Deinflections
searchJpDeinflected(
final String verb,
final RomanizationEnum romanization) {
final SearchQuery result = new SearchQuery(DictTypeEnum.Edict);
final String conv = KanjiUtils.halfwidthToKatakana(verb);
final String romaji = RomanizationEnum.NihonShiki.toRomaji(romanization.toHiragana(conv));
final Deinflections deinflections = VerbDeinflection.deinflect(romaji);
result.query = deinflections.deinflectedVerbs.toArray(new String[0]);
for (int i = 0; i < result.query.length; i++) {
result.query[i] = RomanizationEnum.NihonShiki.toHiragana(result.query[i]);
}
result.isJapanese = true;
result.matcher = MatcherEnum.Exact;
deinflections.query = result;
return deinflections;
}
}