/*
* Copyright (c) Thomas Parker, 2010.
*
* 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.cdom.facet.analysis;
import java.util.List;
import pcgen.cdom.base.ItemFacet;
import pcgen.cdom.enumeration.CharID;
import pcgen.cdom.enumeration.Region;
import pcgen.cdom.facet.base.AbstractItemFacet;
import pcgen.cdom.facet.event.DataFacetChangeEvent;
import pcgen.cdom.facet.event.DataFacetChangeListener;
import pcgen.cdom.facet.fact.AgeFacet;
import pcgen.cdom.facet.fact.RegionFacet;
import pcgen.cdom.facet.model.BioSetFacet;
import pcgen.cdom.facet.model.RaceFacet;
import pcgen.core.AgeSet;
import pcgen.core.BioSet;
import pcgen.core.Race;
import pcgen.output.publish.OutputDB;
/**
* AgeSetFacet stores the AgeSet for the Player Character.
*
* @author Tom Parker (thpr [at] yahoo.com)
*/
public class AgeSetFacet extends AbstractItemFacet<CharID, AgeSet> implements
DataFacetChangeListener<CharID, Object>, ItemFacet<CharID, AgeSet>
{
private AgeFacet ageFacet;
private RegionFacet regionFacet;
private RaceFacet raceFacet;
private BioSetFacet bioSetFacet;
/**
* Drives the identification of the active AgeSet for a Player Character
* when certain changes are made to a Player Character.
*
* Triggered when one of the Facets to which AgeSetFacet listens fires a
* DataFacetChangeEvent to indicate a CDOMObject was added to a Player
* Character.
*
* @param dfce
* The DataFacetChangeEvent containing the information about the
* change
*
* @see pcgen.cdom.facet.event.DataFacetChangeListener#dataAdded(pcgen.cdom.facet.event.DataFacetChangeEvent)
*/
@Override
public void dataAdded(DataFacetChangeEvent<CharID, Object> dfce)
{
update(dfce.getCharID());
}
/**
* This method simply drives a global update of the active AgeSet of a
* PlayerCharacter. This is asserted to be simpler to comprehend than
* attempting to do a change-by-change matrix of possible moves between
* AgeSets (which would have to be built from the BioSet).
*
* Since the processing to determine the AgeSet is reasonably simple, since
* this facet will only throw an event if the AgeSet actually changes, and
* since there are a disparate set of objects that can cause a change in the
* AgeSet (e.g. change of Race, change of Age, change of Region), the
* quantity of extra facets to listen to those changes in a unique fashion
* and the complex storage of AgeSets would seem an unreasonable trade in
* complexity vs. this global update.
*
* @param id
* The CharID identifying the Player Character for which the
* active AgeSet should be established (and updated if necessary)
*/
private void update(CharID id)
{
Region region = Region.getConstant(regionFacet.getRegion(id));
AgeSet ageSet =
bioSetFacet.get(id).getAgeSet(region, getAgeSetIndex(id));
if (ageSet == null)
{
remove(id);
}
else
{
set(id, ageSet);
}
}
/**
* Drives the identification of the active AgeSet for a Player Character
* when certain changes are made to a Player Character.
*
* Triggered when one of the Facets to which AgeSetFacet listens fires a
* DataFacetChangeEvent to indicate a CDOMObject was removed from a Player
* Character.
*
* @param dfce
* The DataFacetChangeEvent containing the information about the
* change
*
* @see pcgen.cdom.facet.event.DataFacetChangeListener#dataRemoved(pcgen.cdom.facet.event.DataFacetChangeEvent)
*/
@Override
public void dataRemoved(DataFacetChangeEvent<CharID, Object> dfce)
{
update(dfce.getCharID());
}
/**
* Returns the index of the active AgeSet on the Player Character.
*
* In general, use of this method outside of AgeSetFacet is discouraged. If
* this method is being used, a serious analysis should be taking place to
* determine if the AgeSet itself (in other words, the get method of
* AgeSetFacet) can be used instead.
*
* @param id
* The CharID identifying the Player Character for which the
* index of the active AgeSet should be returned.
* @return The index of the active AgeSet on the Player Character.
*/
public int getAgeSetIndex(CharID id)
{
BioSet bioSet = bioSetFacet.get(id);
String region = regionFacet.getRegion(id);
Race race = raceFacet.get(id);
String raceName = race == null ? "" : race.getKeyName().trim();
List<String> values =
bioSet.getValueInMaps(region, raceName, "BASEAGE");
if (values == null)
{
return 0;
}
int pcAge = ageFacet.getAge(id);
int ageSet = -1;
for (String s : values)
{
int setBaseAge = Integer.parseInt(s);
if (pcAge < setBaseAge)
{
break;
}
++ageSet;
}
//
// Check to see if character is younger than earliest age group
//
if (ageSet < 0)
{
ageSet = 0;
}
return ageSet;
}
public void setAgeFacet(AgeFacet ageFacet)
{
this.ageFacet = ageFacet;
}
public void setRegionFacet(RegionFacet regionFacet)
{
this.regionFacet = regionFacet;
}
public void setRaceFacet(RaceFacet raceFacet)
{
this.raceFacet = raceFacet;
}
public void setBioSetFacet(BioSetFacet bioSetFacet)
{
this.bioSetFacet = bioSetFacet;
}
/**
* Initializes the connections for AgeSetFacet to other facets.
*
* This method is automatically called by the Spring framework during
* initialization of the AgeSetFacet.
*/
public void init()
{
raceFacet.addDataFacetChangeListener(this);
regionFacet.addDataFacetChangeListener(this);
ageFacet.addDataFacetChangeListener(this);
bioSetFacet.addDataFacetChangeListener(this);
OutputDB.register("ageset", this);
}
}