/*
    GDAM - Geoff & Dave's Audio Mixer
    Copyright (C) 1999    Dave Benson, Geoff Matters.

    This library 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 library 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
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA

    Contact:
        daveb@ffem.org <Dave Benson>
        geoff@ugcs.caltech.edu <Geoff Matters>
*/
#ifndef __GDAM_SINK_H__
#define __GDAM_SINK_H__

typedef struct _GdamSink GdamSink;
typedef struct _GdamSinkClass GdamSinkClass;

#include <gtk/gtkobject.h>
#include "gdassource.h"
#include "gdamserverobject.h"
#include <gdam/common/gdambuffer.h>
#include <gdam/common/gdamsample.h>
#include <gdam/common/gdamarg.h>


#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */


GtkType gdam_sink_get_type();
#define GDAM_TYPE_SINK              (gdam_sink_get_type ())
#define GDAM_SINK(obj)              (GTK_CHECK_CAST ((obj), GDAM_TYPE_SINK, GdamSink))
#define GDAM_SINK_CLASS(klass)      (GTK_CHECK_CLASS_CAST ((klass), GDAM_TYPE_SINK, GdamSinkClass))
#define GDAM_IS_SINK(obj)           (GTK_CHECK_TYPE ((obj), GDAM_TYPE_SINK))
#define GDAM_IS_SINK_CLASS(klass)   (GTK_CHECK_CLASS_TYPE ((klass), GDAM_TYPE_SINK))

struct _GdamSink {
	GdamServerObject    object;

	GdasSource*	    feed;
	gchar*		    device_name;
};

struct _GdamSinkClass {
	GdamServerObjectClass      parent_class;
        GdamBuffer       *(*interpret_command) (GdamSink        *sink,
                                                GdamBuffer      *command);
#if 0
	/* Return values:
	 *      positive: the number of bytes written into buffer,
	 *      0 normal end of stream,
	 *      -1 error end of stream.
	 */
	int		   (*write)            (GdamSink*        output,
	                                        const GdamSample*samples,
						int              max_read);
#endif

        void               (*remove_source)    (GdamSink        *parent);

	/* Will only be called when the source has no "feed". */
        gboolean           (*set_source)       (GdamSink        *parent, 
                                                GdasSource      *child);

        gboolean           (*open)             (GdamSink        *sink,
                                                const char      *dev_name,
                                                const char      *dev_options);
	guint              (*get_latency)      (GdamSink        *sink);
        void               (*close)            (GdamSink        *sink);
};

/* Create a new sink, initialized with the given arguments. */
GdamSink   *gdam_sink_new_generic_v    (const char       *type_name,
                                        int               num_args,
                                        GdamArg          *args);

/* This may call remove_source before set_source. */
gboolean    gdam_sink_set_source       (GdamSink         *sink,
                                        GdasSource       *source);
void        gdam_sink_remove_source    (GdamSink         *sink);

gboolean    gdam_sink_open             (GdamSink         *sink,
                                        const char       *device_name,
                                        const char       *device_options);
void        gdam_sink_close            (GdamSink         *sink);

/* Just wrappers around the virtual functions-- should only be
 * used by other sources or devices. */
int         gdam_sink_write            (GdamSink         *input,
                                        const GdamSample *samples,
                                        int               max_read);
GdamBuffer *gdam_sink_interpret_command(GdamSink         *sink,
                                        GdamBuffer       *command);
guint       gdam_sink_get_latency      (GdamSink         *sink);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif
