package com.xenoage.zong.musiclayout.notator.chord;
import static com.xenoage.zong.musiclayout.notator.chord.accidentals.ManyAccidentals.manyAccidentals;
import static com.xenoage.zong.musiclayout.notator.chord.accidentals.OneAccidental.oneAccidental;
import static com.xenoage.zong.musiclayout.notator.chord.accidentals.ThreeAccidentals.threeAccidentals;
import static com.xenoage.zong.musiclayout.notator.chord.accidentals.TwoAccidentals.twoAccidentals;
import java.util.List;
import com.xenoage.zong.core.music.MusicContext;
import com.xenoage.zong.core.music.Pitch;
import com.xenoage.zong.core.music.chord.Accidental;
import com.xenoage.zong.core.music.chord.Chord;
import com.xenoage.zong.musiclayout.notation.chord.AccidentalsNotation;
import com.xenoage.zong.musiclayout.notation.chord.NoteDisplacement;
import com.xenoage.zong.musiclayout.notation.chord.NotesNotation;
import com.xenoage.zong.musiclayout.notator.chord.accidentals.Strategy;
import com.xenoage.zong.musiclayout.settings.ChordWidths;
/**
* Computes the notations of the accidentals of a given chord.
*
* Some rules are adepted from
* "Ross: The Art of Music Engraving", page 130 ff, and
* "Chlapik: Die Praxis des Notengraphikers", page 48 ff.
*
* @author Andreas Wenger
*/
public class AccidentalsNotator {
public static final AccidentalsNotator accidentalsNotator =
new AccidentalsNotator();
/**
* Computes the notations of the accidentals of the given chord.
* If there are no accidentals, {@link AccidentalsNotation#empty} is returned.
*/
public AccidentalsNotation compute(Chord chord,
NotesNotation notesAlignment, ChordWidths chordWidths, MusicContext mc) {
return compute(chord.getPitches(), notesAlignment.notes,
chordWidths, mc);
}
AccidentalsNotation compute(List<Pitch> pitches, NoteDisplacement[] notes,
ChordWidths chordWidths, MusicContext mc) {
//count number of needed accidentals
int accCount = countAccidentals(pitches, mc);
//there are different alignment algorithms for each number
if (accCount == 0)
return AccidentalsNotation.empty;
else
return getStrategy(accCount).computeAccidentalsDisplacement(
pitches, notes, accCount, chordWidths, mc);
}
private int countAccidentals(List<Pitch> pitches, MusicContext mc) {
int accCount = 0;
for (Pitch pitch : pitches) {
Accidental acc = mc.getAccidental(pitch);
if (acc != null)
accCount++;
}
return accCount;
}
private Strategy getStrategy(int accCount) {
switch (accCount) {
case 0: throw new IllegalArgumentException();
case 1: return oneAccidental;
case 2: return twoAccidentals;
case 3: return threeAccidentals;
default: return manyAccidentals;
}
}
}