/*****************************************************************************
 * FVLMPlayerImpl.java FVLC VLC Java RMI Binding
 *****************************************************************************
 *
 * @author : Festastic, <info@festastic.com>
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *
 */
package com.festastic.fvlc.rmi;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

import org.videolan.jvlc.JVLC;
import org.videolan.jvlc.VLM;

import com.festastic.fvlc.util.VLCLogScanner;

public class FVLMPlayerImpl extends UnicastRemoteObject implements FVLMPlayer {

    private boolean       isInitialized = false;
    private VLM           vlm;
    private VLCLogScanner scanner;

    public FVLMPlayerImpl() throws RemoteException {
    }

    /**
     * Initialize VLM instance.
     *
     * @param JVLC
     *            jvlc
     */
    public synchronized void init(JVLC jvlc) {
        vlm = new VLM(jvlc);
        scanner = new VLCLogScanner(jvlc);

        notifyAll();
        isInitialized = true;
    }

    public int getSourcePort(String name) throws RemoteException {
        waitForInitialize();
        return scanner.getSourcePort(name);
    }

    public String startStream(String name, String uri, final String addr, final int port)
            throws RemoteException {

        waitForInitialize();

        final String streamAddress = "udp://@:" + port;
        final String output = String.format("#std{mux=ts,access=udp,dst=%s:%s}", addr, port);

        vlm.addBroadcast(name, uri, output, null, true, false);
        vlm.playMedia(name);

        synchronized (scanner) {
            scanner.setKey(name);
            new Thread(scanner).start();

            try {
                scanner.wait(3000L);
            } catch (final InterruptedException e) {
                e.printStackTrace();
            }
        }

        return streamAddress;
    }

    public void stopStream(String name) throws RemoteException {
        waitForInitialize();
        vlm.stopMedia(name);
        vlm.deleteMedia(name);
        scanner.removeSourcePort(name);
    }

    public void toggleStream(String name, boolean isPlaying) throws RemoteException {
        waitForInitialize();
        if (isPlaying) {
            vlm.stopMedia(name);
        } else {
            vlm.playMedia(name);
        }
    }

    public void seekStream(String name, float position) throws RemoteException {
        waitForInitialize();
        vlm.seekMedia(name, position);
    }

    /**
     * wait for initializing. for case if method is called remotely before
     * initialize done.
     */
    private synchronized void waitForInitialize() {
        if (!isInitialized) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

}
