/*
* Copyright (c) 2009 Tom Parker <thpr@users.sourceforge.net>
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
package pcgen.rules.persistence.token;
import java.util.ArrayList;
import java.util.List;
import pcgen.base.lang.StringUtil;
import pcgen.cdom.base.CDOMObject;
import pcgen.gui2.converter.event.TokenProcessEvent;
import pcgen.gui2.converter.event.TokenProcessorPlugin;
public abstract class AbstractPreEqualConvertPlugin implements
TokenProcessorPlugin
{
public static final String FLOW_LEFT = "Set unspecified values to next identified value (items queue until set/equals sign flows left)";
public static final String FLOW_RIGHT = "Set unspecified values to previous identified value (equals sign holds on unspecified items until redefined)";
public static final String SET_ONE = "Set unspecified values to one (identify as 'present')";
// Just process over these magical tokens for now
@Override
public String process(TokenProcessEvent tpe)
{
String formula = tpe.getValue();
int commaLoc = formula.indexOf(',');
if (commaLoc == -1)
{
return "Prerequisite " + tpe.getKey() + " must have a count: "
+ formula;
}
if (commaLoc == formula.length() - 1)
{
return "Prerequisite " + tpe.getKey()
+ " can not have only a count: " + formula;
}
String num = formula.substring(0, commaLoc);
try
{
Integer.parseInt(num);
}
catch (NumberFormatException nfe)
{
return "'" + num + "' in " + tpe.getKey()
+ " is not a valid integer";
}
String rest = formula.substring(commaLoc + 1);
commaLoc = rest.indexOf(',');
if (commaLoc == -1)
{
doPrefix(tpe, num);
int equalLoc = rest.indexOf('=');
if (equalLoc == -1)
{
// No equals
tpe.append(rest);
tpe.append("=1");
}
else
{
// unambiguous
tpe.append(rest);
}
}
else
{
String[] strings = rest.split(",");
int withEquals = 0;
boolean withoutEquals = false;
boolean lastWithEquals = false;
List<String> list = new ArrayList<>();
for (String tok : strings)
{
int equalLoc = tok.indexOf('=');
if (equalLoc == -1)
{
withoutEquals = true;
lastWithEquals = false;
}
else
{
withEquals++;
lastWithEquals = true;
}
list.add(tok);
}
if (withEquals == 1 && lastWithEquals)
{
// Propagate item to all...
String last = strings[strings.length - 1];
int equalLoc = last.indexOf('=');
String equal = last.substring(equalLoc + 1);
doPrefix(tpe, num);
tpe.append(StringUtil.join(list, "=" + equal + ","));
}
else if (withEquals > 0 && withoutEquals)
{
StringBuilder one = new StringBuilder();
StringBuilder left = new StringBuilder();
StringBuilder right = new StringBuilder();
one.append(tpe.getKey());
one.append(':');
one.append(num);
one.append(',');
left.append(tpe.getKey());
left.append(':');
left.append(num);
left.append(',');
right.append(tpe.getKey());
right.append(':');
right.append(num);
right.append(',');
boolean needComma = false;
Integer lastValue = null;
for (int i = 0; i < strings.length; i++)
{
if (needComma)
{
one.append(',');
left.append(',');
right.append(',');
}
needComma = true;
String tok = strings[i];
int equalLoc = tok.indexOf('=');
one.append(tok);
left.append(tok);
right.append(tok);
if (equalLoc == -1)
{
one.append("=1");
right.append('=');
if (lastValue == null)
{
right.append('1');
}
else
{
right.append(lastValue);
}
left.append('=');
left.append(getNextValue(strings, i));
}
else
{
lastValue = Integer.decode(tok.substring(equalLoc + 1));
}
}
List<String> descr = new ArrayList<>();
String oneResult = one.toString();
String rightResult = right.toString();
String leftResult = left.toString();
if (oneResult.equals(leftResult)
&& leftResult.equals(rightResult))
{
tpe.append(oneResult);
}
else
{
descr.add(oneResult + " ... " + SET_ONE);
descr.add(rightResult + " ... " + FLOW_RIGHT);
descr.add(leftResult + " ... " + FLOW_LEFT);
List<String> choice = new ArrayList<>();
choice.add(oneResult);
choice.add(rightResult);
choice.add(leftResult);
String decision = tpe.getDecider().getConversionDecision(
"Resolve ambiguity for " + getProcessedToken()
+ ":" + formula, descr, choice, 0);
tpe.append(decision);
}
}
else if (withEquals > 0) // && !withoutEquals
{
doPrefix(tpe, num);
tpe.append(StringUtil.join(list, ","));
}
else if (withoutEquals) // && withEquals == 0
{
doPrefix(tpe, num);
tpe.append(StringUtil.join(list, "=1,"));
tpe.append("=1");
}
}
tpe.consume();
return null;
}
private void doPrefix(TokenProcessEvent tpe, String num)
{
tpe.append(tpe.getKey());
tpe.append(':');
tpe.append(num);
tpe.append(',');
}
private int getNextValue(String[] strings, int i)
{
for (int j = i + 1; j < strings.length; j++)
{
String tok = strings[j];
int equalLoc = tok.indexOf('=');
if (equalLoc != -1)
{
return Integer.parseInt(tok.substring(equalLoc + 1));
}
}
return 1;
}
@Override
public Class<? extends CDOMObject> getProcessedClass()
{
return CDOMObject.class;
}
}