-- Author: John Maxwell
-- Last Edited by: Maxwell, November 18, 1983 9:02 am

DIRECTORY
    MusicDefs: FROM "MusicDefs";

Chord: DEFINITIONS IMPORTS MusicDefs = 
BEGIN
OPEN MusicDefs;

default: INTEGER = 1000;

Draw: PROC[score: ScorePTR, c: ChordPTR, stem: INTEGER ← default]; 
-- default means that the stem is drawn as part of a beam
Adjust: PROCEDURE[sheet: SheetPTR, c: ChordPTR];

SetDefaultStem: PROCEDURE[sheet: SheetPTR, c: ChordPTR];
Sort: PROCEDURE[c: ChordPTR, up: BOOLEAN] RETURNS[n: CARDINAL];

AddNote: PROCEDURE[score: ScorePTR, chord: ChordPTR, note: NotePTR] 
	RETURNS[new: ChordPTR]; -- may need to create new chord
-- removes the note from its chord, if any
-- adds the note to the chord's sync, if any
-- sets note.beam to the chord's beam if it has one,
-- otherwise the chord replaces the note in note.beam.
RemoveNote: PROCEDURE[score: ScorePTR, chord: ChordPTR, note: NotePTR, 
	free: BOOLEAN ← TRUE];
-- removes note from chord.  sets n.beam to NIL.  
-- If chord.length < 2 and free = TRUE, then chord is freed.

New: PROC[score: ScorePTR, length: CARDINAL ← 10, old: ChordPTR ← NIL] 
	RETURNS[chord: ChordPTR]; -- frees old after copying data
Free: PROC[score: ScorePTR, chord: ChordPTR]; 
-- removes chord from anything that points to it, then frees it.

-- INLINE Procedures

Beam: PUBLIC PROC[c: ChordPTR] RETURNS[BeamPTR] = INLINE
   {RETURN[IF c.note[0] # NIL THEN c.note[0].beam ELSE NIL]};

SetBeam: PUBLIC PROC[c: ChordPTR, b: BeamPTR] = INLINE
   {FOR i: CARDINAL IN [0..c.length) DO c.note[i].beam ← b; ENDLOOP};

GetHeapIndex: PUBLIC PROC[heap: ChordHeapPTR, c: ChordPTR] RETURNS[CARDINAL] = INLINE
   {FOR i: CARDINAL IN [0..heap.length) DO 
		IF heap.chord[i] = c THEN RETURN[i]; 
		ENDLOOP; 
    RETURN[heap.length]}; 

Grace: PROCEDURE[c: ChordPTR] RETURNS[BOOLEAN] = INLINE
   {FOR i: CARDINAL IN [0..c.length) DO
		IF ~c.note[i].grace THEN RETURN[FALSE];
		ENDLOOP;
    RETURN[TRUE]};

InVoice: PROCEDURE[c: ChordPTR, voice: CARDINAL] RETURNS[BOOLEAN] = INLINE
   {IF voice = noVoice THEN RETURN[TRUE];
    FOR i: CARDINAL IN [0..c.length) DO
    	IF c.note[i].voice = voice THEN RETURN[TRUE];
    	ENDLOOP;
    RETURN[FALSE]};

Length: PROC[c: ChordPTR] RETURNS[CARDINAL] = INLINE {RETURN[c.length]};

Width: PROCEDURE[c: ChordPTR] RETURNS[INTEGER] = INLINE
   {RETURN[IF Grace[c] THEN 5 ELSE 8]}; 

END..