/*
 * Copyright (c) 1999, 2007, 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.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.applet.AudioClip;
import java.lang.InterruptedException;

import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.Clip;
import javax.sound.sampled.Control;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineListener;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;


import javax.sound.midi.MidiSystem;
import javax.sound.midi.MidiFileFormat;
import javax.sound.midi.MetaMessage;
import javax.sound.midi.Sequence;
import javax.sound.midi.Sequencer;
import javax.sound.midi.InvalidMidiDataException;
import javax.sound.midi.MidiUnavailableException;
import javax.sound.midi.MetaEventListener;

/**
 * Java Sound audio clip;
 *
 * @author Arthur van Hoff, Kara Kytle, Jan Borgersen
 * @author Florian Bomers
 */

public class JavaSoundAudioClip implements AudioClip, MetaEventListener, LineListener {

    private static final boolean DEBUG = false;
    private static final int BUFFER_SIZE = 16384; // number of bytes written each time to the source data line

    private long lastPlayCall = 0;
    private static final int MINIMUM_PLAY_DELAY = 30;

    private byte loadedAudio[] = null;
    private int loadedAudioByteLength = 0;
    private AudioFormat loadedAudioFormat = null;

    private AutoClosingClip clip = null;
    private boolean clipLooping = false;

    private DataPusher datapusher = null;

    private Sequencer sequencer = null;
    private Sequence sequence = null;
    private boolean sequencerloop = false;

    /**
     * used for determining how many samples is the
     * threshhold between playing as a Clip and streaming
     * from the file.
     *
     * $$jb: 11.07.99: the engine has a limit of 1M
     * samples to play as a Clip, so compare this number
     * with the number of samples in the stream.
     *
     */
    private final static long CLIP_THRESHOLD = 1048576;
    //private final static long CLIP_THRESHOLD = 1;
    private final static int STREAM_BUFFER_SIZE = 1024;

    public JavaSoundAudioClip(InputStream in) throws IOException {
        if (DEBUG || Printer.debug)Printer.debug("JavaSoundAudioClip.<init>");

        BufferedInputStream bis = new BufferedInputStream(in, STREAM_BUFFER_SIZE);
        bis.mark(STREAM_BUFFER_SIZE);
        boolean success = false;
        try {
            AudioInputStream as = AudioSystem.getAudioInputStream(bis);
            // load the stream data into memory
            success = loadAudioData(as);

            if (success) {
                success = false;
                if (loadedAudioByteLength < CLIP_THRESHOLD) {
                    success = createClip();
                }
                if (!success) {
                    success = createSourceDataLine();
                }
            }
        } catch (UnsupportedAudioFileException e) {
            // not an audio file
            try {
                MidiFileFormat mff = MidiSystem.getMidiFileFormat(bis);
                success = createSequencer(bis);
            } catch (InvalidMidiDataException e1) {
                success = false;
            }
        }
        if (!success) {
            throw new IOException("Unable to create AudioClip from input stream");
        }
    }


    public synchronized void play() {
        startImpl(false);
    }


    public synchronized void loop() {
        startImpl(true);
    }

    private synchronized void startImpl(boolean loop) {
        // hack for some applets that call the start method very rapidly...
        long currentTime = System.currentTimeMillis();
        long diff = currentTime - lastPlayCall;
        if (diff < MINIMUM_PLAY_DELAY) {
            if (DEBUG || Printer.debug) Printer.debug("JavaSoundAudioClip.startImpl(loop="+loop+"): abort - too rapdly");
            return;
        }
        lastPlayCall = currentTime;

        if (DEBUG || Printer.debug) Printer.debug("JavaSoundAudioClip.startImpl(loop="+loop+")");
        try {
            if (clip != null) {
                if (!clip.isOpen()) {
                    if (DEBUG || Printer.trace)Printer.trace("JavaSoundAudioClip: clip.open()");
                    clip.open(loadedAudioFormat, loadedAudio, 0, loadedAudioByteLength);
                } else {
                    if (DEBUG || Printer.trace)Printer.trace("JavaSoundAudioClip: clip.flush()");
                    clip.flush();
                    if (loop != clipLooping) {
                        // need to stop in case the looped status changed
                        if (DEBUG || Printer.trace)Printer.trace("JavaSoundAudioClip: clip.stop()");
                        clip.stop();
                    }
                }
                clip.setFramePosition(0);
                if (loop) {
                    if (DEBUG || Printer.trace)Printer.trace("JavaSoundAudioClip: clip.loop()");
                    clip.loop(Clip.LOOP_CONTINUOUSLY);
                } else {
                    if (DEBUG || Printer.trace)Printer.trace("JavaSoundAudioClip: clip.start()");
                    clip.start();
                }
                clipLooping = loop;
                if (DEBUG || Printer.debug)Printer.debug("Clip should be playing/looping");

            } else if (datapusher != null ) {
                datapusher.start(loop);
                if (DEBUG || Printer.debug)Printer.debug("Stream should be playing/looping");

            } else if (sequencer != null) {
                sequencerloop = loop;
                if (sequencer.isRunning()) {
                    sequencer.setMicrosecondPosition(0);
                }
                if (!sequencer.isOpen()) {
                    try {
                        sequencer.open();
                        sequencer.setSequence(sequence);

                    } catch (InvalidMidiDataException e1) {
                        if (DEBUG || Printer.err)e1.printStackTrace();
                    } catch (MidiUnavailableException e2) {
                        if (DEBUG || Printer.err)e2.printStackTrace();
                    }
                }
                sequencer.addMetaEventListener(this);
                try {
                    sequencer.start();
                } catch (Exception e) {
                    if (DEBUG || Printer.err) e.printStackTrace();
                }
                if (DEBUG || Printer.debug)Printer.debug("Sequencer should be playing/looping");
            }
        } catch (Exception e) {
            if (DEBUG || Printer.err)e.printStackTrace();
        }
    }

    public synchronized void stop() {

        if (DEBUG || Printer.debug)Printer.debug("JavaSoundAudioClip->stop()");
        lastPlayCall = 0;

        if (clip != null) {
            try {
                if (DEBUG || Printer.trace)Printer.trace("JavaSoundAudioClip: clip.flush()");
                clip.flush();
            } catch (Exception e1) {
                if (Printer.err) e1.printStackTrace();
            }
            try {
                if (DEBUG || Printer.trace)Printer.trace("JavaSoundAudioClip: clip.stop()");
                clip.stop();
            } catch (Exception e2) {
                if (Printer.err) e2.printStackTrace();
            }
            if (DEBUG || Printer.debug)Printer.debug("Clip should be stopped");

        } else if (datapusher != null) {
            datapusher.stop();
            if (DEBUG || Printer.debug)Printer.debug("Stream should be stopped");

        } else if (sequencer != null) {
            try {
                sequencerloop = false;
                sequencer.addMetaEventListener(this);
                sequencer.stop();
            } catch (Exception e3) {
                if (Printer.err) e3.printStackTrace();
            }
            try {
                sequencer.close();
            } catch (Exception e4) {
                if (Printer.err) e4.printStackTrace();
            }
            if (DEBUG || Printer.debug)Printer.debug("Sequencer should be stopped");
        }
    }

    // Event handlers (for debugging)

    public synchronized void update(LineEvent event) {
        if (DEBUG || Printer.debug) Printer.debug("line event received: "+event);
    }

    // handle MIDI track end meta events for looping

    public synchronized void meta( MetaMessage message ) {

        if (DEBUG || Printer.debug)Printer.debug("META EVENT RECEIVED!!!!! ");

        if( message.getType() == 47 ) {
            if (sequencerloop){
                //notifyAll();
                sequencer.setMicrosecondPosition(0);
                loop();
            } else {
                stop();
            }
        }
    }


    public String toString() {
        return getClass().toString();
    }


    protected void finalize() {

        if (clip != null) {
            if (DEBUG || Printer.trace)Printer.trace("JavaSoundAudioClip.finalize: clip.close()");
            clip.close();
        }

        //$$fb 2001-09-26: may improve situation related to bug #4302884
        if (datapusher != null) {
            datapusher.close();
        }

        if (sequencer != null) {
            sequencer.close();
        }
    }

    // FILE LOADING METHODS

    private boolean loadAudioData(AudioInputStream as)  throws IOException, UnsupportedAudioFileException {
        if (DEBUG || Printer.debug)Printer.debug("JavaSoundAudioClip->openAsClip()");

        // first possibly convert this stream to PCM
        as = Toolkit.getPCMConvertedAudioInputStream(as);
        if (as == null) {
            return false;
        }

        loadedAudioFormat = as.getFormat();
        long frameLen = as.getFrameLength();
        int frameSize = loadedAudioFormat.getFrameSize();
        long byteLen = AudioSystem.NOT_SPECIFIED;
        if (frameLen != AudioSystem.NOT_SPECIFIED
            && frameLen > 0
            && frameSize != AudioSystem.NOT_SPECIFIED
            && frameSize > 0) {
            byteLen = frameLen * frameSize;
        }
        if (byteLen != AudioSystem.NOT_SPECIFIED) {
            // if the stream length is known, it can be efficiently loaded into memory
            readStream(as, byteLen);
        } else {
            // otherwise we use a ByteArrayOutputStream to load it into memory
            readStream(as);
        }

        // if everything went fine, we have now the audio data in
        // loadedAudio, and the byte length in loadedAudioByteLength
        return true;
    }



    private void readStream(AudioInputStream as, long byteLen) throws IOException {
        // arrays "only" max. 2GB
        int intLen;
        if (byteLen > 2147483647) {
            intLen = 2147483647;
        } else {
            intLen = (int) byteLen;
        }
        loadedAudio = new byte[intLen];
        loadedAudioByteLength = 0;

        // this loop may throw an IOException
        while (true) {
            int bytesRead = as.read(loadedAudio, loadedAudioByteLength, intLen - loadedAudioByteLength);
            if (bytesRead <= 0) {
                as.close();
                break;
            }
            loadedAudioByteLength += bytesRead;
        }
    }

    private void readStream(AudioInputStream as) throws IOException {

        DirectBAOS baos = new DirectBAOS();
        byte buffer[] = new byte[16384];
        int bytesRead = 0;
        int totalBytesRead = 0;

        // this loop may throw an IOException
        while( true ) {
            bytesRead = as.read(buffer, 0, buffer.length);
            if (bytesRead <= 0) {
                as.close();
                break;
            }
            totalBytesRead += bytesRead;
            baos.write(buffer, 0, bytesRead);
        }
        loadedAudio = baos.getInternalBuffer();
        loadedAudioByteLength = totalBytesRead;
    }


    // METHODS FOR CREATING THE DEVICE

    private boolean createClip() {

        if (DEBUG || Printer.debug)Printer.debug("JavaSoundAudioClip.createClip()");

        try {
            DataLine.Info info = new DataLine.Info(Clip.class, loadedAudioFormat);
            if (!(AudioSystem.isLineSupported(info)) ) {
                if (DEBUG || Printer.err)Printer.err("Clip not supported: "+loadedAudioFormat);
                // fail silently
                return false;
            }
            Object line = AudioSystem.getLine(info);
            if (!(line instanceof AutoClosingClip)) {
                if (DEBUG || Printer.err)Printer.err("Clip is not auto closing!"+clip);
                // fail -> will try with SourceDataLine
                return false;
            }
            clip = (AutoClosingClip) line;
            clip.setAutoClosing(true);
            if (DEBUG || Printer.debug) clip.addLineListener(this);
        } catch (Exception e) {
            if (DEBUG || Printer.err)e.printStackTrace();
            // fail silently
            return false;
        }

        if (clip==null) {
            // fail silently
            return false;
        }

        if (DEBUG || Printer.debug)Printer.debug("Loaded clip.");
        return true;
    }

    private boolean createSourceDataLine() {
        if (DEBUG || Printer.debug)Printer.debug("JavaSoundAudioClip.createSourceDataLine()");
        try {
            DataLine.Info info = new DataLine.Info(SourceDataLine.class, loadedAudioFormat);
            if (!(AudioSystem.isLineSupported(info)) ) {
                if (DEBUG || Printer.err)Printer.err("Line not supported: "+loadedAudioFormat);
                // fail silently
                return false;
            }
            SourceDataLine source = (SourceDataLine) AudioSystem.getLine(info);
            datapusher = new DataPusher(source, loadedAudioFormat, loadedAudio, loadedAudioByteLength);
        } catch (Exception e) {
            if (DEBUG || Printer.err)e.printStackTrace();
            // fail silently
            return false;
        }

        if (datapusher==null) {
            // fail silently
            return false;
        }

        if (DEBUG || Printer.debug)Printer.debug("Created SourceDataLine.");
        return true;
    }

    private boolean createSequencer(BufferedInputStream in) throws IOException {

        if (DEBUG || Printer.debug)Printer.debug("JavaSoundAudioClip.createSequencer()");

        // get the sequencer
        try {
            sequencer = MidiSystem.getSequencer( );
        } catch(MidiUnavailableException me) {
            if (DEBUG || Printer.err)me.printStackTrace();
            return false;
        }
        if (sequencer==null) {
            return false;
        }

        try {
            sequence = MidiSystem.getSequence(in);
            if (sequence == null) {
                return false;
            }
        } catch (InvalidMidiDataException e) {
            if (DEBUG || Printer.err)e.printStackTrace();
            return false;
        }

        if (DEBUG || Printer.debug)Printer.debug("Created Sequencer.");
        return true;
    }


    /*
     * private inner class representing a ByteArrayOutputStream
     * which allows retrieval of the internal array
     */
    private static class DirectBAOS extends ByteArrayOutputStream {
        public DirectBAOS() {
            super();
        }

        public byte[] getInternalBuffer() {
            return buf;
        }

    } // class DirectBAOS

}
