/*
    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_BUILDER_H_
#define __GDAM_BUILDER_H_


typedef struct _GdamBuilder GdamBuilder;
typedef struct _GdamBuilderClass GdamBuilderClass;


#include "gdammodel.h"
#include "gdamfilter.h"
#include "gdamview.h"

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

GtkType gdam_builder_get_type();
#define GDAM_TYPE_BUILDER			(gdam_builder_get_type ())
#define GDAM_BUILDER(obj)              (GTK_CHECK_CAST ((obj), GDAM_TYPE_BUILDER, GdamBuilder))
#define GDAM_BUILDER_CLASS(klass)      (GTK_CHECK_CLASS_CAST ((klass), GDAM_TYPE_BUILDER, GdamBuilderClass))
#define GDAM_IS_BUILDER(obj)           (GTK_CHECK_TYPE ((obj), GDAM_TYPE_BUILDER))
#define GDAM_IS_BUILDER_CLASS(klass)   (GTK_CHECK_CLASS_TYPE ((klass), GDAM_TYPE_BUILDER))

/* The builder is a filter stack in which filters can be added, removed,
 * temporarily disabled, and rearranged.  Builder is itself a filter, and
 * one builder can contain another.  */

struct _GdamBuilderClass {
	//GdamModelClass		builder_class;
	GdamFilterClass		        builder_class;
};
struct _GdamBuilder {
        /* The structure for our base class */
	//GdamModel			builder;
	GdamFilter			builder;
	
	/* This is the child component from which builder gets its input. */
	GdamModel*			component;

	/* A doubly linked list of filters in the stack.  List is in 
	 * the order that filters process data.  Filters_in is the head
	 * of the list, the filter closest to our input component (and 
	 * has dummy_gain_in as a child).  Filters_out is the tail of the
	 * list, the outermost filter on the stack, meaning it gets its 
	 * input through all the other filters and is the child of 
	 * dummy_gain_out */
	GList*				filters_in;
	GList*				filters_out;

	GHashTable*			disabled_filters;
	GHashTable*			saveable_filters;

	/* These are sentinels at the top and bottom of the
	 * filter stack.  dummy_gain_in has our input component
	 * as a child, dummy_gain_out gets its input from the
	 * outermost filter on the stack. */
	GdamFilter*			dummy_gain_in;
	GdamFilter*			dummy_gain_out;
};

typedef struct _GdamBuilderSkinInterface GdamBuilderSkinInterface;
struct _GdamBuilderSkinInterface {
	void			      (*append_skin)
					(GdamView*   skin,
					 GdamView*   subskin);
};

GdamBuilderSkinInterface* gdam_builder_skin_interface_get
                                       (GdamView*);
void                      gdam_builder_skin_interface_register 
	                               (GtkType           type,
				        GdamBuilderSkinInterface*);
					 

/* set / get the child component from which we get our input */
void       gdam_builder_set_component  (GdamBuilder*      builder,
                                        GdamModel*        component);
GdamModel* gdam_builder_get_component  (GdamBuilder*      builder);

/* add a filter to the stack */
void       gdam_builder_append_filter  (GdamBuilder*      builder,
                                        GdamFilter*       model,
					gboolean          enabled,
					gboolean          saveable);

void       gdam_builder_disable_filter (GdamBuilder*      builder,
                                        GdamFilter*       filter);
void       gdam_builder_enable_filter  (GdamBuilder*      builder,
                                        GdamFilter*       filter);
/* not actually implemented yet...
void       gdam_builder_prepend_filter (GdamBuilder*      builder,
                                        GdamFilter*       model);
*/
void       gdam_builder_move_filter    (GdamBuilder*      builder,
                                        GdamFilter*       model,
					int               new_index);
void       gdam_builder_remove_filter  (GdamBuilder*      builder,
                                        GdamFilter*       to_remove);

/* For debugging... */
void       gdam_builder_print_stack    (GdamBuilder* builder);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif
