/*
 * farsight-stream.h - Header for core API streams
 *
 * Farsight Voice+Video library
 * Copyright 2005,2006 Collabora Ltd.
 * Copyright 2005,2006 Nokia Corp.
 *   @author Rob Taylor <rob.taylor@collabora.co.uk>.
 *   @author Philippe Kalaf <philippe.kalaf@collabora.co.uk>
 * Copyright (c) 2005 INdT
 *   @author Andre Moreira Magalhaes <andre.magalhaes@indt.org.br>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser 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 Lesser 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
 */

#ifndef __FARSIGHT_STREAM_H__
#define __FARSIGHT_STREAM_H__

#include <glib.h>
#include <glib-object.h>
#include <gst/gstelement.h>

#include "farsight-codec.h"

G_BEGIN_DECLS

/* TYPE MACROS */
#define FARSIGHT_TYPE_STREAM \
  (farsight_stream_get_type())
#define FARSIGHT_STREAM(obj) \
  (G_TYPE_CHECK_INSTANCE_CAST((obj), FARSIGHT_TYPE_STREAM, FarsightStream))
#define FARSIGHT_STREAM_CLASS(klass) \
  (G_TYPE_CHECK_CLASS_CAST((klass), FARSIGHT_TYPE_STREAM, FarsightStreamClass))
#define FARSIGHT_IS_STREAM(obj) \
  (G_TYPE_CHECK_INSTANCE_TYPE((obj), FARSIGHT_TYPE_STREAM))
#define FARSIGHT_IS_STREAM_CLASS(klass) \
  (G_TYPE_CHECK_CLASS_TYPE((klass), FARSIGHT_TYPE_STREAM))
#define FARSIGHT_STREAM_GET_CLASS(obj) \
  (G_TYPE_INSTANCE_GET_CLASS ((obj), FARSIGHT_TYPE_STREAM, FarsightStreamClass))

typedef struct _FarsightStream FarsightStream;
typedef struct _FarsightStreamClass FarsightStreamClass;
typedef struct _FarsightStreamPrivate FarsightStreamPrivate;

/**
 * FarsightStreamDirection:
 * @FARSIGHT_STREAM_DIRECTION_NONE: No stream direction defined.
 * @FARSIGHT_STREAM_DIRECTION_SENDONLY: Stream only sends to the other client.
 * @FARSIGHT_STREAM_DIRECTION_RECEIVEONLY: Stream only recives from the other client
 * @FARSIGHT_STREAM_DIRECTION_BOTH: Stream is bidirectional.
 *
 * Enum for the direction of a #FarsightStream
 */
typedef enum
{
  FARSIGHT_STREAM_DIRECTION_NONE = 0,
  FARSIGHT_STREAM_DIRECTION_SENDONLY = 1,
  FARSIGHT_STREAM_DIRECTION_RECEIVEONLY = 2,
  FARSIGHT_STREAM_DIRECTION_BOTH = 3,
  FARSIGHT_STREAM_DIRECTION_LAST
} FarsightStreamDirection;

/**
 * FarsightStreamState:
 * @FARSIGHT_STREAM_STATE_DISCONNECTED: The stream is not connected
 * @FARSIGHT_STREAM_STATE_CONNECTING: The stream is trying to establish a
 * connection
 * @FARSIGHT_STREAM_STATE_CONNECTED: The stream is connected and can start
 * streaming.
 *
 * An enum used to signal the state of a #FarsightStream
 */
typedef enum
{
  FARSIGHT_STREAM_STATE_DISCONNECTED,
  FARSIGHT_STREAM_STATE_CONNECTING,
  FARSIGHT_STREAM_STATE_CONNECTED
} FarsightStreamState;

/**
 * FarsightStreamError:
 * @FARSIGHT_STREAM_ERROR_EOS: The stream was erronously ended
 * @FARSIGHT_STREAM_ERROR_UNKNOWN: An unknown error has occured
 * @FARSIGHT_STREAM_UNKNOWN_ERROR: An unknown error has occured (depricated)
 * @FARSIGHT_STREAM_ERROR_TIMEOUT: Timed out on attempt to establish a
 * connection
 * @FARSIGHT_STREAM_ERROR_NETWORK: A network error has occured
 * @FARSIGHT_STREAM_ERROR_PIPELINE_SETUP: An error has occured while setting up
 * the required pipeline
 * @FARSIGHT_STREAM_ERROR_RESOURCE: An error has occured on a required resource
 *
 * An enum used to signal errors that occur on a #FarsightStream
 */
typedef enum
{
  FARSIGHT_STREAM_ERROR_EOS,
  FARSIGHT_STREAM_UNKNOWN_ERROR,
  FARSIGHT_STREAM_ERROR_UNKNOWN = FARSIGHT_STREAM_UNKNOWN_ERROR,
  FARSIGHT_STREAM_ERROR_TIMEOUT,
  FARSIGHT_STREAM_ERROR_NETWORK,
  FARSIGHT_STREAM_ERROR_PIPELINE_SETUP,
  FARSIGHT_STREAM_ERROR_RESOURCE,
  FARSIGHT_STREAM_ERROR_LAST = FARSIGHT_STREAM_ERROR_RESOURCE
} FarsightStreamError;

/**
 * FarsightStreamDTMFEvent:
 *
 * An enum that represents the different DTMF event that can be sent to a
 * #FarsightStream. The values corresponds those those defined in RFC 4733
 * The rest of the possibles values are in the IANA registry at:
 * http://www.iana.org/assignments/audio-telephone-event-registry
 *
 */
typedef enum
{
  FARSIGHT_DTMF_EVENT_0 = 0,
  FARSIGHT_DTMF_EVENT_1 = 1,
  FARSIGHT_DTMF_EVENT_2 = 2,
  FARSIGHT_DTMF_EVENT_3 = 3,
  FARSIGHT_DTMF_EVENT_4 = 4,
  FARSIGHT_DTMF_EVENT_5 = 5,
  FARSIGHT_DTMF_EVENT_6 = 6,
  FARSIGHT_DTMF_EVENT_7 = 7,
  FARSIGHT_DTMF_EVENT_8 = 8,
  FARSIGHT_DTMF_EVENT_9 = 9,
  FARSIGHT_DTMF_EVENT_STAR = 10,
  FARSIGHT_DTMF_EVENT_POUND = 11,
  FARSIGHT_DTMF_EVENT_A = 12,
  FARSIGHT_DTMF_EVENT_B = 13,
  FARSIGHT_DTMF_EVENT_C = 14,
  FARSIGHT_DTMF_EVENT_D = 15
} FarsightStreamDTMFEvent;


/**
 * FarsightStreamDTMFMethod:
 * @FARSIGHT_DTMF_METHOD_AUTO: Send in any possible way
 * @FARSIGHT_DTMF_METHOD_RTP_RFC4733: Send as a special payload type defined by RFC 4733 
 * (which obsoletes RFC 2833)
 * @FARSIGHT_DTMF_METHOD_SOUND: Send as sound
 *
 * An enum that represents the different ways a DTMF event can be sent
 */
typedef enum
{
  FARSIGHT_DTMF_METHOD_AUTO = 0,
  FARSIGHT_DTMF_METHOD_RTP_RFC4733,
  FARSIGHT_DTMF_METHOD_SOUND
} FarsightStreamDTMFMethod;

struct _FarsightStreamClass
{
  GObjectClass parent_class;

  /*virtual methods */
  void (* prepare_transports) (FarsightStream *self);
  GstElement * (* get_pipeline) (FarsightStream *self);
  gboolean (* set_pipeline) (FarsightStream *self, GstElement *pipeline);
  G_CONST_RETURN GList * (* get_native_candidate_list) (FarsightStream *self);
  GList * (* get_native_candidate) (FarsightStream *self,
                                    const gchar* candidate_id);
  void (* set_remote_candidate_list) (FarsightStream *self, 
                                      const GList *remote_candidates);
  void (* add_remote_candidate) (FarsightStream *self,
                                 const GList *remote_candidate);
  void (* remove_remote_candidate) (FarsightStream *self, 
                                    const gchar *remote_candidate_id);
  gboolean (* set_active_candidate_pair) (FarsightStream *self,
                                          const gchar *native_candidate_id,
                                          const gchar *remote_candidiate_id);

  /* void (*set_local_codec_selection) (FarsightStream *self, const GList *ids); */
  G_CONST_RETURN GList * (* get_local_codecs) (FarsightStream *self);
  gboolean (* set_remote_codecs) (FarsightStream *self,
                              const GList *codecs);
  GList *(* get_codec_intersection) (FarsightStream *self);
  void (* set_codec_preference_list) (FarsightStream *self,
          const GArray *codec_pref);
  void (* set_active_codec) (FarsightStream *self, 
                             gint id);
  gint (* get_active_codec) (FarsightStream *self);
  gboolean (* set_sink) (FarsightStream *self, 
                         GstElement *sink);
  gboolean (* set_sink_filter) (FarsightStream *self, 
                         GstCaps *filter);
  GstElement * (* get_sink) (FarsightStream *self);
  gboolean (* set_source) (FarsightStream *self, 
                          GstElement *source);
  gboolean (* set_source_filter) (FarsightStream *self, 
                         GstCaps *filter);
  GstElement * (* get_source) (FarsightStream *self);
  gboolean (* start) (FarsightStream *self);
  void (* stop) (FarsightStream *self);
  gboolean (*set_sending) (FarsightStream *self, gboolean sending);
  
  gboolean (* start_telephony_event) (FarsightStream *self, 
                                      guint8 ev,
                                      guint8 volume,
                                      FarsightStreamDTMFMethod method);
  gboolean (* stop_telephony_event) (FarsightStream *self,
                                     FarsightStreamDTMFMethod method);

  gboolean (*preload_receive_pipeline) (FarsightStream *self,
                                        gint payload_type);

  gpointer _padding[1];         /* padding for binary-compatible expansion */
};

/**
 * FarsightStream:
 *
 * A object that represents and manages a single real-time audio/video stream.
 *
 */
struct _FarsightStream
{
  GObject parent;

  FarsightStreamPrivate *priv;
};

GType farsight_stream_get_type (void);

FarsightMediaType farsight_stream_get_media_type (FarsightStream *self);

void farsight_stream_prepare_transports (FarsightStream *self);

G_CONST_RETURN GList *farsight_stream_get_native_candidate_list (FarsightStream *self);
GList *farsight_stream_get_native_candidate (FarsightStream *self, 
                                             const gchar*candidate_id);

void farsight_stream_set_remote_candidate_list (FarsightStream *self, 
                                                const GList *remote_candidates);
void farsight_stream_add_remote_candidate (FarsightStream *self,
                                           const GList *remote_candidate);
void farsight_stream_remove_remote_candidate (FarsightStream *self, 
                                              const gchar *remote_candidate_id);

gboolean farsight_stream_set_active_candidate_pair (FarsightStream *self,
                                                    const gchar *native_candidate_id,
                                                    const gchar *remote_candidate_id);

/* void farsight_stream_set_local_codecs (FarsightStream *self,
                                          const GList *ids); */
G_CONST_RETURN GList *farsight_stream_get_local_codecs (FarsightStream *self);

gboolean farsight_stream_set_remote_codecs (FarsightStream *self,
                                        const GList *codecs);
/* G_CONST_RETURN GList *farsight_stream_get_remote_codecs (FarsightStream *self); */

GList *farsight_stream_get_codec_intersection (FarsightStream *self);

void farsight_stream_set_codec_preference_list (FarsightStream *self,
        const GArray *codec_pref);

void farsight_stream_set_active_codec (FarsightStream *self, 
                                       gint id);
gint farsight_stream_get_active_codec (FarsightStream *self);

gboolean farsight_stream_set_sink (FarsightStream *self, 
                                   GstElement *sink);

GstElement *farsight_stream_get_sink (FarsightStream *self);

gboolean farsight_stream_set_sink_filter (FarsightStream *self, GstCaps *filter);

gboolean farsight_stream_set_source (FarsightStream *self, 
                                     GstElement *source);

GstElement *farsight_stream_get_source (FarsightStream *self);

gboolean farsight_stream_set_source_filter (FarsightStream *self, GstCaps *filter);

FarsightStreamState farsight_stream_get_state (FarsightStream *self);
FarsightStreamDirection farsight_stream_get_direction (FarsightStream *self);
FarsightStreamDirection farsight_stream_get_current_direction (FarsightStream *self);
FarsightMediaType farsight_stream_get_media_type (FarsightStream *self);
GstElement * farsight_stream_get_pipeline (FarsightStream *self);
gboolean farsight_stream_set_pipeline (FarsightStream *self,
    GstElement *pipeline);

gboolean farsight_stream_start (FarsightStream *self);
void farsight_stream_stop (FarsightStream *self);
gboolean farsight_stream_set_sending (FarsightStream *self, gboolean sending);

/* Signals */
void farsight_stream_signal_error (FarsightStream *self, 
                                   FarsightStreamError err,
                                   const gchar *mesg);
void farsight_stream_signal_native_candidates_prepared (FarsightStream *self);
void farsight_stream_signal_new_native_candidate (FarsightStream *self, 
                                                  const gchar *candidate_id);
void farsight_stream_signal_new_active_candidate_pair (FarsightStream *self,
                                                       const gchar *native_candidate_id, 
                                                       const gchar *remote_candidate_id);
void farsight_stream_signal_codec_changed (FarsightStream *self,
                                           int codec_id);
void farsight_stream_signal_state_changed (FarsightStream *self,
                                           FarsightStreamState state,
                                           FarsightStreamDirection direction);
void farsight_stream_signal_sink_pad_ready (FarsightStream *self,
                                            GstPad *pad);

gboolean farsight_stream_start_telephony_event (FarsightStream *self, 
                                                guint8 ev,
                                                guint8 volume);

gboolean farsight_stream_stop_telephony_event (FarsightStream *self);

gboolean farsight_stream_start_telephony_event_full (FarsightStream *self,
                                                     guint8 ev,
                                                     guint8 volume,
                                                     FarsightStreamDTMFMethod method);

gboolean farsight_stream_stop_telephony_event_full (FarsightStream *self,
                                                    FarsightStreamDTMFMethod method);

gboolean farsight_stream_preload_receive_pipeline (
    FarsightStream *self, gint payload_type);



G_END_DECLS
#endif
