/*
 * Copyright @ 2015 Atlassian Pty Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.jitsi.service.neomedia.recording;

import org.jitsi.service.neomedia.*;

import java.io.*;
import java.util.*;

/**
 * The call recording interface. Provides the capability to start and stop call
 * recording.
 *
 * @author Dmitri Melnikov
 * @author Lubomir Marinov
 * @author Boris Grozev
 */
public interface Recorder
{
    /**
     * The name of the configuration property the value of which specifies the
     * full path to the directory with media recorded by <tt>Recorder</tt> (e.g.
     * the media being sent and received in a <tt>Call</tt>).
     */
    public static final String SAVED_CALLS_PATH
        = "net.java.sip.communicator.impl.neomedia.SAVED_CALLS_PATH";

    /**
     * The name of the configuration property the value of which specifies the
     * format in which media is to be recorded by <tt>Recorder</tt> (e.g. the
     * media being sent and received in a <tt>Call</tt>).
     */
    public static final String FORMAT
        = "net.java.sip.communicator.impl.neomedia.Recorder.FORMAT";

    /**
     * Adds a new <tt>Listener</tt> to the list of listeners interested in
     * notifications from this <tt>Recorder</tt>.
     *
     * @param listener the new <tt>Listener</tt> to be added to the list of
     * listeners interested in notifications from this <tt>Recorder</tt>
     */
    public void addListener(Listener listener);

    /**
     * Gets a list of the formats in which this <tt>Recorder</tt> supports
     * recording media.
     *
     * @return a <tt>List</tt> of the formats in which this <tt>Recorder</tt>
     * supports recording media
     */
    public List<String> getSupportedFormats();

    /**
     * Removes an existing <tt>Listener</tt> from the list of listeners
     * interested in notifications from this <tt>Recorder</tt>.
     *
     * @param listener the existing <tt>Listener</tt> to be removed from the
     * list of listeners interested in notifications from this <tt>Recorder</tt>
     */
    public void removeListener(Listener listener);

    /**
     * Starts the recording of the media associated with this <tt>Recorder</tt>
     * (e.g. the media being sent and received in a <tt>Call</tt>) into a file
     * with a specific name.
     *
     * @param format the format into which the media associated with this
     * <tt>Recorder</tt> is to be recorded into the specified file
     * @param filename the name of the file into which the media associated with
     * this <tt>Recorder</tt> is to be recorded
     * @throws IOException if anything goes wrong with the input and/or output
     * performed by this <tt>Recorder</tt>
     * @throws org.jitsi.service.neomedia.MediaException if anything else goes wrong while starting the
     * recording of media performed by this <tt>Recorder</tt>
     */
    public void start(String format, String filename)
        throws IOException,
            MediaException;

    /**
     * Stops the recording of the media associated with this <tt>Recorder</tt>
     * (e.g. the media being sent and received in a <tt>Call</tt>) if it has
     * been started and prepares this <tt>Recorder</tt> for garbage collection.
     */
    public void stop();

    /**
     * Represents a listener interested in notifications from a <tt>Recorder</tt>.
     *
     * @author Lubomir Marinov
     */
    public interface Listener
    {
        /**
         * Notifies this <tt>Listener</tt> that a specific <tt>Recorder</tt> has
         * stopped recording the media associated with it.
         *
         * @param recorder the <tt>Recorder</tt> which has stopped recording its
         * associated media
         */
        public void recorderStopped(Recorder recorder);
    }

    /**
     * Put the recorder in mute state. It won't record the local input.
     * This is used when the local call is muted and we don't won't to record
     * the local input.
     * @param mute the new value of the mute property
     */
    public void setMute(boolean mute);

    /**
     * Returns the filename we are last started or stopped recording to,
     * null if not started.
     * @return the filename we are last started or stopped recording to,
     * null if not started.
     */
    public String getFilename();

    /**
     * Sets the <tt>RecorderEventHandler</tt> which this <tt>Recorder</tt>
     * should notify when events related to recording (such as start/end of a
     * recording) occur.
     * @param eventHandler the <tt>RecorderEventHandler</tt> to set.
     */
    public void setEventHandler(RecorderEventHandler eventHandler);

    /**
     * Gets the <tt>Synchronizer</tt> of this <tt>Recorder</tt>.
     * @return  the <tt>Synchronizer</tt> of this <tt>Recorder</tt>.
     */
    public Synchronizer getSynchronizer();

    /**
     * Sets the <tt>Synchronizer</tt> that this instance should use.
     * @param synchronizer the <tt>Synchronizer</tt> to set.
     */
    public void setSynchronizer(Synchronizer synchronizer);

    /**
     * Gets the <tt>MediaStream</tt> associated with this <tt>Recorder</tt>.
     * @return the <tt>MediaStream</tt> associated with this <tt>Recorder</tt>.
     */
    public MediaStream getMediaStream();
}
