package com.xenoage.zong.io.midi.out.repetitions;
import com.xenoage.utils.collections.CList;
import com.xenoage.zong.core.Score;
import com.xenoage.zong.core.music.volta.Volta;
import com.xenoage.zong.io.midi.out.repetitions.VoltaGroup.VoltaStartMeasure;
import lombok.AllArgsConstructor;
import lombok.val;
import static com.xenoage.utils.collections.CList.clist;
/**
* Finds the {@link VoltaGroup}s in a score.
*
* A volta group is a list of consecutive voltas. See {@link Volta} for more details
* and ordering rules.
*
* @author Andreas Wenger
*/
@AllArgsConstructor
public class VoltaGroupFinder {
private final Score score;
/**
* Finds all {@link VoltaGroup}s in the score.
* The groups are returned in a map with their start measure index as the key.
*/
public VoltaGroups findAllVoltaGroups() {
CList<VoltaGroup> groups = clist();
val scoreHeader = score.getHeader();
for (int measure = 0; measure < score.getMeasuresCount();) {
if (scoreHeader.getColumnHeader(measure).getVolta() != null) {
val voltaGroup = findVoltaGroup(measure);
groups.add(voltaGroup);
measure += voltaGroup.getMeasuresCount();
}
else {
measure ++;
}
}
return new VoltaGroups(groups.close());
}
/**
* Collects all consecutive {@link Volta}s starting at the given measure
* into a {@link VoltaGroup}.
*/
private VoltaGroup findVoltaGroup(int startMeasure) {
CList<VoltaStartMeasure> voltasMeasures = clist();
val scoreHeader = score.getHeader();
for (int measure = startMeasure; measure < score.getMeasuresCount();) {
Volta volta = scoreHeader.getColumnHeader(measure).getVolta();
if (volta != null) {
voltasMeasures.add(new VoltaStartMeasure(volta, measure));
measure += volta.getLength();
}
else {
break;
}
}
return new VoltaGroup(voltasMeasures.close());
}
}