package tc.oc.pgm.broadcast;
import java.time.Duration;
import javax.inject.Inject;
import com.google.common.collect.Range;
import org.jdom2.Element;
import tc.oc.commons.bukkit.localization.MessageTemplate;
import tc.oc.commons.core.util.Comparables;
import tc.oc.pgm.features.FeatureDefinitionParser;
import tc.oc.pgm.filters.matcher.StaticFilter;
import tc.oc.pgm.filters.parser.FilterParser;
import tc.oc.pgm.xml.InvalidXMLException;
import tc.oc.pgm.xml.Node;
import tc.oc.pgm.xml.parser.Parser;
import tc.oc.pgm.xml.parser.PrimitiveParser;
import tc.oc.pgm.xml.property.DurationProperty;
import tc.oc.pgm.xml.property.NumberProperty;
import tc.oc.pgm.xml.property.PropertyBuilderFactory;
public class BroadcastParser implements FeatureDefinitionParser<Broadcast> {
private final PropertyBuilderFactory<Integer, NumberProperty<Integer>> integers;
private final PropertyBuilderFactory<Duration, DurationProperty> durations;
private final PrimitiveParser<Broadcast.Type> broadcastTypeParser;
private final FilterParser filterParser;
private final Parser<MessageTemplate> messageParser;
@Inject BroadcastParser(FilterParser filterParser,
Parser<MessageTemplate> messageParser,
PropertyBuilderFactory<Integer, NumberProperty<Integer>> integers,
PropertyBuilderFactory<Duration, DurationProperty> durations,
PrimitiveParser<Broadcast.Type> broadcastTypeParser) {
this.filterParser = filterParser;
this.messageParser = messageParser;
this.integers = integers;
this.durations = durations;
this.broadcastTypeParser = broadcastTypeParser;
}
@Override
public Broadcast parseElement(Element el) throws InvalidXMLException {
final Node node = new Node(el);
final Duration after = durations.property(el, "after").required();
Duration every = durations.property(el, "every")
.optional(null);
int count = integers.property(el, "count")
.range(Range.atLeast(1))
.infinity(true)
.optional(1);
if(count > 1 && every == null) {
// If a repeat count is specified but no interval, use the initial delay as the interval
every = after;
} else if(count == 1 && every != null) {
// If a repeat interval is specified but no count, repeat forever
count = Integer.MAX_VALUE;
}
if(every != null && Comparables.lessThan(every, Broadcast.MIN_INTERVAL)) {
throw new InvalidXMLException(
"Broadcast repeat interval must be at least " +
Broadcast.MIN_INTERVAL.toMillis() + "ms",
el
);
}
return new Broadcast(
broadcastTypeParser.parse(node, el.getName()),
after, every, count,
messageParser.parse(node),
filterParser.property(el, "filter").optional(StaticFilter.ALLOW)
);
}
}