/*
    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_MIX_H_
#define __GDAM_MIX_H_


typedef struct _GdamMix GdamMix;
typedef struct _GdamMixClass GdamMixClass;
typedef struct _GdamMixElement GdamMixElement;

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

#include "gdammodel.h"
#include "gdamproducer.h"

GtkType gdam_mix_get_type();
#define GDAM_TYPE_MIX			(gdam_mix_get_type ())
#define GDAM_MIX(obj)              (GTK_CHECK_CAST ((obj), GDAM_TYPE_MIX, GdamMix))
#define GDAM_MIX_CLASS(klass)      (GTK_CHECK_CLASS_CAST ((klass), GDAM_TYPE_MIX, GdamMixClass))
#define GDAM_IS_MIX(obj)           (GTK_CHECK_TYPE ((obj), GDAM_TYPE_MIX))
#define GDAM_IS_MIX_CLASS(klass)   (GTK_CHECK_CLASS_TYPE ((klass), GDAM_TYPE_MIX))


struct _GdamMixElement {
	gdouble			start_time;
	gdouble			length;		/* or -1 if unknown */
	GdamProducer*		producer;
	int			element_state;
};

struct _GdamMixClass {
	GdamProducerClass	producer_class;
	/* Notification signals. */
	void                  (*element_deleted) (GdamMix*         mix,
	                                          GdamMixElement*  old_element);
	void                  (*element_added)   (GdamMix*         mix,
	                                          GdamMixElement*  new_element);
	void                  (*element_changed) (GdamMix*         mix,
	                                          GdamMixElement*  element);
	void                  (*elements_changed)(GdamMix*         mix);
};
struct _GdamMix {
	GdamProducer		producer;

	gboolean		is_looping;

	/* Loop length in seconds. */
	gdouble			loop_length;

	/* List of the models being mixed (GdamMixElements) */
	GSList*			elements;

	/* Length of a single beat in seconds.
	 * Er... we need more methods on this one... */
	gdouble			beat_length;

	int			freeze_count;
	gboolean		frozen_update;

	/* If this value is set, it is used to account for 
	 * lag when adding immediately. */
	gdouble			immediate_lag;
};

void        gdam_mix_set_beat_length(GdamMix*         mix,
			             gdouble          beat_length);

GdamMixElement*
            gdam_mix_add            (GdamMix*         mix,
                                     GdamProducer*    producer,
			             gdouble          offset);
void        gdam_mix_remove         (GdamMix*         mix,
                                     GdamProducer*    producer);
void        gdam_mix_set_start      (GdamMix*         mix,
			             GdamProducer*    producer,
                                     gdouble          start_time);
void        gdam_mix_set_loop_length(GdamMix         *mix,
			             gdouble          loop_length);

void        gdam_mix_freeze         (GdamMix*         mix);
void        gdam_mix_thaw           (GdamMix*         mix);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif
