/* Network-Integrated Multimedia Middleware (NMM)
 * http://www.motama.com/nmm.html
 *
 * Copyright (C) 2006-2007
 * Motama GmbH, Saarbruecken, Germany
 * http://www.motama.com
 *
 * This file is part of NMM. 
 * 
 * NMM 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; only version 2 of the License.      
 * 
 * NMM 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 NMM; if not, write to the Free Software Foundation,    
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

#include "nmm/multimedia/INode.idl"

module NMM {
  
  /** Timeshifting interface.
   * The interface for the timeshifting node.
   */
  interface ITimeshifting {
    /** Main working mode.
     * The main working mode controls what happens to incoming data.
     */
    enum Mode {
      /** Live mode.
       * Every arriving buffer is forwarded and, if enabled, backed up in memory for instant replay.
       */
      LIVE,
      
      /** File buffer mode.
       * Buffers and events are buffered in a file buffer.
       * This mode is divided up in different play modes.
       */
      FILEBUF
    };
    
    /** Play mode.
     * The play mode controls what data is sent to the output if the main mode is FILEBUF.
     */
    enum PlayMode {
      /** Playback mode.
       * Buffers are sent in the order of arrival, but possibly delayed.
       */
      PLAY,
      
      /** Pause mode.
       * No buffers are sent.
       */
      PAUSE,
      
      /** Fast forward mode.
       * Only I-Frames are sent, and a certain number of buffers are skipped, depending on a speed parameter.
       * If there are no more buffers, the node automatically switches to FB_LIVE mode.
       */
      FAST_FORWARD,
      
      /** Rewind mode.
       * Like fast-forward mode, except that buffers are sent in reverse order and
       * if there are no more buffers, the node automatically switches to PLAY mode.
       */
      REWIND,
      
      /** Buffered live mode.
       * Arriving buffers are sent immediately.
       */
      FB_LIVE
    };
    
    /** @name Memory Buffer
     */
    //@{
    /** Enable memory buffer.
     * Enable a memory buffer for instant replay that holds up to @a size buffers.
     * @param size Maximum number of buffers in the memory buffer
     */
    void enableMemBuf(in nmm_uint32 size = 60);
    
    /** Disable memory buffer.
     * Disable and free the memory buffer. Set the @a play flag for instant replay.
     * @param play If true, start playback at the beginning of the buffer
     */
    void disableMemBuf(in nmm_bool play = false);

    /** Is memory buffer enabled.
     * @return true if the memorybuffer is enabled
     */
    nmm_bool isMemBuf();
    
    /** Keep incoming data.
     * Control whether to keep incoming data (and forward no buffers) or not.
     * @param keep if true, keep data
     */
    void keepData(in nmm_bool keep);
    //@}
    
    /** @name Modes and Play Modes
     */
    //@{
    /** Get current main mode.
     * @return Current main mode
     */
    ITimeshifting::Mode getMode() const;
    
    /** Get current play mode.
     * @return Current play mode, if the main mode is FILEBUF
     */
    ITimeshifting::PlayMode getPlayMode() const;
    
    /** Switch to LIVE mode.
     * Switch the node into the LIVE main mode. This completely disables timeshifting and file buffering.
     * @param enable_memory_buffer Enable memory buffering
     * @param send_sync_reset Send a ISyncReset::syncReset event after the mode change
     */
    void setModeLive(in nmm_bool enable_memory_buffer = true, in nmm_bool send_sync_event = true);
    
    /** Set play mode to FB_LIVE.
     * Switch the node into FILEBUF mode and set the play mode to FB_LIVE.
     * @param send_sync_reset Send a ISyncReset::syncReset event after the mode change
     */
    void setModeFBLive(in nmm_bool send_sync_event = true);
    
    /** Set play mode to PLAY.
     * Set the play mode to PLAY. The main mode must be FILEBUF!
     * @param send_sync_reset Send a ISyncReset::syncReset event after the mode change
     */
    void setModePlay(in nmm_bool send_sync_reset = true);
    
    /** Set play mode to PAUSE.
     * Switch the node into FILEBUF mode and set the play mode to PAUSE.
     */
    void setModePause();
    
    /** Set play mode to FAST_FORWARD.
     * Set the play mode to FAST_FORWARD. The main mode must be FILEBUF!
     * Also set the playback speed, which is the number of I-Frames to skip, to @a speed.
     * If there are no more buffers to send, the play mode is imediately set to FB_LIVE.
     * @param speed Playback speed (number of I-Frames to skip for every I-frame sent)
     */
    void setModeFastForward(in nmm_int32 speed = 5);
    
    /**
     * Set play mode to REWIND.
     * Set the play mode to REWIND. The main mode must be FILEBUF!
     * Also set the playback speed, which is the number of I-Frames to skip, to @a speed.
     * If there are no more buffers to send, the play mode is imediately set to PLAY.
     * @param speed Playback speed (number of I-Frames to skip for every I-frame sent)
     */
    void setModeRewind(in nmm_int32 speed = -5);
    //@}
    
    /** @name File Buffer
     */
    //@{
    /** Set file buffer filename.
     * Use another file for buffering if current file is empty.
     * @param filename Buffer filename
     */
    void setFilename(in string filename);
    
    /** Set file buffer threshold.
     * Sets the file buffer threshold, which is the maximum number of GOPs to store in the file buffer.
     * If the buffer is full, the oldest recorded GOPs is overwritten.
     * @param threshold File buffer threshold
     */
    void setFileBufferThreshhold(in nmm_uint32 threshold) limited(INode::CONSTRUCTED);
    
    /** Set maximum buffer size.
     * Sets the maximum size of arriving buffers to @a size. This should be the maximum size of a GOP.
     * @param size Maximum buffer size
     * @return SUCCESS if the method succeeded, otherwise FAILURE
     */
    Result setBufferSize(in nmm_uint32 size);
    
    /** Enter recording mode.
     * Switch the file buffer into recording mode. In this mode, no blocks are overwritten and the file buffer
     * is not deleted after the node is destroyed.
     */
    void startRecord(); 

    /** Leave recording mode.
     * Switch the file buffer back from recording mode into to mode.
     */
    void stopRecord();  

    /** Is file buffer in recording mode.
     * @return True if the file buffer is in recording mode
     */
    nmm_bool isRecording();
    
    /** Save file buffer to file.
     * Saves the file buffer (without events) to a file.
     * @param filename Save filename
     */
    Result saveToFile(in string filename);
    //@}
    
    /** @name Timing
     */
    //@{
    /** Get read position.
     * This method returns the current read position in the timeshifting buffer.
     * In FILEBUF mode, this value is between the values returned by getStartTime and getLivePosition.
     * In LIVE mode, this returns the same value as getLivePosition.
     * @return Current read position
     */
    Time getReadPosition() const limited(INode::STARTED);
    
    /** Get starting time.
     * This method returns the (absolute) time when the tiomeshifting buffer begins.
     * In LIVE mode, this is the same value as returned by getLivePosition.
     * @return The start time of the timeshifting buffer
     */
    Time getStartTime() const limited(INode::STARTED);
    
    /** Get live position.
     * This method returns the (absolute) time when the timeshifting buffer ends.
     * In LIVE mode, this is the same value as returned by getStartTime.
     * @return The end time of the timeshifting buffer
     */
    Time getLivePosition() const limited(INode::STARTED);
    
    /** Get live offset.
     * This method computes the "live" offset when timeshifting. This is the offset between the
     * live position and the current read position.
     * In LIVE mode, the live offset is always zero
     * @return The live offset
     */
    Interval getLiveOffset() const limited(INode::STARTED);

    /** Get file size.
     * This method computes the length of the timeshifting buffer as a time interval.
     * In LIVE mode, the file length is always zero
     * @return The length of the timeshifting buffer
     */
    Interval getFileLength() const limited(INode::STARTED);
    //@}
  };


  /** Time shifting listener.
   * Provides methods for Events sent by TimeshiftingNodes.
   */
  interface ITimeshiftingListener {
    /** Time shifting begins.
     * This method signals, that rewinding the timeshifting buffer has
     * reached its beginning and so, the TimeshiftingNode has changed
     * its internal state from ITimeshifting::REWIND to
     * ITimeshifting::PLAY.
     */
    Result timeshiftingBegin() instream;
    
    /** Live mode.
     * this method signals, that fast-forwarding the timeshifting
     * buffer has reached its end and so, the TimeshiftingNode has
     * changed its internal state from ITimeshfting::FAST_FORWARD to
     * ITimeshifting::FB_LIVE.
     */
    Result live() instream;

    /** Set progress.
     * TimeshiftingNodes send progress as a absolute Time, which is
     * the Time of the stream currently displayed.
     * @param ts_time The current Time of the (timeshifted) stream.
     */
    Result setProgress(in Time ts_time) instream;
  };
  
}
