/*
* Copyright (c) 2008 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 plugin.lsttokens.deprecated;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import pcgen.base.lang.StringUtil;
import pcgen.cdom.base.CDOMObject;
import pcgen.cdom.base.CDOMReference;
import pcgen.cdom.base.ChoiceActor;
import pcgen.cdom.base.ChoiceSet;
import pcgen.cdom.base.ChooseInformation;
import pcgen.cdom.base.ConcreteTransitionChoice;
import pcgen.cdom.base.Constants;
import pcgen.cdom.base.FormulaFactory;
import pcgen.cdom.base.TransitionChoice;
import pcgen.cdom.choiceset.ModifyChoiceDecorator;
import pcgen.cdom.choiceset.ReferenceChoiceSet;
import pcgen.cdom.content.CNAbility;
import pcgen.cdom.content.TabInfo;
import pcgen.cdom.enumeration.ObjectKey;
import pcgen.cdom.reference.ReferenceManufacturer;
import pcgen.core.Ability;
import pcgen.core.AbilityCategory;
import pcgen.core.Globals;
import pcgen.core.PlayerCharacter;
import pcgen.core.chooser.CDOMChooserFacadeImpl;
import pcgen.facade.core.ChooserFacade.ChooserTreeViewType;
import pcgen.rules.context.LoadContext;
import pcgen.rules.persistence.TokenUtilities;
import pcgen.rules.persistence.token.AbstractTokenWithSeparator;
import pcgen.rules.persistence.token.CDOMPrimaryToken;
import pcgen.rules.persistence.token.ParseResult;
import pcgen.util.chooser.ChooserFactory;
import pcgen.util.enumeration.Tab;
/**
* Deals with the MODIFYFEATCHOICE token
*/
public class ModifyfeatchoiceToken extends AbstractTokenWithSeparator<Ability>
implements CDOMPrimaryToken<Ability>, ChoiceActor<CNAbility>
{
public static final Class<Ability> ABILITY_CLASS = Ability.class;
@Override
public String getTokenName()
{
return "MODIFYFEATCHOICE";
}
@Override
protected char separator()
{
return '|';
}
@Override
protected ParseResult parseTokenWithSeparator(LoadContext context, Ability ability, String value)
{
StringTokenizer tok = new StringTokenizer(value, Constants.PIPE);
List<CDOMReference<Ability>> refs = new ArrayList<>();
ReferenceManufacturer<Ability> rm = context.getReferenceContext().getManufacturer(
ABILITY_CLASS, AbilityCategory.FEAT);
while (tok.hasMoreTokens())
{
String token = tok.nextToken();
CDOMReference<Ability> ref = TokenUtilities.getTypeOrPrimitive(rm, token);
if (ref == null)
{
return ParseResult.INTERNAL_ERROR;
}
refs.add(ref);
}
ReferenceChoiceSet<Ability> rcs = new ReferenceChoiceSet<>(refs);
ModifyChoiceDecorator gfd = new ModifyChoiceDecorator(rcs);
ChoiceSet<CNAbility> cs = new ChoiceSet<>(getTokenName(), gfd);
TabInfo ti = context.getReferenceContext().silentlyGetConstructedCDOMObject(
TabInfo.class, Tab.ABILITIES.toString());
String singularName = ti.getResolvedName();
if (singularName.endsWith("s"))
{
singularName = singularName.substring(0, singularName.length() - 1);
}
cs.setTitle("Select a " + singularName + " to modify");
TransitionChoice<CNAbility> tc = new ConcreteTransitionChoice<>(cs,
FormulaFactory.ONE);
tc.setRequired(false);
context.getObjectContext().put(ability, ObjectKey.MODIFY_CHOICE, tc);
tc.setChoiceActor(this);
return ParseResult.SUCCESS;
}
@Override
public String[] unparse(LoadContext context, Ability ability)
{
TransitionChoice<CNAbility> mc = context.getObjectContext().getObject(
ability, ObjectKey.MODIFY_CHOICE);
if (mc == null)
{
// Zero indicates no Token
return null;
}
return new String[] { StringUtil.replaceAll(mc.getChoices()
.getLSTformat(), ",", Constants.PIPE) };
}
@Override
public Class<Ability> getTokenClass()
{
return Ability.class;
}
@Override
public void applyChoice(CDOMObject owner, CNAbility choice, PlayerCharacter pc)
{
// build a list of available choices and choices already made.
processApplication(pc, choice, choice.getChooseInfo());
}
private <T> void processApplication(PlayerCharacter pc, CNAbility choice,
ChooseInformation<T> chooseInfo)
{
List<T> available = new ArrayList<>(chooseInfo.getSet(pc));
List<? extends T> selected =
chooseInfo.getChoiceActor().getCurrentlySelected(choice, pc);
final int currentSelections = selected.size();
final List<T> origSelections = new ArrayList<>(selected);
//
// If nothing to choose, or nothing selected, then leave
//
if (available.isEmpty() || (currentSelections == 0))
{
return;
}
Globals.sortChooserLists(available, selected);
CDOMChooserFacadeImpl<T> chooserFacade =
new CDOMChooserFacadeImpl<>(
"Modify selections for " + choice, available,
selected, 0);
chooserFacade.setDefaultView(ChooserTreeViewType.NAME);
ChooserFactory.getDelegate().showGeneralChooser(chooserFacade);
final int selectedSize = chooserFacade.getFinalSelected().size();
if (selectedSize != currentSelections)
{
// need to have the same number of selections when finished
return;
}
List<T> add = new ArrayList<>(chooserFacade.getFinalSelected());
add.removeAll(origSelections);
List<T> remove = new ArrayList<>(origSelections);
remove.removeAll(chooserFacade.getFinalSelected());
for (T selection : remove)
{
chooseInfo.removeChoice(pc, choice, selection);
}
for (T selection : add)
{
chooseInfo.removeChoice(pc, choice, selection);
}
}
@Override
public boolean allow(CNAbility choice, PlayerCharacter pc, boolean allowStack)
{
return true;
}
}