/*
 * File:     MediaObjectImpl.java
 * Project:  MPI Linguistic Application
 * Date:     03 April 2006
 *
 * Copyright (C) 2001-2006  Max Planck Institute for Psycholinguistics
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package mpi.eudico.server.corpora.clomimpl.abstr;

import mpi.eudico.server.corpora.clom.LanguageResource;
import mpi.eudico.server.corpora.clom.MediaObject;

import mpi.eudico.server.corpora.util.DurationUnknownException;
import mpi.eudico.server.corpora.util.NoAudioSampleDataException;
import mpi.eudico.server.corpora.util.NoMediaFileException;

import mpi.util.OurURL;

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

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

import java.util.Vector;

import javax.media.Manager;
import javax.media.Player;
import javax.media.protocol.URLDataSource;


/**
 * MediaObjectImpl encapsulates all information about media objects on a media
 * server that is used by the EUDICO data objects.
 *
 * @author Hennie Brugman
 * @author Albert Russel
 * @version 2-Jun-1999
 * @version Aug 2005 Identity removed
 */

// modified Daan Broeder 23-10-2000
// added url atribute + getFullPath() method
// OurURL intriduction 181103
public class MediaObjectImpl implements MediaObject {
    /** Name of a media file or stream on the media server. */
    private String mediaFileName;

    /**
     * Name of an audio file or stream on the media server, if the object
     * refers to audio data where individual samples are accessible for
     * visualization.
     */
    private String audioFileName;

    /** Sample rate of media that is associated with this object. */
    private double mediaSampleRate;

    /** Duration of the media file in milliseconds. */
    private long duration;

    /** the url of the media resource */
    private String url;

    /**
     * Depending on the arguments the time scale is calculated and initialized.
     * If there is an audio sample rate, this rate is taken as the basis for
     * time scale, since this rate offers the finest time resolution. Else, if
     * a videoType is specified (PAL or NTSC), the frame count of this type is
     * used as a basis.
     *
     * @param theMediaFile name of the video file or stream
     * @param theMediaType type of video, either PAL or NTSC
     * @param theAudioFile name of the audio file or stream
     * @param thisURL the audio sample rate
     */

    // changed the last parameter from samplerate to url of resource DGB
    public MediaObjectImpl(String theMediaFile, int theMediaType,
        String theAudioFile, String thisURL) {
        mediaFileName = theMediaFile;
        audioFileName = theAudioFile;
        url = thisURL;

        /*
           mediaSampleRate = theMediaSampleRate;
           if (theMediaType == NTSC) {
               mediaSampleRate = 29.97;
           }
           else if (theMediaType == PAL) {
               mediaSampleRate = 25;
           }
         */
    }

    private void logln(String s) {
        System.out.println(" log: " + s);
    }

    /**
     * Returns the name of the MediaObject's media file or stream.
     *
     * @return the media file or stream name
     *
     * @exception NoMediaFileException thrown when no media file or stream is
     *            associated with this MediaObject
     */
    public String getMediaFile() throws NoMediaFileException {
        if (mediaFileName == null) {
            throw new NoMediaFileException();
        }

        String rep1 = mediaFileName.replace(' ', '_');
        String rep2 = rep1.replace('/', '_');

        if (rep2.endsWith(".wav")) {
            return rep2;
        } else if (rep2.endsWith(".mpg")) {
            return rep2;
        }
        // HS 21-11-2001 mov added
        else if (rep2.endsWith(".mov")) {
            return rep2;
        } else {
            // return rep2 + ".mov";
            return rep2 + ".mpg";
        }

        //return mediaFileName;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public URL getMediaURL() {
        OurURL mediaURL = null;

        try {
            mediaURL = new OurURL(url);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }

        return mediaURL.toURL();
    }

    /**
     * Returns the name of the MediaObject's audio file or stream, if the
     * individual audio samples are accessible.
     *
     * @return the audio file or stream name
     *
     * @exception NoAudioSampleDataException thrown when no audio sample file
     *            or stream is associated with this MediaObject
     */
    public String getAudioSampleData() throws NoAudioSampleDataException {
        if (audioFileName == null) {
            throw new NoAudioSampleDataException();
        }

        return audioFileName;
    }

    /**
     * Gives the duration of the file or stream associated with the
     * MediaObject, if it is known and assessible.
     *
     * @return the duration in milliseconds
     *
     * @exception DurationUnknownException thrown when the duration is unknown
     *            or     unaccessible.
     */
    public long getDuration() throws DurationUnknownException {
        if (duration == 0) {
            // THIS NEEDS TO BE RECONSIDERED
            OurURL mediaURL = null;

            try {
                mediaURL = new OurURL(url);

                //    logln("MediaObjectImpl: retrieved ");
                System.out.println("MediaObject: creating Player " +
                    mediaURL.toString());

                //
                // hack to force Player to accept smb url's
                URLDataSource ds = new URLDataSource(mediaURL.toURL());
                ds.connect();

                Player player = Manager.createPlayer(ds);

                //					Player player = Manager.createPlayer(mediaURL.toURL());
                player.realize();

                while (player.getState() != Player.Realized) { // do not block any other Threads while realizing
                    Thread.currentThread().sleep(500);
                }

                duration = (player.getDuration().getNanoseconds()) / 1000000;
            } catch (IOException ioe) {
                System.err.println(
                    "MediaObjectImpl: error creating player for: " + mediaURL);
                ioe.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return duration;
    }

    /**
     * Returns the sample rate of a media object. (examples: 25 for PAL video,
     * 29.97 for NTSC video, 44100, ... for audio.
     *
     * @return DOCUMENT ME!
     */
    public double getMediaSampleRate() {
        //		return mediaSampleRate;
        return 0;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public LanguageResource[] getLanguageResources() {
        return null;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public boolean hasLanguageResources() {
        return false;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public String getTag() {
        return mediaFileName;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public String getDescription() {
        return "media description";
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public String getInfo() {
        return "media info";
    }

    /**
     * DOCUMENT ME!
     *
     * @param fmt DOCUMENT ME!
     */
    public void setFormat(String fmt) {
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public String getFormat() {
        return "some media format";
    }

    // TreeViewable methods

    /**
     * Returns the name of the TreeViewable Object as it must be used in the
     * Tree.
     *
     * @return the name of the TreeViewable
     */
    public String getNodeName() {
        return getTag();
    }

    /**
     * Informs whether this TreeViewable has TreeViewable children.
     *
     * @return true if this TreeViewable has TreeViewable children, false
     *         otherwise
     */
    public boolean isTreeViewableLeaf() {
        return true;
    }

    /**
     * Returns a Vector with the TreeViewable children of this TreeViewable. If
     * this TreeViewable has no children an empty Vector must be returned
     * instead of null.
     *
     * @return the TreeViewable children
     */
    public Vector getChildren() {
        return new Vector();
    }

    /**
     * getFullPath(): return the LR content storage specification
     *
     * @return DOCUMENT ME!
     */
    public String getFullPath() {
        return url;
    }

    /**
     * getContentType()
     *
     * @return the semi mime-type of the resource default implementation
     *         returns mime-type according to file extension
     */
    public String getContentType() {
        String type;

        if (url.endsWith(".wav")) {
            type = "audio/wav";
        } else if (url.endsWith(".aif")) {
            type = "audio/aif";
        } else if (url.endsWith(".sd")) {
            type = "audio/x-esps";
        } else if (url.endsWith(".au")) {
            type = "audio/au";
        } else {
            type = "";
        }

        return type;
    }

    /**
     * getContentStream() gets an InputStream for the media resource this is
     * the default implementation assuming it is just an url/file
     *
     * @return InputStream for the resource
     */
    public InputStream getContentStream() {
        InputStream is = null;

        if (url != null) {
            try {
                is = (new OurURL(url)).openStream();
            } catch (Exception e) {
                e.printStackTrace();
                is = null;
            }
        }

        return is;
    }
}
