/*
* PrerequisiteMultWriter.java
*
* Copyright 2004 (C) Frugal <frugal@purplewombat.co.uk>
*
* This library 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 library 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Created on 18-Dec-2003
*
* Current Ver: $Revision$
*
*
*
*/
package pcgen.persistence.lst.output.prereq;
import java.io.IOException;
import java.io.Writer;
import pcgen.core.prereq.Prerequisite;
import pcgen.core.prereq.PrerequisiteOperator;
import pcgen.persistence.PersistenceLayerException;
public class PrerequisiteMultWriter extends AbstractPrerequisiteWriter
implements PrerequisiteWriterInterface
{
private boolean allSkillTot = false;
/* (non-Javadoc)
* @see pcgen.persistence.lst.output.prereq.PrerequisiteWriterInterface#kindHandled()
*/
@Override
public String kindHandled()
{
return null;
}
/* (non-Javadoc)
* @see pcgen.persistence.lst.output.prereq.PrerequisiteWriterInterface#operatorsHandled()
*/
@Override
public PrerequisiteOperator[] operatorsHandled()
{
return new PrerequisiteOperator[]{PrerequisiteOperator.GTEQ,
PrerequisiteOperator.LT, PrerequisiteOperator.EQ,
PrerequisiteOperator.NEQ};
}
@Override
public void write(Writer writer, Prerequisite prereq)
throws PersistenceLayerException
{
checkValidOperator(prereq, operatorsHandled());
try
{
Prerequisite subreq;
//
// Check to see if this is a special case for PREMULT
//
if (isSpecialCase(prereq))
{
handleSpecialCase(writer, prereq);
return;
}
if (isNegatedPreability(prereq))
{
handleNegatedPreAbility(writer, prereq);
return;
}
if (prereq.getPrerequisiteCount() != 0)
{
subreq = prereq.getPrerequisites().get(0);
final PrerequisiteWriterInterface test =
PrerequisiteWriterFactory.getInstance().getWriter(
subreq.getKind());
if ((test != null)
&& (test instanceof AbstractPrerequisiteWriter)
&& ((AbstractPrerequisiteWriter) test).specialCase(writer,
prereq))
{
return;
}
}
if (prereq.getOperator().equals(PrerequisiteOperator.LT))
{
writer.write('!');
}
writer.write("PREMULT:");
writer.write(prereq.getOperand());
writer.write(',');
int i = 0;
for (Prerequisite pre : prereq.getPrerequisites())
{
if (i > 0)
{
writer.write(',');
}
writer.write('[');
PrerequisiteWriterFactory factory =
PrerequisiteWriterFactory.getInstance();
PrerequisiteWriterInterface w =
factory.getWriter(pre.getKind());
if (w != null)
{
w.write(writer, pre);
}
else
{
writer.write("unrecognized kind:" + pre.getKind());
}
writer.write(']');
i++;
}
}
catch (IOException e)
{
throw new PersistenceLayerException(e.getMessage());
}
}
/**
* @param writer
* @param prereq
* @throws IOException
*/
private void handleSpecialCase(Writer writer, Prerequisite prereq)
throws IOException
{
if (allSkillTot)
{
if (prereq.getOperator().equals(PrerequisiteOperator.LT))
{
writer.write('!');
}
writer.write("PRESKILLTOT:");
int i = 0;
for (Prerequisite subreq : prereq.getPrerequisites())
{
if (i > 0)
{
writer.write(',');
}
writer.write(subreq.getKey());
i++;
}
writer.write('=');
writer.write(prereq.getOperand());
}
}
/**
* @param prereq
* @return TRUE if special case, else FALSE
*/
private boolean isSpecialCase(Prerequisite prereq)
{
// Special case of all subreqs being SKILL with total-values=true
allSkillTot = true;
for (Prerequisite element : prereq.getPrerequisites())
{
if (!allSkillTot)
{
break;
}
if (!"skill".equalsIgnoreCase(element.getKind())
|| !element.isTotalValues())
{
allSkillTot = false;
}
}
if (allSkillTot)
{
return allSkillTot;
}
return false;
}
/**
* Identify if this is a PREABILITY which has been converted into a PREMULT
* to include a negated check, i.e. ensure a particular ability is not
* present in the character.
*
* @param prereq The PREMULT to be checked.
* @return true if this is a negated PREABILITY, false if not.
*/
private boolean isNegatedPreability(Prerequisite prereq)
{
if (prereq.getPrerequisites().isEmpty())
{
return false;
}
boolean hasNegated = false;
for (Prerequisite element : prereq.getPrerequisites())
{
if (!"ability".equalsIgnoreCase(element.getKind()))
{
return false;
}
if (element.getOperator() == PrerequisiteOperator.LT
&& "1".equals(element.getOperand()))
{
hasNegated = true;
}
}
return hasNegated;
}
/**
* Restore the format of a prereq such as
* PREABILITY:1,CATEGORY=FEAT,[Surprise Strike]
*
* @param writer The output destination writer.
* @param prereq The prereq to be written, must be a negated PREABILITY
* @throws IOException If the output cannot be written.
*/
private void handleNegatedPreAbility(Writer writer, Prerequisite prereq)
throws IOException
{
writer.write("PREABILITY:");
writer.write(String.valueOf(Integer.parseInt(prereq.getOperand()) - 1));
writer.write(",");
String cat = prereq.getPrerequisites().get(0).getCategoryName();
if (cat == null)
{
writer.write("CATEGORY=ANY");
}
else
{
writer.write("CATEGORY=" + cat);
}
for (Prerequisite child : prereq.getPrerequisites())
{
writer.write(",");
if (child.getOperator() == PrerequisiteOperator.LT)
{
writer.write("[");
}
writer.write(child.getKey());
if (child.getSubKey() != null)
{
writer.write(" (");
writer.write(child.getSubKey());
writer.write(")");
}
if (child.getOperator() == PrerequisiteOperator.LT)
{
writer.write("]");
}
}
}
}