/*
 * Copyright (c) 2003, 2014, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.media.sound;

import java.io.IOException;
import java.io.InputStream;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;

import javax.sound.midi.*;


/**
 * A Real Time Sequencer
 *
 * @author Florian Bomers
 */

/* TODO:
 * - rename PlayThread to PlayEngine (because isn't a thread)
 */
final class RealTimeSequencer extends AbstractMidiDevice
        implements Sequencer, AutoConnectSequencer {

    // STATIC VARIABLES

    /** debugging flags */
    private static final boolean DEBUG_PUMP = false;
    private static final boolean DEBUG_PUMP_ALL = false;

    /**
     * Event Dispatcher thread. Should be using a shared event
     * dispatcher instance with a factory in EventDispatcher
     */
    private static final Map<ThreadGroup, EventDispatcher> dispatchers =
            new WeakHashMap<>();

    /**
     * All RealTimeSequencers share this info object.
     */
    static final MidiDevice.Info info = new RealTimeSequencerInfo();


    private static final Sequencer.SyncMode[] masterSyncModes = { Sequencer.SyncMode.INTERNAL_CLOCK };
    private static final Sequencer.SyncMode[] slaveSyncModes  = { Sequencer.SyncMode.NO_SYNC };

    private static final Sequencer.SyncMode masterSyncMode    = Sequencer.SyncMode.INTERNAL_CLOCK;
    private static final Sequencer.SyncMode slaveSyncMode     = Sequencer.SyncMode.NO_SYNC;


    /**
     * Sequence on which this sequencer is operating.
     */
    private Sequence sequence = null;

    // caches

    /**
     * Same for setTempoInMPQ...
     * -1 means not set.
     */
    private double cacheTempoMPQ = -1;


    /**
     * cache value for tempo factor until sequence is set
     * -1 means not set.
     */
    private float cacheTempoFactor = -1;


    /** if a particular track is muted */
    private boolean[] trackMuted = null;
    /** if a particular track is solo */
    private boolean[] trackSolo = null;

    /** tempo cache for getMicrosecondPosition */
    private final MidiUtils.TempoCache tempoCache = new MidiUtils.TempoCache();

    /**
     * True if the sequence is running.
     */
    private boolean running = false;


    /** the thread for pushing out the MIDI messages */
    private PlayThread playThread;


    /**
     * True if we are recording
     */
    private boolean recording = false;


    /**
     * List of tracks to which we're recording
     */
    private final List<RecordingTrack> recordingTracks = new ArrayList<>();


    private long loopStart = 0;
    private long loopEnd = -1;
    private int loopCount = 0;


    /**
     * Meta event listeners
     */
    private final ArrayList<Object> metaEventListeners = new ArrayList<>();


    /**
     * Control change listeners
     */
    private final ArrayList<ControllerListElement> controllerEventListeners = new ArrayList<>();


    /** automatic connection support */
    private boolean autoConnect = false;

    /** if we need to autoconnect at next open */
    private boolean doAutoConnectAtNextOpen = false;

    /** the receiver that this device is auto-connected to */
    Receiver autoConnectedReceiver = null;


    /* ****************************** CONSTRUCTOR ****************************** */

    RealTimeSequencer(){
        super(info);

        if (Printer.trace) Printer.trace(">> RealTimeSequencer CONSTRUCTOR");
        if (Printer.trace) Printer.trace("<< RealTimeSequencer CONSTRUCTOR completed");
    }


    /* ****************************** SEQUENCER METHODS ******************** */

    public synchronized void setSequence(Sequence sequence)
        throws InvalidMidiDataException {

        if (Printer.trace) Printer.trace(">> RealTimeSequencer: setSequence(" + sequence +")");

        if (sequence != this.sequence) {
            if (this.sequence != null && sequence == null) {
                setCaches();
                stop();
                // initialize some non-cached values
                trackMuted = null;
                trackSolo = null;
                loopStart = 0;
                loopEnd = -1;
                loopCount = 0;
                if (getDataPump() != null) {
                    getDataPump().setTickPos(0);
                    getDataPump().resetLoopCount();
                }
            }

            if (playThread != null) {
                playThread.setSequence(sequence);
            }

            // store this sequence (do not copy - we want to give the possibility
            // of modifying the sequence at runtime)
            this.sequence = sequence;

            if (sequence != null) {
                tempoCache.refresh(sequence);
                // rewind to the beginning
                setTickPosition(0);
                // propagate caches
                propagateCaches();
            }
        }
        else if (sequence != null) {
            tempoCache.refresh(sequence);
            if (playThread != null) {
                playThread.setSequence(sequence);
            }
        }

        if (Printer.trace) Printer.trace("<< RealTimeSequencer: setSequence(" + sequence +") completed");
    }


    public synchronized void setSequence(InputStream stream) throws IOException, InvalidMidiDataException {

        if (Printer.trace) Printer.trace(">> RealTimeSequencer: setSequence(" + stream +")");

        if (stream == null) {
            setSequence((Sequence) null);
            return;
        }

        Sequence seq = MidiSystem.getSequence(stream); // can throw IOException, InvalidMidiDataException

        setSequence(seq);

        if (Printer.trace) Printer.trace("<< RealTimeSequencer: setSequence(" + stream +") completed");

    }


    public Sequence getSequence() {
        return sequence;
    }


    public synchronized void start() {
        if (Printer.trace) Printer.trace(">> RealTimeSequencer: start()");

        // sequencer not open: throw an exception
        if (!isOpen()) {
            throw new IllegalStateException("sequencer not open");
        }

        // sequence not available: throw an exception
        if (sequence == null) {
            throw new IllegalStateException("sequence not set");
        }

        // already running: return quietly
        if (running == true) {
            return;
        }

        // start playback
        implStart();

        if (Printer.trace) Printer.trace("<< RealTimeSequencer: start() completed");
    }


    public synchronized void stop() {
        if (Printer.trace) Printer.trace(">> RealTimeSequencer: stop()");

        if (!isOpen()) {
            throw new IllegalStateException("sequencer not open");
        }
        stopRecording();

        // not running; just return
        if (running == false) {
            if (Printer.trace) Printer.trace("<< RealTimeSequencer: stop() not running!");
            return;
        }

        // stop playback
        implStop();

        if (Printer.trace) Printer.trace("<< RealTimeSequencer: stop() completed");
    }


    public boolean isRunning() {
        return running;
    }


    public void startRecording() {
        if (!isOpen()) {
            throw new IllegalStateException("Sequencer not open");
        }

        start();
        recording = true;
    }


    public void stopRecording() {
        if (!isOpen()) {
            throw new IllegalStateException("Sequencer not open");
        }
        recording = false;
    }


    public boolean isRecording() {
        return recording;
    }


    public void recordEnable(Track track, int channel) {
        if (!findTrack(track)) {
            throw new IllegalArgumentException("Track does not exist in the current sequence");
        }

        synchronized(recordingTracks) {
            RecordingTrack rc = RecordingTrack.get(recordingTracks, track);
            if (rc != null) {
                rc.channel = channel;
            } else {
                recordingTracks.add(new RecordingTrack(track, channel));
            }
        }

    }


    public void recordDisable(Track track) {
        synchronized(recordingTracks) {
            RecordingTrack rc = RecordingTrack.get(recordingTracks, track);
            if (rc != null) {
                recordingTracks.remove(rc);
            }
        }

    }


    private boolean findTrack(Track track) {
        boolean found = false;
        if (sequence != null) {
            Track[] tracks = sequence.getTracks();
            for (int i = 0; i < tracks.length; i++) {
                if (track == tracks[i]) {
                    found = true;
                    break;
                }
            }
        }
        return found;
    }


    public float getTempoInBPM() {
        if (Printer.trace) Printer.trace(">> RealTimeSequencer: getTempoInBPM() ");

        return (float) MidiUtils.convertTempo(getTempoInMPQ());
    }


    public void setTempoInBPM(float bpm) {
        if (Printer.trace) Printer.trace(">> RealTimeSequencer: setTempoInBPM() ");
        if (bpm <= 0) {
            // should throw IllegalArgumentException
            bpm = 1.0f;
        }

        setTempoInMPQ((float) MidiUtils.convertTempo((double) bpm));
    }


    public float getTempoInMPQ() {
        if (Printer.trace) Printer.trace(">> RealTimeSequencer: getTempoInMPQ() ");

        if (needCaching()) {
            // if the sequencer is closed, return cached value
            if (cacheTempoMPQ != -1) {
                return (float) cacheTempoMPQ;
            }
            // if sequence is set, return current tempo
            if (sequence != null) {
                return tempoCache.getTempoMPQAt(getTickPosition());
            }

            // last resort: return a standard tempo: 120bpm
            return (float) MidiUtils.DEFAULT_TEMPO_MPQ;
        }
        return getDataPump().getTempoMPQ();
    }


    public void setTempoInMPQ(float mpq) {
        if (mpq <= 0) {
            // should throw IllegalArgumentException
            mpq = 1.0f;
        }

        if (Printer.trace) Printer.trace(">> RealTimeSequencer: setTempoInMPQ() ");

        if (needCaching()) {
            // cache the value
            cacheTempoMPQ = mpq;
        } else {
            // set the native tempo in MPQ
            getDataPump().setTempoMPQ(mpq);

            // reset the tempoInBPM and tempoInMPQ values so we won't use them again
            cacheTempoMPQ = -1;
        }
    }


    public void setTempoFactor(float factor) {
        if (factor <= 0) {
            // should throw IllegalArgumentException
            return;
        }

        if (Printer.trace) Printer.trace(">> RealTimeSequencer: setTempoFactor() ");

        if (needCaching()) {
            cacheTempoFactor = factor;
        } else {
            getDataPump().setTempoFactor(factor);
            // don't need cache anymore
            cacheTempoFactor = -1;
        }
    }


    public float getTempoFactor() {
        if (Printer.trace) Printer.trace(">> RealTimeSequencer: getTempoFactor() ");

        if (needCaching()) {
            if (cacheTempoFactor != -1) {
                return cacheTempoFactor;
            }
            return 1.0f;
        }
        return getDataPump().getTempoFactor();
    }


    public long getTickLength() {
        if (Printer.trace) Printer.trace(">> RealTimeSequencer: getTickLength() ");

        if (sequence == null) {
            return 0;
        }

        return sequence.getTickLength();
    }


    public synchronized long getTickPosition() {
        if (Printer.trace) Printer.trace(">> RealTimeSequencer: getTickPosition() ");

        if (getDataPump() == null || sequence == null) {
            return 0;
        }

        return getDataPump().getTickPos();
    }


    public synchronized void setTickPosition(long tick) {
        if (tick < 0) {
            // should throw IllegalArgumentException
            return;
        }

        if (Printer.trace) Printer.trace(">> RealTimeSequencer: setTickPosition("+tick+") ");

        if (getDataPump() == null) {
            if (tick != 0) {
                // throw new InvalidStateException("cannot set position in closed state");
            }
        }
        else if (sequence == null) {
            if (tick != 0) {
                // throw new InvalidStateException("cannot set position if sequence is not set");
            }
        } else {
            getDataPump().setTickPos(tick);
        }
    }


    public long getMicrosecondLength() {
        if (Printer.trace) Printer.trace(">> RealTimeSequencer: getMicrosecondLength() ");

        if (sequence == null) {
            return 0;
        }

        return sequence.getMicrosecondLength();
    }


    public long getMicrosecondPosition() {
        if (Printer.trace) Printer.trace(">> RealTimeSequencer: getMicrosecondPosition() ");

        if (getDataPump() == null || sequence == null) {
            return 0;
        }
        synchronized (tempoCache) {
            return MidiUtils.tick2microsecond(sequence, getDataPump().getTickPos(), tempoCache);
        }
    }


    public void setMicrosecondPosition(long microseconds) {
        if (microseconds < 0) {
            // should throw IllegalArgumentException
            return;
        }

        if (Printer.trace) Printer.trace(">> RealTimeSequencer: setMicrosecondPosition("+microseconds+") ");

        if (getDataPump() == null) {
            if (microseconds != 0) {
                // throw new InvalidStateException("cannot set position in closed state");
            }
        }
        else if (sequence == null) {
            if (microseconds != 0) {
                // throw new InvalidStateException("cannot set position if sequence is not set");
            }
        } else {
            synchronized(tempoCache) {
                setTickPosition(MidiUtils.microsecond2tick(sequence, microseconds, tempoCache));
            }
        }
    }


    public void setMasterSyncMode(Sequencer.SyncMode sync) {
        // not supported
    }


    public Sequencer.SyncMode getMasterSyncMode() {
        return masterSyncMode;
    }


    public Sequencer.SyncMode[] getMasterSyncModes() {
        Sequencer.SyncMode[] returnedModes = new Sequencer.SyncMode[masterSyncModes.length];
        System.arraycopy(masterSyncModes, 0, returnedModes, 0, masterSyncModes.length);
        return returnedModes;
    }


    public void setSlaveSyncMode(Sequencer.SyncMode sync) {
        // not supported
    }


    public Sequencer.SyncMode getSlaveSyncMode() {
        return slaveSyncMode;
    }


    public Sequencer.SyncMode[] getSlaveSyncModes() {
        Sequencer.SyncMode[] returnedModes = new Sequencer.SyncMode[slaveSyncModes.length];
        System.arraycopy(slaveSyncModes, 0, returnedModes, 0, slaveSyncModes.length);
        return returnedModes;
    }

    int getTrackCount() {
        Sequence seq = getSequence();
        if (seq != null) {
            // $$fb wish there was a nicer way to get the number of tracks...
            return sequence.getTracks().length;
        }
        return 0;
    }



    public synchronized void setTrackMute(int track, boolean mute) {
        int trackCount = getTrackCount();
        if (track < 0 || track >= getTrackCount()) return;
        trackMuted = ensureBoolArraySize(trackMuted, trackCount);
        trackMuted[track] = mute;
        if (getDataPump() != null) {
            getDataPump().muteSoloChanged();
        }
    }


    public synchronized boolean getTrackMute(int track) {
        if (track < 0 || track >= getTrackCount()) return false;
        if (trackMuted == null || trackMuted.length <= track) return false;
        return trackMuted[track];
    }


    public synchronized void setTrackSolo(int track, boolean solo) {
        int trackCount = getTrackCount();
        if (track < 0 || track >= getTrackCount()) return;
        trackSolo = ensureBoolArraySize(trackSolo, trackCount);
        trackSolo[track] = solo;
        if (getDataPump() != null) {
            getDataPump().muteSoloChanged();
        }
    }


    public synchronized boolean getTrackSolo(int track) {
        if (track < 0 || track >= getTrackCount()) return false;
        if (trackSolo == null || trackSolo.length <= track) return false;
        return trackSolo[track];
    }


    public boolean addMetaEventListener(MetaEventListener listener) {
        synchronized(metaEventListeners) {
            if (! metaEventListeners.contains(listener)) {

                metaEventListeners.add(listener);
            }
            return true;
        }
    }


    public void removeMetaEventListener(MetaEventListener listener) {
        synchronized(metaEventListeners) {
            int index = metaEventListeners.indexOf(listener);
            if (index >= 0) {
                metaEventListeners.remove(index);
            }
        }
    }


    public int[] addControllerEventListener(ControllerEventListener listener, int[] controllers) {
        synchronized(controllerEventListeners) {

            // first find the listener.  if we have one, add the controllers
            // if not, create a new element for it.
            ControllerListElement cve = null;
            boolean flag = false;
            for(int i=0; i < controllerEventListeners.size(); i++) {

                cve = controllerEventListeners.get(i);

                if (cve.listener.equals(listener)) {
                    cve.addControllers(controllers);
                    flag = true;
                    break;
                }
            }
            if (!flag) {
                cve = new ControllerListElement(listener, controllers);
                controllerEventListeners.add(cve);
            }

            // and return all the controllers this listener is interested in
            return cve.getControllers();
        }
    }


    public int[] removeControllerEventListener(ControllerEventListener listener, int[] controllers) {
        synchronized(controllerEventListeners) {
            ControllerListElement cve = null;
            boolean flag = false;
            for (int i=0; i < controllerEventListeners.size(); i++) {
                cve = controllerEventListeners.get(i);
                if (cve.listener.equals(listener)) {
                    cve.removeControllers(controllers);
                    flag = true;
                    break;
                }
            }
            if (!flag) {
                return new int[0];
            }
            if (controllers == null) {
                int index = controllerEventListeners.indexOf(cve);
                if (index >= 0) {
                    controllerEventListeners.remove(index);
                }
                return new int[0];
            }
            return cve.getControllers();
        }
    }


    ////////////////// LOOPING (added in 1.5) ///////////////////////

    public void setLoopStartPoint(long tick) {
        if ((tick > getTickLength())
            || ((loopEnd != -1) && (tick > loopEnd))
            || (tick < 0)) {
            throw new IllegalArgumentException("invalid loop start point: "+tick);
        }
        loopStart = tick;
    }

    public long getLoopStartPoint() {
        return loopStart;
    }

    public void setLoopEndPoint(long tick) {
        if ((tick > getTickLength())
            || ((loopStart > tick) && (tick != -1))
            || (tick < -1)) {
            throw new IllegalArgumentException("invalid loop end point: "+tick);
        }
        loopEnd = tick;
    }

    public long getLoopEndPoint() {
        return loopEnd;
    }

    public void setLoopCount(int count) {
        if (count != LOOP_CONTINUOUSLY
            && count < 0) {
            throw new IllegalArgumentException("illegal value for loop count: "+count);
        }
        loopCount = count;
        if (getDataPump() != null) {
            getDataPump().resetLoopCount();
        }
    }

    public int getLoopCount() {
        return loopCount;
    }


    /* *********************************** play control ************************* */

    /*
     */
    protected void implOpen() throws MidiUnavailableException {
        if (Printer.trace) Printer.trace(">> RealTimeSequencer: implOpen()");

        //openInternalSynth();

        // create PlayThread
        playThread = new PlayThread();

        //id = nOpen();
        //if (id == 0) {
        //    throw new MidiUnavailableException("unable to open sequencer");
        //}
        if (sequence != null) {
            playThread.setSequence(sequence);
        }

        // propagate caches
        propagateCaches();

        if (doAutoConnectAtNextOpen) {
            doAutoConnect();
        }
        if (Printer.trace) Printer.trace("<< RealTimeSequencer: implOpen() succeeded");
    }

    private void doAutoConnect() {
        if (Printer.trace) Printer.trace(">> RealTimeSequencer: doAutoConnect()");
        Receiver rec = null;
        // first try to connect to the default synthesizer
        // IMPORTANT: this code needs to be synch'ed with
        //            MidiSystem.getSequencer(boolean), because the same
        //            algorithm needs to be used!
        try {
            Synthesizer synth = MidiSystem.getSynthesizer();
            if (synth instanceof ReferenceCountingDevice) {
                rec = ((ReferenceCountingDevice) synth).getReceiverReferenceCounting();
            } else {
                synth.open();
                try {
                    rec = synth.getReceiver();
                } finally {
                    // make sure that the synth is properly closed
                    if (rec == null) {
                        synth.close();
                    }
                }
            }
        } catch (Exception e) {
            // something went wrong with synth
        }
        if (rec == null) {
            // then try to connect to the default Receiver
            try {
                rec = MidiSystem.getReceiver();
            } catch (Exception e) {
                // something went wrong. Nothing to do then!
            }
        }
        if (rec != null) {
            autoConnectedReceiver = rec;
            try {
                getTransmitter().setReceiver(rec);
            } catch (Exception e) {}
        }
        if (Printer.trace) Printer.trace("<< RealTimeSequencer: doAutoConnect() succeeded");
    }

    private synchronized void propagateCaches() {
        // only set caches if open and sequence is set
        if (sequence != null && isOpen()) {
            if (cacheTempoFactor != -1) {
                setTempoFactor(cacheTempoFactor);
            }
            if (cacheTempoMPQ == -1) {
                setTempoInMPQ((new MidiUtils.TempoCache(sequence)).getTempoMPQAt(getTickPosition()));
            } else {
                setTempoInMPQ((float) cacheTempoMPQ);
            }
        }
    }

    /** populate the caches with the current values */
    private synchronized void setCaches() {
        cacheTempoFactor = getTempoFactor();
        cacheTempoMPQ = getTempoInMPQ();
    }



    protected synchronized void implClose() {
        if (Printer.trace) Printer.trace(">> RealTimeSequencer: implClose() ");

        if (playThread == null) {
            if (Printer.err) Printer.err("RealTimeSequencer.implClose() called, but playThread not instanciated!");
        } else {
            // Interrupt playback loop.
            playThread.close();
            playThread = null;
        }

        super.implClose();

        sequence = null;
        running = false;
        cacheTempoMPQ = -1;
        cacheTempoFactor = -1;
        trackMuted = null;
        trackSolo = null;
        loopStart = 0;
        loopEnd = -1;
        loopCount = 0;

        /** if this sequencer is set to autoconnect, need to
         * re-establish the connection at next open!
         */
        doAutoConnectAtNextOpen = autoConnect;

        if (autoConnectedReceiver != null) {
            try {
                autoConnectedReceiver.close();
            } catch (Exception e) {}
            autoConnectedReceiver = null;
        }

        if (Printer.trace) Printer.trace("<< RealTimeSequencer: implClose() completed");
    }

    void implStart() {
        if (Printer.trace) Printer.trace(">> RealTimeSequencer: implStart()");

        if (playThread == null) {
            if (Printer.err) Printer.err("RealTimeSequencer.implStart() called, but playThread not instanciated!");
            return;
        }

        tempoCache.refresh(sequence);
        if (!running) {
            running  = true;
            playThread.start();
        }
        if (Printer.trace) Printer.trace("<< RealTimeSequencer: implStart() completed");
    }


    void implStop() {
        if (Printer.trace) Printer.trace(">> RealTimeSequencer: implStop()");

        if (playThread == null) {
            if (Printer.err) Printer.err("RealTimeSequencer.implStop() called, but playThread not instanciated!");
            return;
        }

        recording = false;
        if (running) {
            running = false;
            playThread.stop();
        }
        if (Printer.trace) Printer.trace("<< RealTimeSequencer: implStop() completed");
    }

    private static EventDispatcher getEventDispatcher() {
        // create and start the global event thread
        //TODO  need a way to stop this thread when the engine is done
        final ThreadGroup tg = Thread.currentThread().getThreadGroup();
        synchronized (dispatchers) {
            EventDispatcher eventDispatcher = dispatchers.get(tg);
            if (eventDispatcher == null) {
                eventDispatcher = new EventDispatcher();
                dispatchers.put(tg, eventDispatcher);
                eventDispatcher.start();
            }
            return eventDispatcher;
        }
    }

    /**
     * Send midi player events.
     * must not be synchronized on "this"
     */
    void sendMetaEvents(MidiMessage message) {
        if (metaEventListeners.size() == 0) return;

        //if (Printer.debug) Printer.debug("sending a meta event");
        getEventDispatcher().sendAudioEvents(message, metaEventListeners);
    }

    /**
     * Send midi player events.
     */
    void sendControllerEvents(MidiMessage message) {
        int size = controllerEventListeners.size();
        if (size == 0) return;

        //if (Printer.debug) Printer.debug("sending a controller event");

        if (! (message instanceof ShortMessage)) {
            if (Printer.debug) Printer.debug("sendControllerEvents: message is NOT instanceof ShortMessage!");
            return;
        }
        ShortMessage msg = (ShortMessage) message;
        int controller = msg.getData1();
        List<Object> sendToListeners = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            ControllerListElement cve = controllerEventListeners.get(i);
            for(int j = 0; j < cve.controllers.length; j++) {
                if (cve.controllers[j] == controller) {
                    sendToListeners.add(cve.listener);
                    break;
                }
            }
        }
        getEventDispatcher().sendAudioEvents(message, sendToListeners);
    }



    private boolean needCaching() {
        return !isOpen() || (sequence == null) || (playThread == null);
    }

    /**
     * return the data pump instance, owned by play thread
     * if playthread is null, return null.
     * This method is guaranteed to return non-null if
     * needCaching returns false
     */
    private DataPump getDataPump() {
        if (playThread != null) {
            return playThread.getDataPump();
        }
        return null;
    }

    private MidiUtils.TempoCache getTempoCache() {
        return tempoCache;
    }

    private static boolean[] ensureBoolArraySize(boolean[] array, int desiredSize) {
        if (array == null) {
            return new boolean[desiredSize];
        }
        if (array.length < desiredSize) {
            boolean[] newArray = new boolean[desiredSize];
            System.arraycopy(array, 0, newArray, 0, array.length);
            return newArray;
        }
        return array;
    }


    // OVERRIDES OF ABSTRACT MIDI DEVICE METHODS

    protected boolean hasReceivers() {
        return true;
    }

    // for recording
    protected Receiver createReceiver() throws MidiUnavailableException {
        return new SequencerReceiver();
    }


    protected boolean hasTransmitters() {
        return true;
    }


    protected Transmitter createTransmitter() throws MidiUnavailableException {
        return new SequencerTransmitter();
    }


    // interface AutoConnectSequencer
    public void setAutoConnect(Receiver autoConnectedReceiver) {
        this.autoConnect = (autoConnectedReceiver != null);
        this.autoConnectedReceiver = autoConnectedReceiver;
    }



    // INNER CLASSES

    /**
     * An own class to distinguish the class name from
     * the transmitter of other devices
     */
    private class SequencerTransmitter extends BasicTransmitter {
        private SequencerTransmitter() {
            super();
        }
    }


    final class SequencerReceiver extends AbstractReceiver {

        void implSend(MidiMessage message, long timeStamp) {
            if (recording) {
                long tickPos = 0;

                // convert timeStamp to ticks
                if (timeStamp < 0) {
                    tickPos = getTickPosition();
                } else {
                    synchronized(tempoCache) {
                        tickPos = MidiUtils.microsecond2tick(sequence, timeStamp, tempoCache);
                    }
                }

                // and record to the first matching Track
                Track track = null;
                // do not record real-time events
                // see 5048381: NullPointerException when saving a MIDI sequence
                if (message.getLength() > 1) {
                    if (message instanceof ShortMessage) {
                        ShortMessage sm = (ShortMessage) message;
                        // all real-time messages have 0xF in the high nibble of the status byte
                        if ((sm.getStatus() & 0xF0) != 0xF0) {
                            track = RecordingTrack.get(recordingTracks, sm.getChannel());
                        }
                    } else {
                        // $$jb: where to record meta, sysex events?
                        // $$fb: the first recording track
                        track = RecordingTrack.get(recordingTracks, -1);
                    }
                    if (track != null) {
                        // create a copy of this message
                        if (message instanceof ShortMessage) {
                            message = new FastShortMessage((ShortMessage) message);
                        } else {
                            message = (MidiMessage) message.clone();
                        }

                        // create new MidiEvent
                        MidiEvent me = new MidiEvent(message, tickPos);
                        track.add(me);
                    }
                }
            }
        }
    }


    private static class RealTimeSequencerInfo extends MidiDevice.Info {

        private static final String name = "Real Time Sequencer";
        private static final String vendor = "Oracle Corporation";
        private static final String description = "Software sequencer";
        private static final String version = "Version 1.0";

        RealTimeSequencerInfo() {
            super(name, vendor, description, version);
        }
    } // class Info


    private class ControllerListElement {

        // $$jb: using an array for controllers b/c its
        //       easier to deal with than turning all the
        //       ints into objects to use a Vector
        int []  controllers;
        final ControllerEventListener listener;

        private ControllerListElement(ControllerEventListener listener, int[] controllers) {

            this.listener = listener;
            if (controllers == null) {
                controllers = new int[128];
                for (int i = 0; i < 128; i++) {
                    controllers[i] = i;
                }
            }
            this.controllers = controllers;
        }

        private void addControllers(int[] c) {

            if (c==null) {
                controllers = new int[128];
                for (int i = 0; i < 128; i++) {
                    controllers[i] = i;
                }
                return;
            }
            int temp[] = new int[ controllers.length + c.length ];
            int elements;

            // first add what we have
            for(int i=0; i<controllers.length; i++) {
                temp[i] = controllers[i];
            }
            elements = controllers.length;
            // now add the new controllers only if we don't already have them
            for(int i=0; i<c.length; i++) {
                boolean flag = false;

                for(int j=0; j<controllers.length; j++) {
                    if (c[i] == controllers[j]) {
                        flag = true;
                        break;
                    }
                }
                if (!flag) {
                    temp[elements++] = c[i];
                }
            }
            // now keep only the elements we need
            int newc[] = new int[ elements ];
            for(int i=0; i<elements; i++){
                newc[i] = temp[i];
            }
            controllers = newc;
        }

        private void removeControllers(int[] c) {

            if (c==null) {
                controllers = new int[0];
            } else {
                int temp[] = new int[ controllers.length ];
                int elements = 0;


                for(int i=0; i<controllers.length; i++){
                    boolean flag = false;
                    for(int j=0; j<c.length; j++) {
                        if (controllers[i] == c[j]) {
                            flag = true;
                            break;
                        }
                    }
                    if (!flag){
                        temp[elements++] = controllers[i];
                    }
                }
                // now keep only the elements remaining
                int newc[] = new int[ elements ];
                for(int i=0; i<elements; i++) {
                    newc[i] = temp[i];
                }
                controllers = newc;

            }
        }

        private int[] getControllers() {

            // return a copy of our array of controllers,
            // so others can't mess with it
            if (controllers == null) {
                return null;
            }

            int c[] = new int[controllers.length];

            for(int i=0; i<controllers.length; i++){
                c[i] = controllers[i];
            }
            return c;
        }

    } // class ControllerListElement


    static class RecordingTrack {

        private final Track track;
        private int channel;

        RecordingTrack(Track track, int channel) {
            this.track = track;
            this.channel = channel;
        }

        static RecordingTrack get(List<RecordingTrack> recordingTracks, Track track) {

            synchronized(recordingTracks) {
                int size = recordingTracks.size();

                for (int i = 0; i < size; i++) {
                    RecordingTrack current = recordingTracks.get(i);
                    if (current.track == track) {
                        return current;
                    }
                }
            }
            return null;
        }

        static Track get(List<RecordingTrack> recordingTracks, int channel) {

            synchronized(recordingTracks) {
                int size = recordingTracks.size();
                for (int i = 0; i < size; i++) {
                    RecordingTrack current = recordingTracks.get(i);
                    if ((current.channel == channel) || (current.channel == -1)) {
                        return current.track;
                    }
                }
            }
            return null;

        }
    }


    final class PlayThread implements Runnable {
        private Thread thread;
        private final Object lock = new Object();

        /** true if playback is interrupted (in close) */
        boolean interrupted = false;
        boolean isPumping = false;

        private final DataPump dataPump = new DataPump();


        PlayThread() {
            // nearly MAX_PRIORITY
            int priority = Thread.NORM_PRIORITY
                + ((Thread.MAX_PRIORITY - Thread.NORM_PRIORITY) * 3) / 4;
            thread = JSSecurityManager.createThread(this,
                                                    "Java Sound Sequencer", // name
                                                    false,                  // daemon
                                                    priority,               // priority
                                                    true);                  // doStart
        }

        DataPump getDataPump() {
            return dataPump;
        }

        synchronized void setSequence(Sequence seq) {
            dataPump.setSequence(seq);
        }


        /** start thread and pump. Requires up-to-date tempoCache */
        synchronized void start() {
            // mark the sequencer running
            running = true;

            if (!dataPump.hasCachedTempo()) {
                long tickPos = getTickPosition();
                dataPump.setTempoMPQ(tempoCache.getTempoMPQAt(tickPos));
            }
            dataPump.checkPointMillis = 0; // means restarted
            dataPump.clearNoteOnCache();
            dataPump.needReindex = true;

            dataPump.resetLoopCount();

            // notify the thread
            synchronized(lock) {
                lock.notifyAll();
            }

            if (Printer.debug) Printer.debug(" ->Started MIDI play thread");

        }

        // waits until stopped
        synchronized void stop() {
            playThreadImplStop();
            long t = System.nanoTime() / 1000000l;
            while (isPumping) {
                synchronized(lock) {
                    try {
                        lock.wait(2000);
                    } catch (InterruptedException ie) {
                        // ignore
                    }
                }
                // don't wait for more than 2 seconds
                if ((System.nanoTime()/1000000l) - t > 1900) {
                    if (Printer.err) Printer.err("Waited more than 2 seconds in RealTimeSequencer.PlayThread.stop()!");
                    //break;
                }
            }
        }

        void playThreadImplStop() {
            // mark the sequencer running
            running = false;
            synchronized(lock) {
                lock.notifyAll();
            }
        }

        void close() {
            Thread oldThread = null;
            synchronized (this) {
                // dispose of thread
                interrupted = true;
                oldThread = thread;
                thread = null;
            }
            if (oldThread != null) {
                // wake up the thread if it's in wait()
                synchronized(lock) {
                    lock.notifyAll();
                }
            }
            // wait for the thread to terminate itself,
            // but max. 2 seconds. Must not be synchronized!
            if (oldThread != null) {
                try {
                    oldThread.join(2000);
                } catch (InterruptedException ie) {}
            }
        }


        /**
         * Main process loop driving the media flow.
         *
         * Make sure to NOT synchronize on RealTimeSequencer
         * anywhere here (even implicit). That is a sure deadlock!
         */
        public void run() {

            while (!interrupted) {
                boolean EOM = false;
                boolean wasRunning = running;
                isPumping = !interrupted && running;
                while (!EOM && !interrupted && running) {
                    EOM = dataPump.pump();

                    try {
                        Thread.sleep(1);
                    } catch (InterruptedException ie) {
                        // ignore
                    }
                }
                if (Printer.debug) {
                    Printer.debug("Exited main pump loop because: ");
                    if (EOM) Printer.debug(" -> EOM is reached");
                    if (!running) Printer.debug(" -> running was set to false");
                    if (interrupted) Printer.debug(" -> interrupted was set to true");
                }

                playThreadImplStop();
                if (wasRunning) {
                    dataPump.notesOff(true);
                }
                if (EOM) {
                    dataPump.setTickPos(sequence.getTickLength());

                    // send EOT event (mis-used for end of media)
                    MetaMessage message = new MetaMessage();
                    try{
                        message.setMessage(MidiUtils.META_END_OF_TRACK_TYPE, new byte[0], 0);
                    } catch(InvalidMidiDataException e1) {}
                    sendMetaEvents(message);
                }
                synchronized (lock) {
                    isPumping = false;
                    // wake up a waiting stop() method
                    lock.notifyAll();
                    while (!running && !interrupted) {
                        try {
                            lock.wait();
                        } catch (Exception ex) {}
                    }
                }
            } // end of while(!EOM && !interrupted && running)
            if (Printer.debug) Printer.debug("end of play thread");
        }
    }


    /**
     * class that does the actual dispatching of events,
     * used to be in native in MMAPI
     */
    private class DataPump {
        private float currTempo;         // MPQ tempo
        private float tempoFactor;       // 1.0 is default
        private float inverseTempoFactor;// = 1.0 / tempoFactor
        private long ignoreTempoEventAt; // ignore next META tempo during playback at this tick pos only
        private int resolution;
        private float divisionType;
        private long checkPointMillis;   // microseconds at checkoint
        private long checkPointTick;     // ticks at checkpoint
        private int[] noteOnCache;       // bit-mask of notes that are currently on
        private Track[] tracks;
        private boolean[] trackDisabled; // if true, do not play this track
        private int[] trackReadPos;      // read index per track
        private long lastTick;
        private boolean needReindex = false;
        private int currLoopCounter = 0;

        //private sun.misc.Perf perf = sun.misc.Perf.getPerf();
        //private long perfFreq = perf.highResFrequency();


        DataPump() {
            init();
        }

        synchronized void init() {
            ignoreTempoEventAt = -1;
            tempoFactor = 1.0f;
            inverseTempoFactor = 1.0f;
            noteOnCache = new int[128];
            tracks = null;
            trackDisabled = null;
        }

        synchronized void setTickPos(long tickPos) {
            long oldLastTick = tickPos;
            lastTick = tickPos;
            if (running) {
                notesOff(false);
            }
            if (running || tickPos > 0) {
                // will also reindex
                chaseEvents(oldLastTick, tickPos);
            } else {
                needReindex = true;
            }
            if (!hasCachedTempo()) {
                setTempoMPQ(getTempoCache().getTempoMPQAt(lastTick, currTempo));
                // treat this as if it is a real time tempo change
                ignoreTempoEventAt = -1;
            }
            // trigger re-configuration
            checkPointMillis = 0;
        }

        long getTickPos() {
            return lastTick;
        }

        // hasCachedTempo is only valid if it is the current position
        boolean hasCachedTempo() {
            if (ignoreTempoEventAt != lastTick) {
                ignoreTempoEventAt = -1;
            }
            return ignoreTempoEventAt >= 0;
        }

        // this method is also used internally in the pump!
        synchronized void setTempoMPQ(float tempoMPQ) {
            if (tempoMPQ > 0 && tempoMPQ != currTempo) {
                ignoreTempoEventAt = lastTick;
                this.currTempo = tempoMPQ;
                // re-calculate check point
                checkPointMillis = 0;
            }
        }

        float getTempoMPQ() {
            return currTempo;
        }

        synchronized void setTempoFactor(float factor) {
            if (factor > 0 && factor != this.tempoFactor) {
                tempoFactor = factor;
                inverseTempoFactor = 1.0f / factor;
                // re-calculate check point
                checkPointMillis = 0;
            }
        }

        float getTempoFactor() {
            return tempoFactor;
        }

        synchronized void muteSoloChanged() {
            boolean[] newDisabled = makeDisabledArray();
            if (running) {
                applyDisabledTracks(trackDisabled, newDisabled);
            }
            trackDisabled = newDisabled;
        }



        synchronized void setSequence(Sequence seq) {
            if (seq == null) {
                init();
                return;
            }
            tracks = seq.getTracks();
            muteSoloChanged();
            resolution = seq.getResolution();
            divisionType = seq.getDivisionType();
            trackReadPos = new int[tracks.length];
            // trigger re-initialization
            checkPointMillis = 0;
            needReindex = true;
        }

        synchronized void resetLoopCount() {
            currLoopCounter = loopCount;
        }

        void clearNoteOnCache() {
            for (int i = 0; i < 128; i++) {
                noteOnCache[i] = 0;
            }
        }

        void notesOff(boolean doControllers) {
            int done = 0;
            for (int ch=0; ch<16; ch++) {
                int channelMask = (1<<ch);
                for (int i=0; i<128; i++) {
                    if ((noteOnCache[i] & channelMask) != 0) {
                        noteOnCache[i] ^= channelMask;
                        // send note on with velocity 0
                        getTransmitterList().sendMessage((ShortMessage.NOTE_ON | ch) | (i<<8), -1);
                        done++;
                    }
                }
                /* all notes off */
                getTransmitterList().sendMessage((ShortMessage.CONTROL_CHANGE | ch) | (123<<8), -1);
                /* sustain off */
                getTransmitterList().sendMessage((ShortMessage.CONTROL_CHANGE | ch) | (64<<8), -1);
                if (doControllers) {
                    /* reset all controllers */
                    getTransmitterList().sendMessage((ShortMessage.CONTROL_CHANGE | ch) | (121<<8), -1);
                    done++;
                }
            }
            if (DEBUG_PUMP) Printer.println("  noteOff: sent "+done+" messages.");
        }


        private boolean[] makeDisabledArray() {
            if (tracks == null) {
                return null;
            }
            boolean[] newTrackDisabled = new boolean[tracks.length];
            boolean[] solo;
            boolean[] mute;
            synchronized(RealTimeSequencer.this) {
                mute = trackMuted;
                solo = trackSolo;
            }
            // if one track is solo, then only play solo
            boolean hasSolo = false;
            if (solo != null) {
                for (int i = 0; i < solo.length; i++) {
                    if (solo[i]) {
                        hasSolo = true;
                        break;
                    }
                }
            }
            if (hasSolo) {
                // only the channels with solo play, regardless of mute
                for (int i = 0; i < newTrackDisabled.length; i++) {
                    newTrackDisabled[i] = (i >= solo.length) || (!solo[i]);
                }
            } else {
                // mute the selected channels
                for (int i = 0; i < newTrackDisabled.length; i++) {
                    newTrackDisabled[i] = (mute != null) && (i < mute.length) && (mute[i]);
                }
            }
            return newTrackDisabled;
        }

        /**
         * chase all events from beginning of Track
         * and send note off for those events that are active
         * in noteOnCache array.
         * It is possible, of course, to catch notes from other tracks,
         * but better than more complicated logic to detect
         * which notes are really from this track
         */
        private void sendNoteOffIfOn(Track track, long endTick) {
            int size = track.size();
            int done = 0;
            try {
                for (int i = 0; i < size; i++) {
                    MidiEvent event = track.get(i);
                    if (event.getTick() > endTick) break;
                    MidiMessage msg = event.getMessage();
                    int status = msg.getStatus();
                    int len = msg.getLength();
                    if (len == 3 && ((status & 0xF0) == ShortMessage.NOTE_ON)) {
                        int note = -1;
                        if (msg instanceof ShortMessage) {
                            ShortMessage smsg = (ShortMessage) msg;
                            if (smsg.getData2() > 0) {
                                // only consider Note On with velocity > 0
                                note = smsg.getData1();
                            }
                        } else {
                            byte[] data = msg.getMessage();
                            if ((data[2] & 0x7F) > 0) {
                                // only consider Note On with velocity > 0
                                note = data[1] & 0x7F;
                            }
                        }
                        if (note >= 0) {
                            int bit = 1<<(status & 0x0F);
                            if ((noteOnCache[note] & bit) != 0) {
                                // the bit is set. Send Note Off
                                getTransmitterList().sendMessage(status | (note<<8), -1);
                                // clear the bit
                                noteOnCache[note] &= (0xFFFF ^ bit);
                                done++;
                            }
                        }
                    }
                }
            } catch (ArrayIndexOutOfBoundsException aioobe) {
                // this happens when messages are removed
                // from the track while this method executes
            }
            if (DEBUG_PUMP) Printer.println("  sendNoteOffIfOn: sent "+done+" messages.");
        }


        /**
         * Runtime application of mute/solo:
         * if a track is muted that was previously playing, send
         *    note off events for all currently playing notes
         */
        private void applyDisabledTracks(boolean[] oldDisabled, boolean[] newDisabled) {
            byte[][] tempArray = null;
            synchronized(RealTimeSequencer.this) {
                for (int i = 0; i < newDisabled.length; i++) {
                    if (((oldDisabled == null)
                         || (i >= oldDisabled.length)
                         || !oldDisabled[i])
                        && newDisabled[i]) {
                        // case that a track gets muted: need to
                        // send appropriate note off events to prevent
                        // hanging notes

                        if (tracks.length > i) {
                            sendNoteOffIfOn(tracks[i], lastTick);
                        }
                    }
                    else if ((oldDisabled != null)
                             && (i < oldDisabled.length)
                             && oldDisabled[i]
                             && !newDisabled[i]) {
                        // case that a track was muted and is now unmuted
                        // need to chase events and re-index this track
                        if (tempArray == null) {
                            tempArray = new byte[128][16];
                        }
                        chaseTrackEvents(i, 0, lastTick, true, tempArray);
                    }
                }
            }
        }

        /** go through all events from startTick to endTick
         * chase the controller state and program change state
         * and then set the end-states at once.
         *
         * needs to be called in synchronized state
         * @param tempArray an byte[128][16] to hold controller messages
         */
        private void chaseTrackEvents(int trackNum,
                                      long startTick,
                                      long endTick,
                                      boolean doReindex,
                                      byte[][] tempArray) {
            if (startTick > endTick) {
                // start from the beginning
                startTick = 0;
            }
            byte[] progs = new byte[16];
            // init temp array with impossible values
            for (int ch = 0; ch < 16; ch++) {
                progs[ch] = -1;
                for (int co = 0; co < 128; co++) {
                    tempArray[co][ch] = -1;
                }
            }
            Track track = tracks[trackNum];
            int size = track.size();
            try {
                for (int i = 0; i < size; i++) {
                    MidiEvent event = track.get(i);
                    if (event.getTick() >= endTick) {
                        if (doReindex && (trackNum < trackReadPos.length)) {
                            trackReadPos[trackNum] = (i > 0)?(i-1):0;
                            if (DEBUG_PUMP) Printer.println("  chaseEvents: setting trackReadPos["+trackNum+"] = "+trackReadPos[trackNum]);
                        }
                        break;
                    }
                    MidiMessage msg = event.getMessage();
                    int status = msg.getStatus();
                    int len = msg.getLength();
                    if (len == 3 && ((status & 0xF0) == ShortMessage.CONTROL_CHANGE)) {
                        if (msg instanceof ShortMessage) {
                            ShortMessage smsg = (ShortMessage) msg;
                            tempArray[smsg.getData1() & 0x7F][status & 0x0F] = (byte) smsg.getData2();
                        } else {
                            byte[] data = msg.getMessage();
                            tempArray[data[1] & 0x7F][status & 0x0F] = data[2];
                        }
                    }
                    if (len == 2 && ((status & 0xF0) == ShortMessage.PROGRAM_CHANGE)) {
                        if (msg instanceof ShortMessage) {
                            ShortMessage smsg = (ShortMessage) msg;
                            progs[status & 0x0F] = (byte) smsg.getData1();
                        } else {
                            byte[] data = msg.getMessage();
                            progs[status & 0x0F] = data[1];
                        }
                    }
                }
            } catch (ArrayIndexOutOfBoundsException aioobe) {
                // this happens when messages are removed
                // from the track while this method executes
            }
            int numControllersSent = 0;
            // now send out the aggregated controllers and program changes
            for (int ch = 0; ch < 16; ch++) {
                for (int co = 0; co < 128; co++) {
                    byte controllerValue = tempArray[co][ch];
                    if (controllerValue >= 0) {
                        int packedMsg = (ShortMessage.CONTROL_CHANGE | ch) | (co<<8) | (controllerValue<<16);
                        getTransmitterList().sendMessage(packedMsg, -1);
                        numControllersSent++;
                    }
                }
                // send program change *after* controllers, to
                // correctly initialize banks
                if (progs[ch] >= 0) {
                    getTransmitterList().sendMessage((ShortMessage.PROGRAM_CHANGE | ch) | (progs[ch]<<8), -1);
                }
                if (progs[ch] >= 0 || startTick == 0 || endTick == 0) {
                    // reset pitch bend on this channel (E0 00 40)
                    getTransmitterList().sendMessage((ShortMessage.PITCH_BEND | ch) | (0x40 << 16), -1);
                    // reset sustain pedal on this channel
                    getTransmitterList().sendMessage((ShortMessage.CONTROL_CHANGE | ch) | (64 << 8), -1);
                }
            }
            if (DEBUG_PUMP) Printer.println("  chaseTrackEvents track "+trackNum+": sent "+numControllersSent+" controllers.");
        }


        /** chase controllers and program for all tracks */
        synchronized void chaseEvents(long startTick, long endTick) {
            if (DEBUG_PUMP) Printer.println(">> chaseEvents from tick "+startTick+".."+(endTick-1));
            byte[][] tempArray = new byte[128][16];
            for (int t = 0; t < tracks.length; t++) {
                if ((trackDisabled == null)
                    || (trackDisabled.length <= t)
                    || (!trackDisabled[t])) {
                    // if track is not disabled, chase the events for it
                    chaseTrackEvents(t, startTick, endTick, true, tempArray);
                }
            }
            if (DEBUG_PUMP) Printer.println("<< chaseEvents");
        }


        // playback related methods (pumping)

        private long getCurrentTimeMillis() {
            return System.nanoTime() / 1000000l;
            //return perf.highResCounter() * 1000 / perfFreq;
        }

        private long millis2tick(long millis) {
            if (divisionType != Sequence.PPQ) {
                double dTick = ((((double) millis) * tempoFactor)
                                * ((double) divisionType)
                                * ((double) resolution))
                    / ((double) 1000);
                return (long) dTick;
            }
            return MidiUtils.microsec2ticks(millis * 1000,
                                            currTempo * inverseTempoFactor,
                                            resolution);
        }

        private long tick2millis(long tick) {
            if (divisionType != Sequence.PPQ) {
                double dMillis = ((((double) tick) * 1000) /
                                  (tempoFactor * ((double) divisionType) * ((double) resolution)));
                return (long) dMillis;
            }
            return MidiUtils.ticks2microsec(tick,
                                            currTempo * inverseTempoFactor,
                                            resolution) / 1000;
        }

        private void ReindexTrack(int trackNum, long tick) {
            if (trackNum < trackReadPos.length && trackNum < tracks.length) {
                trackReadPos[trackNum] = MidiUtils.tick2index(tracks[trackNum], tick);
                if (DEBUG_PUMP) Printer.println("  reindexTrack: setting trackReadPos["+trackNum+"] = "+trackReadPos[trackNum]);
            }
        }

        /* returns if changes are pending */
        private boolean dispatchMessage(int trackNum, MidiEvent event) {
            boolean changesPending = false;
            MidiMessage message = event.getMessage();
            int msgStatus = message.getStatus();
            int msgLen = message.getLength();
            if (msgStatus == MetaMessage.META && msgLen >= 2) {
                // a meta message. Do not send it to the device.
                // 0xFF with length=1 is a MIDI realtime message
                // which shouldn't be in a Sequence, but we play it
                // nonetheless.

                // see if this is a tempo message. Only on track 0.
                if (trackNum == 0) {
                    int newTempo = MidiUtils.getTempoMPQ(message);
                    if (newTempo > 0) {
                        if (event.getTick() != ignoreTempoEventAt) {
                            setTempoMPQ(newTempo); // sets ignoreTempoEventAt!
                            changesPending = true;
                        }
                        // next loop, do not ignore anymore tempo events.
                        ignoreTempoEventAt = -1;
                    }
                }
                // send to listeners
                sendMetaEvents(message);

            } else {
                // not meta, send to device
                getTransmitterList().sendMessage(message, -1);

                switch (msgStatus & 0xF0) {
                case ShortMessage.NOTE_OFF: {
                    // note off - clear the bit in the noteOnCache array
                    int note = ((ShortMessage) message).getData1() & 0x7F;
                    noteOnCache[note] &= (0xFFFF ^ (1<<(msgStatus & 0x0F)));
                    break;
                }

                case ShortMessage.NOTE_ON: {
                    // note on
                    ShortMessage smsg = (ShortMessage) message;
                    int note = smsg.getData1() & 0x7F;
                    int vel = smsg.getData2() & 0x7F;
                    if (vel > 0) {
                        // if velocity > 0 set the bit in the noteOnCache array
                        noteOnCache[note] |= 1<<(msgStatus & 0x0F);
                    } else {
                        // if velocity = 0 clear the bit in the noteOnCache array
                        noteOnCache[note] &= (0xFFFF ^ (1<<(msgStatus & 0x0F)));
                    }
                    break;
                }

                case ShortMessage.CONTROL_CHANGE:
                    // if controller message, send controller listeners
                    sendControllerEvents(message);
                    break;

                }
            }
            return changesPending;
        }


        /** the main pump method
         * @return true if end of sequence is reached
         */
        synchronized boolean pump() {
            long currMillis;
            long targetTick = lastTick;
            MidiEvent currEvent;
            boolean changesPending = false;
            boolean doLoop = false;
            boolean EOM = false;

            currMillis = getCurrentTimeMillis();
            int finishedTracks = 0;
            do {
                changesPending = false;

                // need to re-find indexes in tracks?
                if (needReindex) {
                    if (DEBUG_PUMP) Printer.println("Need to re-index at "+currMillis+" millis. TargetTick="+targetTick);
                    if (trackReadPos.length < tracks.length) {
                        trackReadPos = new int[tracks.length];
                    }
                    for (int t = 0; t < tracks.length; t++) {
                        ReindexTrack(t, targetTick);
                        if (DEBUG_PUMP_ALL) Printer.println("  Setting trackReadPos["+t+"]="+trackReadPos[t]);
                    }
                    needReindex = false;
                    checkPointMillis = 0;
                }

                // get target tick from current time in millis
                if (checkPointMillis == 0) {
                    // new check point
                    currMillis = getCurrentTimeMillis();
                    checkPointMillis = currMillis;
                    targetTick = lastTick;
                    checkPointTick = targetTick;
                    if (DEBUG_PUMP) Printer.println("New checkpoint to "+currMillis+" millis. "
                                                       +"TargetTick="+targetTick
                                                       +" new tempo="+MidiUtils.convertTempo(currTempo)+"bpm");
                } else {
                    // calculate current tick based on current time in milliseconds
                    targetTick = checkPointTick + millis2tick(currMillis - checkPointMillis);
                    if (DEBUG_PUMP_ALL) Printer.println("targetTick = "+targetTick+" at "+currMillis+" millis");
                    if ((loopEnd != -1)
                        && ((loopCount > 0 && currLoopCounter > 0)
                            || (loopCount == LOOP_CONTINUOUSLY))) {
                        if (lastTick <= loopEnd && targetTick >= loopEnd) {
                            // need to loop!
                            // only play until loop end
                            targetTick = loopEnd - 1;
                            doLoop = true;
                            if (DEBUG_PUMP) Printer.println("set doLoop to true. lastTick="+lastTick
                                                               +"  targetTick="+targetTick
                                                               +"  loopEnd="+loopEnd
                                                               +"  jumping to loopStart="+loopStart
                                                               +"  new currLoopCounter="+currLoopCounter);
                            if (DEBUG_PUMP) Printer.println("  currMillis="+currMillis
                                                               +"  checkPointMillis="+checkPointMillis
                                                               +"  checkPointTick="+checkPointTick);

                        }
                    }
                    lastTick = targetTick;
                }

                finishedTracks = 0;

                for (int t = 0; t < tracks.length; t++) {
                    try {
                        boolean disabled = trackDisabled[t];
                        Track thisTrack = tracks[t];
                        int readPos = trackReadPos[t];
                        int size = thisTrack.size();
                        // play all events that are due until targetTick
                        while (!changesPending && (readPos < size)
                               && (currEvent = thisTrack.get(readPos)).getTick() <= targetTick) {

                            if ((readPos == size -1) &&  MidiUtils.isMetaEndOfTrack(currEvent.getMessage())) {
                                // do not send out this message. Finished with this track
                                readPos = size;
                                break;
                            }
                            // TODO: some kind of heuristics if the MIDI messages have changed
                            // significantly (i.e. deleted or inserted a bunch of messages)
                            // since last time. Would need to set needReindex = true then
                            readPos++;
                            // only play this event if the track is enabled,
                            // or if it is a tempo message on track 0
                            // Note: cannot put this check outside
                            //       this inner loop in order to detect end of file
                            if (!disabled ||
                                ((t == 0) && (MidiUtils.isMetaTempo(currEvent.getMessage())))) {
                                changesPending = dispatchMessage(t, currEvent);
                            }
                        }
                        if (readPos >= size) {
                            finishedTracks++;
                        }
                        if (DEBUG_PUMP_ALL) {
                            System.out.print(" pumped track "+t+" ("+size+" events) "
                                             +" from index: "+trackReadPos[t]
                                             +" to "+(readPos-1));
                            System.out.print(" -> ticks: ");
                            if (trackReadPos[t] < size) {
                                System.out.print(""+(thisTrack.get(trackReadPos[t]).getTick()));
                            } else {
                                System.out.print("EOT");
                            }
                            System.out.print(" to ");
                            if (readPos < size) {
                                System.out.print(""+(thisTrack.get(readPos-1).getTick()));
                            } else {
                                System.out.print("EOT");
                            }
                            System.out.println();
                        }
                        trackReadPos[t] = readPos;
                    } catch(Exception e) {
                        if (Printer.debug) Printer.debug("Exception in Sequencer pump!");
                        if (Printer.debug) e.printStackTrace();
                        if (e instanceof ArrayIndexOutOfBoundsException) {
                            needReindex = true;
                            changesPending = true;
                        }
                    }
                    if (changesPending) {
                        break;
                    }
                }
                EOM = (finishedTracks == tracks.length);
                if (doLoop
                    || ( ((loopCount > 0 && currLoopCounter > 0)
                          || (loopCount == LOOP_CONTINUOUSLY))
                         && !changesPending
                         && (loopEnd == -1)
                         && EOM)) {

                    long oldCheckPointMillis = checkPointMillis;
                    long loopEndTick = loopEnd;
                    if (loopEndTick == -1) {
                        loopEndTick = lastTick;
                    }

                    // need to loop back!
                    if (loopCount != LOOP_CONTINUOUSLY) {
                        currLoopCounter--;
                    }
                    if (DEBUG_PUMP) Printer.println("Execute loop: lastTick="+lastTick
                                                       +"  loopEnd="+loopEnd
                                                       +"  jumping to loopStart="+loopStart
                                                       +"  new currLoopCounter="+currLoopCounter);
                    setTickPos(loopStart);
                    // now patch the checkPointMillis so that
                    // it points to the exact beginning of when the loop was finished

                    // $$fb TODO: although this is mathematically correct (i.e. the loop position
                    //            is correct, and doesn't drift away with several repetition,
                    //            there is a slight lag when looping back, probably caused
                    //            by the chasing.

                    checkPointMillis = oldCheckPointMillis + tick2millis(loopEndTick - checkPointTick);
                    checkPointTick = loopStart;
                    if (DEBUG_PUMP) Printer.println("  Setting currMillis="+currMillis
                                                       +"  new checkPointMillis="+checkPointMillis
                                                       +"  new checkPointTick="+checkPointTick);
                    // no need for reindexing, is done in setTickPos
                    needReindex = false;
                    changesPending = false;
                    // reset doLoop flag
                    doLoop = false;
                    EOM = false;
                }
            } while (changesPending);

            return EOM;
        }

    } // class DataPump

}
