/*
 * @(#)AudioView.java  1.0.1  1999-09-25
 *
 * Copyright (c) 1999 Werner Randelshofer, Immensee, Switzerland.
 * All rights reserved.
 *
 * You may not use, copy or modify this file, except in compliance with the
 * license agreement you entered into with Werner Randelshofer.
 * For details see accompanying license terms.
 */
package ch.randelshofer.view;

import ch.randelshofer.util.PropertyModel;

import java.awt.*;
import java.awt.dnd.*;
import java.awt.event.*;

import java.applet.AudioClip;

import java.net.URL;
import java.net.MalformedURLException;

import java.util.Enumeration;
import java.util.Vector;

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

import sun.audio.AudioData;
import sun.audio.AudioPlayer;
import sun.audio.AudioDataStream;
import sun.audio.AudioStream;
import sun.audio.ContinuousAudioDataStream;

import javax.activation.CommandObject;
import javax.activation.DataHandler;

import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JComponent;
import javax.swing.JButton;

/**
 * Audio viewer for files of type audio/basic (as supported by the Java VM).
 * Warning this viewer does not work on all Java VM's: Calls are made 'beyond'
 * the official Java API.
 *
 * @author  Werner Randelshofer, Hausmatt 10, CH-6405 Immensee, Switzerland
 * @version 1.0.1   2000-09-25
 * <br> 1.0  1999-10-19
 */
public class AudioView extends AbstractView implements AudioClip, ActionListener {

    /**
     * The audio data used to build an audio data stream.
     */
    private AudioData audioData_;
    /**
     * The audio data stream currently being played.
     */
    private AudioDataStream activeStream_;

    public AudioView() {
        setLayout(new FlowLayout()); //--> already set by java.awt.Panel
        JButton button = new JButton("Play");
        button.setActionCommand("play");
        button.addActionListener(this);
        add(button);
        button = new JButton("Loop");
        button.setActionCommand("loop");
        button.addActionListener(this);
        add(button);
        button = new JButton("Stop");
        button.setActionCommand("stop");
        button.addActionListener(this);
        add(button);
    }

    public void actionPerformed(ActionEvent event) {
        String command = event.getActionCommand();
        if (command.equals("play")) {
            stop();
            play();
        } else if (command.equals("loop")) {
            stop();
            loop();
        } else if (command.equals("stop")) {
            stop();
        }
    }

    public void play() {
        if (audioData_ != null) {
            AudioPlayer.player.start(activeStream_ = new AudioDataStream(audioData_));
        }
    }

    public void loop() {
        if (audioData_ != null) {
            AudioPlayer.player.start(activeStream_ = new ContinuousAudioDataStream(audioData_));
        }
    }

    public void stop() {
        if (activeStream_ != null) {
            AudioPlayer.player.stop(activeStream_);
            activeStream_ = null;
        }
    }

    /** Sets the command context for the bean. The receiver loads
     * the image data provided by the data handler and displays it.
     */
    public void setCommandContext(String verb, DataHandler dh)
            throws IOException {
        stop();

        if (dh != null) {
            InputStream in = dh.getInputStream();
            try {
                audioData_ = new AudioStream(in).getData();
            } catch (Throwable e) {
                add("South", new JLabel(e.toString()));
            } finally {
                in.close();
            }
        }
    }

    public void removeNotify() {
        stop();
        super.removeNotify();
    }

    /**
     * Adds menu items to the "View" menu.
     *
     * When the viewer is added to a container with a
     * JMenuBar. Then the container asks the viewer to
     * add his menu items to the "View" menu of the container.
     */
    public void mergeViewMenuItems(JMenu m) {
    }

    /**
     * Adds menu items to the "Settings" menu.
     *
     * When the viewer is added to a container with a
     * JMenuBar. Then the container asks the viewer to
     * add his menu items to the "Settings" menu of the container.
     */
    public void mergeSettingsMenuItems(JMenu m) {
    }

    protected void updateViewProperties() {
        getViewProperties().put("title", " as Audio");
    }

    protected void updateApplicationProperties() {
    }

    /**
     * Frees all resources allocated by this viewer.
     */
    public void dispose() {
        stop();
    }

    /**
     * Returns true if this viewer has a scrollpane of its own.
     * The container that contains this viewers uses this method to
     * determine if it should wrap a scrollpane around the viewer
     * or not.
     *
     * @return  true if this viewer has a scrollpane of its own.
     */
    public boolean hasScrollPane() {
        return false;
    }

    public String toString() {
        return "Sun Audio View (Java 1.1 API)";
    }

    /**
     * This method adds the given drop target listener to
     * all components of the viewer.
     */
    public void addDropTargetListener(DropTargetListener listener) {
        new DropTarget(this, listener);
    }
}
