package vermilion;

import java.util.ArrayList;
import java.util.TreeMap;

/**
 * Represents a pattern cue currently being played on a master track. Stores
 * the machine ID the pattern cues are to be sent to and the pattern node that
 * was cued.
 * This is created when a pattern cue is played and is kept in a list by the
 * SystemComposer where it is used to generate the cues that occur in the
 * pattern. When the pattern is finished it will be removed from the list by the
 * composer.
 */
class PlayingPattern
{
    /**
     * The next tick that is going to play. Once the tick's time has arrived
     * we will provide the cues for that tick.
     */
    public int nextPatternTick;

    /**
     * The pattern that is being played. We actually get all the cues out
     * immediately on construction but we hold this reference for... reference.
     */
    public PatternNode pattern;

    /**
     * The timescale time at which the next tick will occur.
     */
    public long nextTickTime = 0;

    /**
     * The time signature of the pattern, for calculating the tick length.
     */
    private int patternTimeSig = 4;

    // TODO: Fractional tick display for non-master pattern cursors.
    /**
     * The tick position of the playback cursor, which we read for display.
     */
    public double tickCursor;

    public String machineID;

    /**
     * The events which we unpack from the pattern into playback events.
     */
    //private TreeMap<Integer, ArrayList<PlaybackEvent>> events;

    // TODO: Efficiency - there is a large overhead on this call which probably
    // isn't saving that much work (if not creating it).
    /**
     * The constructor actually unpacks all events for the pattern in one go,
     * so they can be quickly accessed from then on.
     */
    public PlayingPattern(PatternNode node, String machID, long startTime)
    {
        pattern = node;
        nextTickTime = startTime;
        tickCursor = 0.0;
        patternTimeSig = node.timeSig;
        machineID = machID;

    }

    /**
     * This is called when a tick occurs to return the events and advance
     * the cursor.
     */
    public void getEvents(ArrayList<Object> buffer, int barsPerTenMinutes)
    {
        //System.out.println(pattern.patternID + " tick " + nextPatternTick);

        for (UsefulFileObject obj : pattern.tracks.arrayValue)
        {
            PatternTrackNode node = (PatternTrackNode) obj;
            ParameterBase param = (ParameterBase) node.commands.get(nextPatternTick);
            if (param != null) buffer.add(new PlaybackEvent(machineID, node.paramName, param, node.groupNumber));
        }

        tickCursor = nextPatternTick;
        nextTickTime += 600 * SystemComposerPlayback.TIME_RES / barsPerTenMinutes / patternTimeSig;
        nextPatternTick++;
    }
}
