/*
 * Copyright 1999-2004 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package javax.sound.midi;

import java.util.Vector;
import com.sun.media.sound.MidiUtils;


/**
 * A <code>Sequence</code> is a data structure containing musical
 * information (often an entire song or composition) that can be played
 * back by a <code>{@link Sequencer}</code> object. Specifically, the
 * <code>Sequence</code> contains timing
 * information and one or more tracks.  Each <code>{@link Track track}</code> consists of a
 * series of MIDI events (such as note-ons, note-offs, program changes, and meta-events).
 * The sequence's timing information specifies the type of unit that is used
 * to time-stamp the events in the sequence.
 * <p>
 * A <code>Sequence</code> can be created from a MIDI file by reading the file
 * into an input stream and invoking one of the <code>getSequence</code> methods of
 * {@link MidiSystem}.  A sequence can also be built from scratch by adding new
 * <code>Tracks</code> to an empty <code>Sequence</code>, and adding
 * <code>{@link MidiEvent}</code> objects to these <code>Tracks</code>.
 *
 * @see Sequencer#setSequence(java.io.InputStream stream)
 * @see Sequencer#setSequence(Sequence sequence)
 * @see Track#add(MidiEvent)
 * @see MidiFileFormat
 *
 * @author Kara Kytle
 */
public class Sequence {


    // Timing types

    /**
     * The tempo-based timing type, for which the resolution is expressed in pulses (ticks) per quarter note.
     * @see #Sequence(float, int)
     */
    public static final float PPQ                                                       = 0.0f;

    /**
     * The SMPTE-based timing type with 24 frames per second (resolution is expressed in ticks per frame).
     * @see #Sequence(float, int)
     */
    public static final float SMPTE_24                                          = 24.0f;

    /**
     * The SMPTE-based timing type with 25 frames per second (resolution is expressed in ticks per frame).
     * @see #Sequence(float, int)
     */
    public static final float SMPTE_25                                          = 25.0f;

    /**
     * The SMPTE-based timing type with 29.97 frames per second (resolution is expressed in ticks per frame).
     * @see #Sequence(float, int)
     */
    public static final float SMPTE_30DROP                                      = 29.97f;

    /**
     * The SMPTE-based timing type with 30 frames per second (resolution is expressed in ticks per frame).
     * @see #Sequence(float, int)
     */
    public static final float SMPTE_30                                          = 30.0f;


    // Variables

    /**
     * The timing division type of the sequence.
     * @see #PPQ
     * @see #SMPTE_24
     * @see #SMPTE_25
     * @see #SMPTE_30DROP
     * @see #SMPTE_30
     * @see #getDivisionType
     */
    protected float divisionType;

    /**
     * The timing resolution of the sequence.
     * @see #getResolution
     */
    protected int resolution;

    /**
     * The MIDI tracks in this sequence.
     * @see #getTracks
     */
    protected Vector<Track> tracks = new Vector<Track>();


    /**
     * Constructs a new MIDI sequence with the specified timing division
     * type and timing resolution.  The division type must be one of the
     * recognized MIDI timing types.  For tempo-based timing,
     * <code>divisionType</code> is PPQ (pulses per quarter note) and
     * the resolution is specified in ticks per beat.  For SMTPE timing,
     * <code>divisionType</code> specifies the number of frames per
     * second and the resolution is specified in ticks per frame.
     * The sequence will contain no initial tracks.  Tracks may be
     * added to or removed from the sequence using <code>{@link #createTrack}</code>
     * and <code>{@link #deleteTrack}</code>.
     *
     * @param divisionType the timing division type (PPQ or one of the SMPTE types)
     * @param resolution the timing resolution
     * @throws InvalidMidiDataException if <code>divisionType</code> is not valid
     *
     * @see #PPQ
     * @see #SMPTE_24
     * @see #SMPTE_25
     * @see #SMPTE_30DROP
     * @see #SMPTE_30
     * @see #getDivisionType
     * @see #getResolution
     * @see #getTracks
     */
    public Sequence(float divisionType, int resolution) throws InvalidMidiDataException {

        if (divisionType == PPQ)
            this.divisionType = PPQ;
        else if (divisionType == SMPTE_24)
            this.divisionType = SMPTE_24;
        else if (divisionType == SMPTE_25)
            this.divisionType = SMPTE_25;
        else if (divisionType == SMPTE_30DROP)
            this.divisionType = SMPTE_30DROP;
        else if (divisionType == SMPTE_30)
            this.divisionType = SMPTE_30;
        else throw new InvalidMidiDataException("Unsupported division type: " + divisionType);

        this.resolution = resolution;
    }


    /**
     * Constructs a new MIDI sequence with the specified timing division
     * type, timing resolution, and number of tracks.  The division type must be one of the
     * recognized MIDI timing types.  For tempo-based timing,
     * <code>divisionType</code> is PPQ (pulses per quarter note) and
     * the resolution is specified in ticks per beat.  For SMTPE timing,
     * <code>divisionType</code> specifies the number of frames per
     * second and the resolution is specified in ticks per frame.
     * The sequence will be initialized with the number of tracks specified by
     * <code>numTracks</code>. These tracks are initially empty (i.e.
     * they contain only the meta-event End of Track).
     * The tracks may be retrieved for editing using the <code>{@link #getTracks}</code>
     * method.  Additional tracks may be added, or existing tracks removed,
     * using <code>{@link #createTrack}</code> and <code>{@link #deleteTrack}</code>.
     *
     * @param divisionType the timing division type (PPQ or one of the SMPTE types)
     * @param resolution the timing resolution
     * @param numTracks the initial number of tracks in the sequence.
     * @throws InvalidMidiDataException if <code>divisionType</code> is not valid
     *
     * @see #PPQ
     * @see #SMPTE_24
     * @see #SMPTE_25
     * @see #SMPTE_30DROP
     * @see #SMPTE_30
     * @see #getDivisionType
     * @see #getResolution
     */
    public Sequence(float divisionType, int resolution, int numTracks) throws InvalidMidiDataException {

        if (divisionType == PPQ)
            this.divisionType = PPQ;
        else if (divisionType == SMPTE_24)
            this.divisionType = SMPTE_24;
        else if (divisionType == SMPTE_25)
            this.divisionType = SMPTE_25;
        else if (divisionType == SMPTE_30DROP)
            this.divisionType = SMPTE_30DROP;
        else if (divisionType == SMPTE_30)
            this.divisionType = SMPTE_30;
        else throw new InvalidMidiDataException("Unsupported division type: " + divisionType);

        this.resolution = resolution;

        for (int i = 0; i < numTracks; i++) {
            tracks.addElement(new Track());
        }
    }


    /**
     * Obtains the timing division type for this sequence.
     * @return the division type (PPQ or one of the SMPTE types)
     *
     * @see #PPQ
     * @see #SMPTE_24
     * @see #SMPTE_25
     * @see #SMPTE_30DROP
     * @see #SMPTE_30
     * @see #Sequence(float, int)
     * @see MidiFileFormat#getDivisionType()
     */
    public float getDivisionType() {
        return divisionType;
    }


    /**
     * Obtains the timing resolution for this sequence.
     * If the sequence's division type is PPQ, the resolution is specified in ticks per beat.
     * For SMTPE timing, the resolution is specified in ticks per frame.
     *
     * @return the number of ticks per beat (PPQ) or per frame (SMPTE)
     * @see #getDivisionType
     * @see #Sequence(float, int)
     * @see MidiFileFormat#getResolution()
     */
    public int getResolution() {
        return resolution;
    }


    /**
     * Creates a new, initially empty track as part of this sequence.
     * The track initially contains the meta-event End of Track.
     * The newly created track is returned.  All tracks in the sequence
     * may be retrieved using <code>{@link #getTracks}</code>.  Tracks may be
     * removed from the sequence using <code>{@link #deleteTrack}</code>.
     * @return the newly created track
     */
    public Track createTrack() {

        Track track = new Track();
        tracks.addElement(track);

        return track;
    }


    /**
     * Removes the specified track from the sequence.
     * @param track the track to remove
     * @return <code>true</code> if the track existed in the track and was removed,
     * otherwise <code>false</code>.
     *
     * @see #createTrack
     * @see #getTracks
     */
    public boolean deleteTrack(Track track) {

        synchronized(tracks) {

            return tracks.removeElement(track);
        }
    }


    /**
     * Obtains an array containing all the tracks in this sequence.
     * If the sequence contains no tracks, an array of length 0 is returned.
     * @return the array of tracks
     *
     * @see #createTrack
     * @see #deleteTrack
     */
    public Track[] getTracks() {

        return (Track[]) tracks.toArray(new Track[tracks.size()]);
    }


    /**
     * Obtains the duration of this sequence, expressed in microseconds.
     * @return this sequence's duration in microseconds.
     */
    public long getMicrosecondLength() {

        return com.sun.media.sound.MidiUtils.tick2microsecond(this, getTickLength(), null);
    }


    /**
     * Obtains the duration of this sequence, expressed in MIDI ticks.
     *
     * @return this sequence's length in ticks
     *
     * @see #getMicrosecondLength
     */
    public long getTickLength() {

        long length = 0;

        synchronized(tracks) {

            for(int i=0; i<tracks.size(); i++ ) {
                long temp = ((Track)tracks.elementAt(i)).ticks();
                if( temp>length ) {
                    length = temp;
                }
            }
            return length;
        }
    }


    /**
     * Obtains a list of patches referenced in this sequence.
     * This patch list may be used to load the required
     * <code>{@link Instrument}</code> objects
     * into a <code>{@link Synthesizer}</code>.
     *
     * @return an array of <code>{@link Patch}</code> objects used in this sequence
     *
     * @see Synthesizer#loadInstruments(Soundbank, Patch[])
     */
    public Patch[] getPatchList() {

        // $$kk: 04.09.99: need to implement!!
        return new Patch[0];
    }
}
