package eu.irreality.age.language;
import java.util.StringTokenizer;
import eu.irreality.age.Mobile;
import eu.irreality.age.NaturalLanguage;
import eu.irreality.age.StringMethods;
import eu.irreality.age.World;
import eu.irreality.age.spell.ReferenceNameCorrector;
import eu.irreality.age.spell.SimpleReverseCorrector;
public class Catalan extends NaturalLanguage
{
public Catalan()
{
super("ca");
}
private static String firstWord ( String s )
{
StringTokenizer st = new StringTokenizer(s);
if ( st.hasMoreTokens() ) return st.nextToken();
else return "";
}
private static String restWords ( String s )
{
StringTokenizer st = new StringTokenizer(s);
if ( !st.hasMoreTokens() ) return "";
else
{
st.nextToken();
if ( !st.hasMoreTokens() ) return "";
else return st.nextToken("");
}
}
//
//sustituye los comandos al final del verbo por las ZR's correspondientes
//this method NO LONGER checks if the input is actually a verb, that should be checked outside.
//however, it now (2013-05-07) checks if the OUTPUT is a verb - it won't return outputs with unrecognized verbs.
public String substitutePronouns ( Mobile p , String command , Mentions mentions )
{
String thestring = command;
boolean doneSomething = false;
if ( firstWord(thestring).toLowerCase().endsWith ( "-les" ) && firstWord(thestring).length() > 4 ) //les agafar-les o agafa-les
{
//Pronombre femenino plural.
doneSomething = true;
//lo quitamos
String cut = firstWord(thestring).substring(0,firstWord(thestring).length()-4); // -4 hay que quitar el guión
//añadimos la ZR femenina plural
thestring = cut + " " + mentions.getLastMentionedObjectFP() + " " + restWords(thestring);
doneSomething = true;
}
else if ( firstWord(thestring).toLowerCase().endsWith ( "-los" ) && firstWord(thestring).length() > 4 ) //los agafar-los o agafa-los
{
//Pronombre masculino o neutro plural.
doneSomething = true;
//lo quitamos
String cut = firstWord(thestring).substring(0,firstWord(thestring).length()-4); // -4 hay que quitar el guión
//añadimos la ZR plural
thestring = cut + " " + mentions.getLastMentionedObjectP() + " " + restWords(thestring);
}
else if ( firstWord(thestring).toLowerCase().endsWith ( "-ho" ) && firstWord(thestring).length() > 3 ) // ho agafar-ho
{
//Pronombre masculino singular
doneSomething = true;
//lo quitamos
String cut = firstWord(thestring).substring(0,firstWord(thestring).length()-3); // -3 hay que quitar el guión
//añadimos la ZR masculina singular
thestring = cut + " " + mentions.getLastMentionedObjectMS() + " " + restWords(thestring);
}
else if ( firstWord(thestring).toLowerCase().endsWith ( "-la" ) && firstWord(thestring).length() > 3 ) // agafar-la
{
//Pronombre femenino singular
doneSomething = true;
//lo quitamos
String cut = firstWord(thestring).substring(0,firstWord(thestring).length()-3); // -3 hay que quitar el guión
//añadimos la ZR masculina singular
thestring = cut + " " + mentions.getLastMentionedObjectFS() + " " + restWords(thestring);
}
else if ( ( firstWord(thestring).toLowerCase().endsWith ( "'ls" ) // agafa'ls
|| firstWord(thestring).toLowerCase().endsWith ( "'ls" ) ) // los dos tipos de apostrofe
&& firstWord(thestring).length() > 3 ) // agafa'ls igual para el masculino y fenemino
{
//Pronombre femenino/masculino plural
doneSomething = true;
//lo quitamos
String cut = firstWord(thestring).substring(0,firstWord(thestring).length()-3); // -3 hay que quitar el apostrofe
//añadimos la ZR masculina singular
thestring = cut + " " + mentions.getLastMentionedObjectFS() + " " + restWords(thestring);
}
else if ( ( firstWord(thestring).toLowerCase().endsWith ( "'l" ) // agafa'l, con el apostrofe, hay palabras que acaban en l
|| firstWord(thestring).toLowerCase().endsWith ( "'l" ) ) // los dos tipos de apostrofe
&& firstWord(thestring).length() > 2 ) // agafa'l
{
//Pronombre femenino/masculino singular
doneSomething = true;
//lo quitamos
String cut = firstWord(thestring).substring(0,firstWord(thestring).length()-2); // -3 hay que quitar el apostrofe
//añadimos la ZR masculina singular
thestring = cut + " " + mentions.getLastMentionedObjectFS() + " " + restWords(thestring);
}
//intermediate checkpoint: we store the string at this point, and whether the first word in this current string has a recognized verb.
//we store this because sometimes a verb may look like it has two clitics, but only actually have one.
//for example, suppose the input "mételo" (or "metelo").
//after we substitute "lo", what we have ("mete") is a verb.
//if we keep substituting (see below) thinking that "te" is a clitic, we will reach "me", but this is no longer a verb. "te" was not a clitic, it was a verb termination!
//in cases like that, we will fall back to this intermediate checkpoint.
boolean intermStringIsMeaningful = false;
if ( doneSomething && isVerb(removeAccents(firstWord(thestring))) )
intermStringIsMeaningful = true; //we have done some substitution, and obtained something that can be a verb.
String intermString = thestring;
//rentar-me
//rentar-te
//rentar-se
//these pronouns can appear with the above ones (in combinations like melo, tela, selo, etc.) They can also appear on its own.
if ( firstWord(thestring).toLowerCase().endsWith ( "me" ) || firstWord(thestring).toLowerCase().endsWith ( "te" ) || firstWord(thestring).toLowerCase().endsWith ( "se" ) )
{
/*
este if creo que no hace falta, los puntos cardinales en catalán no se escribe así
*/
if ( !firstWord(thestring).toLowerCase().endsWith("este") && !firstWord(thestring).toLowerCase().endsWith("norte") /*&& lenguaje.esVerboComando ( thestring.substring(0,thestring.length()-2) ) */ )
{
//Pronombre, se refiere al jugador
doneSomething = true;
//lo quitamos
String cut = firstWord(thestring).substring(0,firstWord(thestring).length()-3); // hay que quitar el guión
//añadimos el nombre del jugador
String playerRefName = p.getBestReferenceName(false);
if ( playerRefName == null )
{
p.writeError("Error in player " + p + ": cannot apply pronoun substitution to \"" + firstWord(thestring) + "\" because player has no reference name. Add a singular reference name to fix this.\n" );
return command;
}
thestring = cut + " " + playerRefName + " " + restWords(thestring);
}
}
//if we haven't done any substitutions, we return the original string.
if ( !doneSomething ) return command;
if ( !isVerb(removeAccents(firstWord(thestring))) )
{
if ( intermStringIsMeaningful )
{
//this is the case where we have made two substitutions, so that the first one produced a correct verb,
//but the last one produced something that is not a verb (like substituting "te" and "lo" in "mételo").
//in this case, we go back to the intermediate result (substituting "lo" but not "te"), which is likely to be the correct one according to our verb lists.
thestring = intermString;
}
else
{
//in this case, neither the first nor the second step of the substitution produced a known verb.
//therefore, we return the original string (we could be facing a noun ending with something that looks like a critic but isn't, like
//"bote" or "cola" - substitutions shouldn't have an effect in this case).
return command;
}
}
//{when we reach this point, we have made some substitution and thestring starts with a recognized verb}
StringTokenizer st = new StringTokenizer(thestring.toLowerCase());
String newVerb = st.nextToken().trim();
String unaccentedVerb = this.removeAccents(newVerb); //verbos pierden acentos: cógelo -> cóge <tal> -> coge <tal>
return unaccentedVerb + st.nextToken("");
}
//sustituye los comandos al final del verbo por las ZR's correspondientes
//tambien corrige el verbo
//UNUSED
public String substitutePronounsIfVerb ( Mobile p , String command , Mentions mentions )
{
StringTokenizer st = new StringTokenizer(command);
String origVerb = st.nextToken();
String newCommand = substitutePronouns(p,command,mentions);
newCommand = newCommand.trim();
st = new StringTokenizer(newCommand);
String uncorrectedVerbWithoutPronouns = st.nextToken();
if ( !p.getPropertyValueAsBoolean("noVerbSpellChecking") )
newCommand = this.correctVerb(newCommand);
st = new StringTokenizer(newCommand);
String correctedVerbWithoutPronouns = st.nextToken();
if ( !this.isVerb(correctedVerbWithoutPronouns) ) //maybe change to corrected verb to correct things like "mriate"?
{
//check failed! no way to find a verb here, return original string.
return command;
}
else if ( this.isVerb(correctedVerbWithoutPronouns) && //verb is recognised only if it is corrected, and pronoun substitution has taken place
!this.isVerb(uncorrectedVerbWithoutPronouns) &&
!uncorrectedVerbWithoutPronouns.equals(origVerb) )
{
return command;
}
else
{
//check passed.
return newCommand;
}
}
// a + el = al a + els = als
// de + el = del de + els = dels
// per + el = pel per + els = pels
private String doContractions ( String s )
{
String result = s.replaceAll(" a el"," al");
result = result.replaceAll(" de el"," del");
result = result.replaceAll(" per el"," pel");
result = result.replaceAll(" a els"," als");
result = result.replaceAll(" de els"," dels");
result = result.replaceAll(" per els"," pels");
result = result.replaceAll(" la a", " l'a"); // la avioneta -> l'avioneta
result = result.replaceAll(" la e", " l'e");
result = result.replaceAll(" la o", " l'o");
result = result.replaceAll(" el a", "l'a"); // el avión -> l'avión
result = result.replaceAll(" el e", "l'e");
result = result.replaceAll(" el o", "l'o");
return result;
}
public String correctMorphology ( String s )
{
if ( s == null ) return null;
String niceString = super.correctMorphology(s);
niceString = doContractions(niceString);
//TODO This is a temporary workaround due to the limitations of $oa to parameterize messages as male/female. A more flexible system for that should be added and then this will become unnecessary.
return StringMethods.textualSubstitution ( StringMethods.textualSubstitution ( niceString , "tancado" , " tancat" ) , "mateixo" , "mateix" );
}
public String correctMorphologyWithoutTrimming ( String s )
{
if ( s == null ) return null;
String niceString = super.correctMorphologyWithoutTrimming(s);
niceString = doContractions(niceString);
//TODO This is a temporary workaround due to the limitations of $oa to parameterize messages as male/female. A more flexible system for that should be added and then this will become unnecessary.
return StringMethods.textualSubstitution ( StringMethods.textualSubstitution ( niceString , "tancado" , " tancat" ) , "mateixo" , "mateix" );
}
/**
* Gets a Spanish corrector for the reference names of the given world.
* @param w
* @return
*/
public ReferenceNameCorrector initNameCorrector ( World w )
{
ReferenceNameCorrector base = super.initNameCorrector(w);
//add common synonyms of cardinal directions
base.addDictionaryWord("sud-oest");
base.addDictionaryWord("sud-est");
base.addDictionaryWord("nord-est");
base.addDictionaryWord("nord-oest");
//add articles so that, for example, the article "las" is not corrected to the noun "alas"
base.addDictionaryWord("el");
base.addDictionaryWord("la");
base.addDictionaryWord("els");
base.addDictionaryWord("les");
base.addDictionaryWord("un");
base.addDictionaryWord("una");
base.addDictionaryWord("uns");
base.addDictionaryWord("unes");
//"con": avoid confusion with verb "pon"
//base.addDictionaryWord("con");
return base;
}
/**
* Returns the default verb, i.e., verb that will be used by default if a reference name is typed
* at the beginning of a game without specifying a verb.
*/
public String getDefaultVerb()
{
return "mirar";
}
}