/*
 * Track-Assignment handler
 *  Used by iff2ms to assign one or more colors to each track.
 *  Each track is assigned to one color, which will play that track's notes.
 *  However, a track may contain chorded notes, in which case more than
 *  one Music Studio color will be required to play that track's notes.
 */

#include "smus.h"
#include "music.h"

/*
 * Assign colors to tracks which have not matched any adsrname, i.e.
 *  those for which there is no indication of which Music Studio color
 *  should play the notes on this track.
 */
AssignColors(TrackCt)
   int   TrackCt;          /* Number of IFF tracks in this SMUS */
{
   int   NextTrack;           /* track having colors assigned */
   int   FreeColor;           /* color to be assigned */

   for (NextTrack = 0; NextTrack < TrackCt; NextTrack++)
      if (Tracks[NextTrack].Colors == 0)   /* if no assignment this track */
         if ((FreeColor = AFreeColor()) < MAXCOLORS)  /* if free color */
            Tracks[NextTrack].Colors =                /* assign it */
               assign(Tracks[NextTrack].Colors,FreeColor);
      /* Now, for any tracks which still have no colors, assign
         them colors that are already allocated to some other track */
      /* (when TrackCt > MAXCOLORS) */

} /* AssignColors */


/*
 *  Return an as yet unused color that is
 *   available to this track.  Lowest colors checked first.
 */
int
WhichColor(Trak)
   int   Trak;             /* track number to find colors for */
{
   int   WC;
   int   GotCol = MAXCOLORS+1;      /* indicates no color found! */

   for (WC = 0; ((WC < MAXCOLORS) && (GotCol == MAXCOLORS+1)); WC++)
      if (Tracks[Trak].Colors & (1<<WC))
         GotCol = WC;                /* Save color number & stop looping */
   return(GotCol+1);    /* return 1..15 from 0..14 */
}

/* free colors represented as ones in ColorsFree */
static int  ColorsFree = 0xFF;      /* Initially, all colors free */

/*
 *  Assign color ColorNum to track whose current assignment mask
 *   is given by Asgn.  Return the new assignment mask.
 */
int
assign(Asgn,ColorNum)
int Asgn;
int ColorNum;
{
   Asgn = Asgn | (1<<ColorNum);
   ColorsFree = ColorsFree & (~(1<<ColorNum));
   return(Asgn);
}

free(Asgn,ColorNum)
int Asgn;
int ColorNum;
{
   Asgn = Asgn & (~(1<<ColorNum));
   ColorsFree = ColorsFree | (1<<ColorNum);
   return(Asgn);
}

/*
 * Return the color number (0-14) of a color that
 *  has not been assigned to any track.
 *  If all colors already belong to some track,
 *    then return MAXCOLORS
 */

int
AFreeColor()
{
   int   Col;

   for (Col = 0; Col < MAXCOLORS; Col++)
      if ((ColorsFree & (1<<Col)) != 0)
         return(Col);
   return(MAXCOLORS);
}

