/* TrackDisplayScheduling.h */

#ifndef Included_TrackDisplayScheduling_h
#define Included_TrackDisplayScheduling_h

/* TrackDisplayScheduling module depends on */
/* MiscInfo.h */
/* Audit */
/* Debug */
/* Definitions */
/* Array */
/* TrackObject */
/* FrameObject */
/* Memory */
/* Fractions */
/* DataMunging */
/* NoteObject */
/* TieTrackPixel */
/* TieTracking */
/* StaffCalibration */

struct TrackDispScheduleRec;
typedef struct TrackDispScheduleRec TrackDispScheduleRec;

/* forward declarations */
struct TrackObjectRec;
struct NoteObjectRec;
struct TieIntersectListRec;

/* how much space between notes */
#define EXTERNALSEPARATION (16)

/* create a new schedule state record */
TrackDispScheduleRec*	NewTrackDisplaySchedule(struct TrackObjectRec* MainTrackObj);

/* dispose of schedule state record */
void									DisposeTrackDisplaySchedule(TrackDispScheduleRec* Schedule);

/* add track to schedule list */
MyBoolean							AddTrackToDisplaySchedule(TrackDispScheduleRec* Schedule,
												struct TrackObjectRec* TrackObj);

/* delete a track from the schedule list */
void									DeleteTrackFromDisplaySchedule(TrackDispScheduleRec* Schedule,
												struct TrackObjectRec* TrackObj);

/* apply schedule to tracks. */
MyBoolean							TrackDisplayScheduleUpdate(TrackDispScheduleRec* Schedule);

/* find out where a pixel position is located in the score.  it returns the */
/* index of the frame the position is on and *OnFrame is True if it was on a frame. */
/* otherwise, it returns the index of the frame that the position precedes and */
/* sets *OnFrame to False.  TrackObj is the track that we want to find positions */
/* with respect to. */
MyBoolean							TrackDisplayPixelToIndex(TrackDispScheduleRec* Schedule,
												struct TrackObjectRec* TrackObj, long PixelPosition,
												MyBoolean* OnFrame, long* Index);

/* mark scheduler so that it recalculates all the stuff.  the track and frame */
/* index specify where recalculation has to start from, so that data before that */
/* doesn't need to be updated. */
void									TrackDisplayScheduleMarkChanged(TrackDispScheduleRec* Schedule,
												struct TrackObjectRec* TrackObj, long FrameIndex);

/* calculate the pixel index for a frame based on it's array index */
MyBoolean							TrackDisplayIndexToPixel(TrackDispScheduleRec* Schedule,
												long TrackIndex, long FrameIndex, long* Pixel);

/* get the number of tracks controlled by this scheduler */
long									TrackDisplayGetNumTracks(TrackDispScheduleRec* Schedule);

/* look up the track index of a specific track */
long									TrackDisplayGetTrackIndex(TrackDispScheduleRec* Schedule,
												struct TrackObjectRec* TrackObj);

/* get the track specified by the index (0..last func return value - 1) */
struct TrackObjectRec*	TrackDisplayGetParticularTrack(TrackDispScheduleRec* Schedule,
												long Index);

/* get the total length of the track */
MyBoolean							TrackDisplayGetTotalLength(TrackDispScheduleRec* Schedule,
												long* LongestLength);

/* find out what NOTE (not frame) is at the specified location.  NIL */
/* is returned if no note is there.  If the flag is clear, then it's a note, */
/* otherwise it's a command.  If you intend to modify it, then pass an address */
/* for FrameIndex so you know what to pass to TrackDisplayScheduleMarkChanged. */
struct NoteObjectRec*	TrackDisplayGetUnderlyingNote(TrackDispScheduleRec* Schedule,
												long TrackIndex, MyBoolean* CommandFlag, long PixelX,
												long* FrameIndex);

/* find out if a certain frame should be drawn.  this is for squashing command */
/* frames from channels other than the front channel */
MyBoolean							TrackDisplayShouldWeDrawIt(TrackDispScheduleRec* Schedule,
												long TrackIndex, long FrameIndex);

/* find out what index a measure bar should be.  if it shouldn't be a measure */
/* bar, then it returns -1. */
long									TrackDisplayMeasureBarIndex(TrackDispScheduleRec* Schedule,
												long FrameIndex);

/* find out the frame index for the specified measure bar.  if it can't find the */
/* specified measure bar, it returns the location for the largest one less than */
/* the value specified.  it returns false if calculation fails. */
MyBoolean							TrackDisplayMeasureIndexToFrame(TrackDispScheduleRec* Schedule,
												long MeasureBarIndex, long* FrameIndexOut);

/* find out if a measure bar should be greyed out or drawn solid.  it returns */
/* true if the measure bar should be greyed. */
MyBoolean							TrackDisplayShouldMeasureBarBeGreyed(
												TrackDispScheduleRec* Schedule, long FrameIndex);

/* get a list of coordinates that need to be tied together */
/* it might return NIL if there isn't a tie tracker. */
struct TieIntersectListRec*	TrackDisplayGetTieIntervalList(TrackDispScheduleRec* Schedule,
												long StartX, long Width);

#endif
