#include <locale.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <gtk/gtk.h>
#include "../../common/looperdata.h"
#include "gtkloopview.h"
#include "configfile.h"

char* config_check_filename (char *filename){
	if (strcmp (".klp",(char*)(filename + strlen(filename) - 4))){
                filename = realloc(filename, sizeof(char) * (strlen(filename) + 5));
                filename = strcat(filename,".klp");
        }
	return filename;
}

int save_config (GList *looperlist, speciallist_t *bufferlist, char* spath, 
		char* cpath, char *filename, gint x, gint y, gint width, gint height, long samplerate){
	xmlDocPtr doc;
	int err;
	char txt[128];
	char *cmd = NULL;
	char *old_locale;
	GList *listptr = looperlist;
	looper_gui_t *looper = NULL;
	buffer_info_t *buf = NULL;
	xmlNodePtr topptr, looperptr, bufferptr;

	old_locale = setlocale(LC_NUMERIC,"C");

	doc = xmlNewDoc((xmlChar*)XML_DEFAULT_VERSION);
	topptr = xmlNewDocNode(doc, NULL, (xmlChar*)"kluppe", NULL);
	xmlAddChild ((xmlNodePtr)doc, topptr);

	xmlNewChild (topptr, NULL, (xmlChar*)"soundfilepath", (xmlChar*)spath);
	xmlNewChild (topptr, NULL, (xmlChar*)"configfilepath", (xmlChar*)cpath);
	sprintf (txt, "%d",(int)x);
        xmlNewChild (topptr, NULL, (xmlChar*)"window-xpos",(xmlChar*)txt);
	sprintf (txt, "%d",(int)y);
        xmlNewChild (topptr, NULL, (xmlChar*)"window-ypos",(xmlChar*)txt);
	sprintf (txt, "%d",(int)width);
	xmlNewChild (topptr, NULL, (xmlChar*)"window-width",(xmlChar*)txt);
	sprintf (txt, "%d",(int)height);
        xmlNewChild (topptr, NULL, (xmlChar*)"window-height",(xmlChar*)txt);
	sprintf (txt, "%ld",samplerate);
	xmlNewChild (topptr, NULL, (xmlChar*)"system-samplerate",(xmlChar*)txt);
	
	while (listptr){
		if ((looper = (looper_gui_t*)listptr->data) != NULL){
			looperptr  =  xmlNewChild (topptr, NULL, (xmlChar*)"looper", NULL);
			sprintf (txt, "%d", looper->id);
			xmlNewChild (looperptr, NULL, (xmlChar*)"id", (xmlChar*)txt);	
			sprintf (txt, "%d", looper_get_position(looper));
                        xmlNewChild (looperptr, NULL, (xmlChar*)"position",(xmlChar*)txt);
			
			if (looper->data){
				/* BUF??? */
				if (looper->data->buf){
					sprintf (txt, "%d", looper->data->buf->id);
					xmlNewChild (looperptr, NULL, (xmlChar*)"buffer", (xmlChar*)txt);
				}else 	xmlNewChild (looperptr, NULL, (xmlChar*)"buffer", (xmlChar*)"0");
				/*should use looperdatai's functions insetad of writing directly */
				sprintf (txt, "%f", looper->data->vol);
				xmlNewChild (looperptr, NULL, (xmlChar*)"vol", (xmlChar*)txt);
				sprintf (txt, "%f", looper->data->pan);
				xmlNewChild (looperptr, NULL, (xmlChar*)"pan",(xmlChar*)txt);
				sprintf (txt, "%f", looper->data->panswing);
				xmlNewChild (looperptr, NULL, (xmlChar*)"panswing",(xmlChar*)txt);
                                sprintf (txt, "%f", looper->data->recmix);
				xmlNewChild (looperptr, NULL, (xmlChar*)"recmix",(xmlChar*)txt);
				sprintf (txt, "%f", looper->data->speed);
                                xmlNewChild (looperptr, NULL, (xmlChar*)"speed",(xmlChar*)txt);

				sprintf (txt, "%f", looper->data->playpos);
				xmlNewChild (looperptr, NULL, (xmlChar*)"playpos",(xmlChar*)txt);
				sprintf (txt, "%ld", looper->data->recpos);
                                xmlNewChild (looperptr, NULL, (xmlChar*)"recpos",(xmlChar*)txt);
				sprintf (txt, "%ld", looper->data->loopstart);
                                xmlNewChild (looperptr, NULL, (xmlChar*)"loopstart",(xmlChar*)txt);
                                sprintf (txt, "%ld", looper->data->loopend);
                                xmlNewChild (looperptr, NULL, (xmlChar*)"loopend",(xmlChar*)txt);
				sprintf (txt, "%ld", looper->data->recstart);
                                xmlNewChild (looperptr, NULL, (xmlChar*)"recstart",(xmlChar*)txt);
                                sprintf (txt, "%ld", looper->data->recend);
                                xmlNewChild (looperptr, NULL, (xmlChar*)"recend",(xmlChar*)txt);

				sprintf (txt, "%d", looper->data->isplaying);
                                xmlNewChild (looperptr, NULL, (xmlChar*)"isplaying",(xmlChar*)txt);
                                sprintf (txt, "%d", looper->data->isrecording);
                                xmlNewChild (looperptr, NULL, (xmlChar*)"isrecording",(xmlChar*)txt);
				sprintf (txt, "%d", looper->data->linkrec2play);
                                xmlNewChild (looperptr, NULL, (xmlChar*)"linkrec2play",(xmlChar*)txt);
                                sprintf (txt, "%d", looper->data->keepabsolute);
                                xmlNewChild (looperptr, NULL, (xmlChar*)"keepabsolute",(xmlChar*)txt);
				sprintf (txt, "%d", looper->data->limiter);
				xmlNewChild (looperptr, NULL, (xmlChar*)"limiter",(xmlChar*)txt);

			
				if (gtk_toggle_button_get_active((GtkToggleButton*)looper->shuttlebutton))
					xmlNewChild (looperptr, NULL, (xmlChar*)"shuttle",(xmlChar*)"1");
				else
					xmlNewChild (looperptr, NULL, (xmlChar*)"shuttle",(xmlChar*)"0");

                                if (gtk_toggle_button_get_active((GtkToggleButton*)looper->minimizebutton))
                                        xmlNewChild (looperptr, NULL, (xmlChar*)"minimized",(xmlChar*)"1");
                                else
                                        xmlNewChild (looperptr, NULL, (xmlChar*)"minimized",(xmlChar*)"0");

				if (gtk_check_menu_item_get_active((GtkCheckMenuItem*)looper->snap2griditem))
                                	xmlNewChild (looperptr, NULL, (xmlChar*)"snap2grid",(xmlChar*)"1");
				else
					xmlNewChild (looperptr, NULL, (xmlChar*)"snap2grid",(xmlChar*)"0");

                                if (gtk_check_menu_item_get_active((GtkCheckMenuItem*)looper->showgriditem))
                                        xmlNewChild (looperptr, NULL, (xmlChar*)"showgrid",(xmlChar*)"1");
                                else
                                        xmlNewChild (looperptr, NULL, (xmlChar*)"showgrid",(xmlChar*)"0");

				sprintf (txt, "%.4lf",gtk_loopview_get_bpm(GTK_LOOPVIEW(looper->loopview)));
				xmlNewChild (looperptr, NULL, (xmlChar*)"bpm",(xmlChar*)txt);

                                sprintf (txt, "%.4lf",gtk_loopview_get_bpb(GTK_LOOPVIEW(looper->loopview)));
                                xmlNewChild (looperptr, NULL, (xmlChar*)"bpb",(xmlChar*)txt);

				sprintf (txt, "%ld",(long)gtk_loopview_get_gridoffset(GTK_LOOPVIEW(looper->loopview)));
                                xmlNewChild (looperptr, NULL, (xmlChar*)"gridoffset",(xmlChar*)txt);

				sprintf (txt, "%d", looper->data->playmode);
				xmlNewChild (looperptr, NULL, (xmlChar*)"playmode",(xmlChar*)txt);
				
				sprintf (txt, "%d", looper->data->recmode);
                                xmlNewChild (looperptr, NULL, (xmlChar*)"recmode",(xmlChar*)txt);

				sprintf (txt, "%d", looper->data->ngrains);
				xmlNewChild (looperptr, NULL, (xmlChar*)"ngrains",(xmlChar*)txt);
				sprintf (txt, "%d", looper->data->graindensity);
				xmlNewChild (looperptr, NULL, (xmlChar*)"graindensity",(xmlChar*)txt);
				sprintf (txt, "%f", looper->data->stereodiversity);
				xmlNewChild (looperptr, NULL, (xmlChar*)"stereodiversity",(xmlChar*)txt);
				sprintf (txt, "%f", looper->data->mingrainspeed);
				xmlNewChild (looperptr, NULL, (xmlChar*)"mingrainspeed",(xmlChar*)txt);
				sprintf (txt, "%f", looper->data->maxgrainspeed);
				xmlNewChild (looperptr, NULL, (xmlChar*)"maxgrainspeed",(xmlChar*)txt);
				sprintf (txt, "%ld", looper->data->mingrainlength);
                                xmlNewChild (looperptr, NULL, (xmlChar*)"mingrainlength",(xmlChar*)txt);
                                sprintf (txt, "%ld", looper->data->maxgrainlength);
                                xmlNewChild (looperptr, NULL, (xmlChar*)"maxgrainlength",(xmlChar*)txt);
				sprintf (txt, "%d", looperdata_get_grainpitchmode(looper->data));
				xmlNewChild (looperptr, NULL, (xmlChar*)"grainpitchmode",(xmlChar*)txt);

				sprintf (txt, "%d", looperdata_get_thresholdmode(looper->data));
				xmlNewChild (looperptr, NULL, (xmlChar*)"thresholdmode",(xmlChar*)txt);
				sprintf (txt, "%d", looperdata_get_thresholdbuffersize(looper->data));
				xmlNewChild (looperptr, NULL, (xmlChar*)"thresholdbuffersize",(xmlChar*)txt);
				sprintf (txt, "%lf",looperdata_get_low_threshold(looper->data));
				xmlNewChild (looperptr, NULL, (xmlChar*)"low_threshold",(xmlChar*)txt);
				sprintf (txt, "%lf",looperdata_get_high_threshold(looper->data));
                                xmlNewChild (looperptr, NULL, (xmlChar*)"high_threshold",(xmlChar*)txt);


				sprintf (txt, "%s", buffer_get_shortname(
					looperdata_get_clickmode_buf(looper->data)));

				xmlNewChild (looperptr, NULL, (xmlChar*)"clickmode",(xmlChar*)txt);
				/* grainpitchbend??? */
				sprintf (txt, "%d", looperdata_get_midichannel(looper->data));
				xmlNewChild (looperptr, NULL, (xmlChar*)"midichannel",(xmlChar*)txt);

				sprintf (txt, "%ld", 
					gtk_loopview_get_zoomstart((GtkLoopview*)looper->loopview));
				xmlNewChild (looperptr, NULL, (xmlChar*)"zoomstart",(xmlChar*)txt);
				sprintf (txt, "%ld", 
					gtk_loopview_get_zoomend((GtkLoopview*)looper->loopview));
                                xmlNewChild (looperptr, NULL, (xmlChar*)"zoomend",(xmlChar*)txt);

			
				sprintf (txt, "%d", looper->data->cm_size);
				xmlNewChild (looperptr, NULL, (xmlChar*)"cm_size",(xmlChar*)txt);	
				cmd = looperdata_cm2str(looper->data,cmd);	
				xmlNewChild (looperptr, NULL, (xmlChar*)"custommode_data",(xmlChar*)cmd);
			}
		}
		listptr = g_list_next(listptr);
	}

	buf = speciallist_get_first(bufferlist);
	while(buf){
/*		printf ("saving buffer %d:%s\n",buf->id,buf->shortname);*/
		bufferptr = xmlNewChild (topptr, NULL, (xmlChar*)"buffer",NULL);
		sprintf (txt, "%d", buf->id);
		xmlNewChild (bufferptr, NULL, (xmlChar*)"id",(xmlChar*)txt);
		xmlNewChild (bufferptr, NULL, (xmlChar*)"shortname",(xmlChar*)buf->shortname);
		xmlNewChild (bufferptr, NULL, (xmlChar*)"filename",(xmlChar*)buf->filename);
		sprintf (txt, "%d", buf->status);
		xmlNewChild (bufferptr, NULL, (xmlChar*)"status",(xmlChar*)txt);	
		sprintf (txt, "%d", buffer_get_type(buf));
		xmlNewChild (bufferptr, NULL, (xmlChar*)"type",(xmlChar*)txt);
                sprintf (txt, "%d", buffer_get_channels(buf));
		xmlNewChild (bufferptr, NULL, (xmlChar*)"channels",(xmlChar*)txt);
		sprintf (txt, "%ld", buffer_get_size(buf));
		xmlNewChild (bufferptr, NULL, (xmlChar*)"size",(xmlChar*)txt);
		sprintf (txt, "%lf", buffer_get_volume_factor(buf));
                xmlNewChild (bufferptr, NULL, (xmlChar*)"volumefactor",(xmlChar*)txt);
		buf = speciallist_get_next(bufferlist,buf);
	}

	if ((err = xmlSaveFormatFile (filename, doc, TRUE)) == -1 ){
		xmlFreeDoc (doc);
		return -1;
	}

	setlocale(LC_NUMERIC,old_locale);
		
	return 0;
}

configfile_handler_t* open_config_reader (char *filename, long samplerate){
	configfile_handler_t *handler = (configfile_handler_t*)malloc (sizeof(configfile_handler_t));
	xmlNodePtr node;

	LIBXML_TEST_VERSION

	handler->doc = xmlReadFile(filename, NULL, 0);
	handler->kluppe = NULL;

	if (!xmlDocGetRootElement(handler->doc)) return NULL;

	for (node = handler->doc->children; node; node = node->next)
      		if (strcmp ((char*)node->name, (char*)"kluppe") == 0)
        		handler->kluppe =  node;

	handler->looperptr = NULL;
	handler->bufferptr = NULL;
	handler->samplerate = samplerate;

	if (handler->kluppe)
		return handler;
	else{
		close_config_reader (handler);
		return NULL;
	}
}

void close_config_reader (configfile_handler_t* handler){
	xmlFreeDoc(handler->doc);
	xmlCleanupParser();
}

static int subnode2int (xmlNodePtr parent, const char *key){
	xmlNodePtr node;
	xmlChar *content;
	int i;
	char * old_locale = setlocale(LC_NUMERIC,"C");

	for (node = parent->children; node; node = node->next){
		if (!strcmp((char*)node->name, (char*)key)){
			content = xmlNodeGetContent (node);
			i = atoi ((char*)content);
			setlocale(LC_NUMERIC, old_locale);
			return i;
		}
	}
	
	setlocale(LC_NUMERIC, old_locale);
	return 0;
}

static long subnode2long (xmlNodePtr parent, const char *key){
        xmlNodePtr node;
        xmlChar *content;
	long l;
	char * old_locale = setlocale(LC_NUMERIC,"C");

        for (node = parent->children; node; node = node->next){
                if (!strcmp((char*)node->name, (char*)key)){
                        content = xmlNodeGetContent (node);
			l = atol ((char*)content);
			setlocale(LC_NUMERIC, old_locale);
                        return l;
                }
        }

	setlocale(LC_NUMERIC, old_locale);
	return 0;
}

static float subnode2float (xmlNodePtr parent, const char *key){
        xmlNodePtr node;
        xmlChar *content;
	float f;
	char * old_locale = setlocale(LC_NUMERIC,"C");

        for (node = parent->children; node; node = node->next){
                if (!strcmp((char*)node->name, (char*)key)){
                        content = xmlNodeGetContent (node);
			f = (float)atof ((char*)content);
			setlocale(LC_NUMERIC, old_locale);
                        return f;
                }
        }

	setlocale(LC_NUMERIC, old_locale);
	return 0.0;
}

static double subnode2double (xmlNodePtr parent, const char *key){
        xmlNodePtr node;
        xmlChar *content;
	double d;
	char * old_locale = setlocale(LC_NUMERIC,"C");

        for (node = parent->children; node; node = node->next){
                if (!strcmp((char*)node->name,(char*) key)){
                        content = xmlNodeGetContent (node);
			d = atof ((char*)content);
			setlocale(LC_NUMERIC, old_locale);
                        return d;
                }
        }

	setlocale(LC_NUMERIC, old_locale);
	return 0.0;
}

static char* subnode2string (xmlNodePtr parent, const char *key){
        xmlNodePtr node;
        xmlChar *content;

        for (node = parent->children; node; node = node->next){
                if (!strcmp((char*)node->name, (char*)key)){
                        content = xmlNodeGetContent (node);
                        return (char*)content;
                }
        }
        return NULL;
}

void config_get_geometry(configfile_handler_t* handler,gint* x, gint* y, gint* width,gint* height){
	*x = subnode2int (handler->kluppe,"window-xpos");
	*y = subnode2int (handler->kluppe,"window-ypos");
        *width = subnode2int (handler->kluppe,"window-width");
        *height = subnode2int (handler->kluppe,"window-height");
        return;
}                       

int config_next_looper (configfile_handler_t* handler){
        xmlNodePtr node;
        int found_old = 0;

        if (!handler->looperptr) found_old = 1;

        for (node = handler->kluppe->children; node; node = node->next){
                if (!strcmp((char*)node->name, (char*)"looper")){
                        if (found_old){
                                /*search and return id */
                                handler->looperptr = node;
                                return subnode2int (node,"id");
                        }else if (node == handler->looperptr)
                                found_old = 1;
                }
        }
        return 0;
}

int config_get_looper_minimized (configfile_handler_t* handler, int id){
	xmlNodePtr node;
        xmlNodePtr lptr = NULL; 
                                
        for (node = handler->kluppe->children; node; node = node->next){
                if (!strcmp((char*)node->name, (char*)"looper"))
                        if (subnode2int(node, "id") == id) lptr = node;
        }                       
                        
        if (lptr) return subnode2int(lptr,"minimized");
	return 0;
}

int config_read_looper (configfile_handler_t* handler, looper_gui_t *looper){
	xmlNodePtr node;
	xmlNodePtr lptr = NULL;
	buffer_info_t *buf;

	for (node = handler->kluppe->children; node; node = node->next){
		if (!strcmp((char*)node->name, (char*)"looper"))
			if (subnode2int(node, "id") == looper->id)
				lptr = node;
	}	

	if (looper &&  lptr){
		/*LATER: do correct samplerate conversion */
		if (looper->data && subnode2int(lptr,"buffer")){
                        gtk_toggle_button_set_active((GtkToggleButton*)looper->minimizebutton,
                                (subnode2int(lptr,"minimized") ? TRUE : FALSE));

			looper_set_buffer_by_id(looper,subnode2int(lptr,"buffer"));

			if (subnode2string(lptr,"clickmode"))
				looper_set_position(looper,subnode2int(lptr,"position"));

			looperdata_set_vol(looper->data,
				subnode2float(lptr,"vol"));	
			looperdata_set_pan(looper->data,
                                subnode2float(lptr,"pan"));
			looperdata_set_panswing(looper->data,
                                subnode2float(lptr,"panswing"));
			looperdata_set_recmix(looper->data,
                                subnode2float(lptr,"recmix"));
			looperdata_set_speed(looper->data,
                                subnode2double(lptr,"speed"));

			looperdata_set_loopstart(looper->data,
                                subnode2long(lptr,"loopstart"));
			looperdata_set_loopend(looper->data,
                                subnode2long(lptr,"loopend"));
			looperdata_set_recstart(looper->data,
                                subnode2long(lptr,"recstart"));
			looperdata_set_recend(looper->data,
                                subnode2long(lptr,"recend"));

			looperdata_set_playpos(looper->data,
                                subnode2double(lptr,"playpos"));
                        looperdata_set_recpos(looper->data,
                                subnode2long(lptr,"recpos"));

			looperdata_set_ngrains(looper->data,
                                subnode2int(lptr,"ngrains"));
			looperdata_set_graindensity(looper->data,
                                subnode2int(lptr,"graindensity"));
			looperdata_set_stereodiversity(looper->data,
                                subnode2double(lptr,"stereodiversity"));

			looperdata_set_mingrainspeed(looper->data,
                                subnode2double(lptr,"mingrainspeed"));
			looperdata_set_maxgrainspeed(looper->data,
                                subnode2double(lptr,"maxgrainspeed"));
			looperdata_set_mingrainlength(looper->data,
                                subnode2long(lptr,"mingrainlength"));
                        looperdata_set_maxgrainlength(looper->data,
                                subnode2long(lptr,"maxgrainlength"));
			looperdata_set_grainpitchmode(looper->data,
				subnode2int(lptr,"grainpitchmode"));
			looperdata_set_midichannel(looper->data,
                                subnode2int(lptr,"midichannel"));

			looperdata_set_thresholdbuffersize(looper->data,
                                subnode2int(lptr,"thresholdbuffersize"));
			looperdata_set_thresholdmode(looper->data,
                                subnode2int(lptr,"thresholdmode"));
			looperdata_set_low_threshold(looper->data,
                                subnode2double(lptr,"low_threshold"));
			looperdata_set_high_threshold(looper->data,
                                subnode2double(lptr,"high_threshold"));

			if (subnode2int(lptr,"cm_size")){
				looperdata_str2cm(looper->data,
					subnode2string (lptr,"custommode_data"),
					subnode2int (lptr,"cm_size"));
			}

			looperdata_set_playmode(looper->data,
				subnode2int(lptr,"playmode"));

			looperdata_set_recmode(looper->data,
                                subnode2int(lptr,"recmode"));

/*			gtk_toggle_button_set_active((GtkToggleButton*)looper->limiterbutton,
				(subnode2int(lptr,"limiter") ? TRUE : FALSE));
*/
			gtk_check_menu_item_set_active((GtkCheckMenuItem*)looper->limiteritem,
				(subnode2int(lptr,"limiter") ? TRUE : FALSE));
			
			gtk_check_menu_item_set_active((GtkCheckMenuItem*)looper->snap2griditem,
				(subnode2int(lptr,"snap2grid") ? TRUE : FALSE));

			gtk_check_menu_item_set_active((GtkCheckMenuItem*)looper->showgriditem,
                                (subnode2int(lptr,"showgrid") ? TRUE : FALSE));

                        gtk_check_menu_item_set_active((GtkCheckMenuItem*)looper->thresholdtoggle,
                                (subnode2int(lptr,"thresholdmode") ? TRUE : FALSE));

			gtk_toggle_button_set_active((GtkToggleButton*)looper->shuttlebutton,
                                (subnode2int(lptr,"shuttle") ? TRUE : FALSE));

			gtk_toggle_button_set_active((GtkToggleButton*)looper->recbutton,
                                (subnode2int(lptr,"isrecording") ? TRUE : FALSE));

                        gtk_toggle_button_set_active((GtkToggleButton*)looper->playbutton,
                                (subnode2int(lptr,"isplaying") ? TRUE : FALSE));

			gtk_loopview_set_bpm(GTK_LOOPVIEW(looper->loopview),
				subnode2double(lptr,"bpm"));
			gtk_loopview_set_bpb(GTK_LOOPVIEW(looper->loopview),
                                subnode2double(lptr,"bpb"));
			gtk_loopview_set_gridoffset(GTK_LOOPVIEW(looper->loopview),
				subnode2long(lptr,"gridoffset"));

			if (subnode2string(lptr,"clickmode")){ 
				/* old configfiles have no clickmode*/
				buf = speciallist_get_first(looper->clickmodes);
/*				printf ("clickmode buf #1: %p, %p\n",buf, looper->clickmodes);*/
				while (buf){
					if (!strcmp(buffer_get_shortname(buf),
						subnode2string(lptr,"clickmode"))){
						looperdata_set_clickmode_buf(looper->data, buf);
					}
					buf = speciallist_get_next(looper->clickmodes,buf);
				}
			}


			switch (subnode2int(lptr,"playmode")){
				case LOOP_PLAYMODE_LOOP:
					gtk_check_menu_item_set_active(
						(GtkCheckMenuItem*)looper->loopmode, TRUE);
					break;
				case LOOP_PLAYMODE_BACKFORTH:
                                        gtk_check_menu_item_set_active(
						(GtkCheckMenuItem*)looper->backforthmode, TRUE);
                                        break;
                                case LOOP_PLAYMODE_SINE:
                                        gtk_check_menu_item_set_active(
						(GtkCheckMenuItem*)looper->sinewavemode, TRUE);
                                        break;
                                case LOOP_PLAYMODE_CUSTOMSPEED:
                                        gtk_check_menu_item_set_active(
						(GtkCheckMenuItem*)looper->customspeedmode, TRUE);
                                        break;
                                case LOOP_PLAYMODE_POSITION:
                                        gtk_check_menu_item_set_active(
						(GtkCheckMenuItem*)looper->customposmode, TRUE);
                                        break;
				case LOOP_PLAYMODE_ONCE:
                                        gtk_check_menu_item_set_active(
                                                (GtkCheckMenuItem*)looper->oncemode, TRUE);
                                        break;
			}

			switch (subnode2int(lptr,"recmode")){
                                case LOOP_RECMODE_LOOP:
                                        gtk_check_menu_item_set_active(
                                                (GtkCheckMenuItem*)looper->recloopmode, TRUE);
                                        break;
				case LOOP_RECMODE_ONCE:
                                        gtk_check_menu_item_set_active(
                                                (GtkCheckMenuItem*)looper->reconcemode, TRUE);
                                        break;
			}
			
			if (subnode2int(lptr,"zoomend"))
				gtk_loopview_set_zoom((GtkLoopview*)looper->loopview,
					subnode2long(lptr,"zoomstart"),
					subnode2long(lptr,"zoomend"));

			looper_update_widgets(looper);
                	return looper->id;
		}
	}
	return 0;
}

int config_next_buffer (configfile_handler_t* handler){
	xmlNodePtr node;
	int found_old = 0;

	if (!handler->bufferptr) found_old = 1;

	for (node = handler->kluppe->children; node; node = node->next){
		if (!strcmp((char*)node->name, (char*)"buffer")){
			if (found_old){
				/*search and return id */
				handler->bufferptr = node;
				return subnode2int (node,"id");
			}else if (node == handler->bufferptr)
				found_old = 1;
		}
	}
	return 0;
}

int config_read_buffer (configfile_handler_t* handler, buffer_info_t* buf){
	int type = 0;
	int file_ok = 0;
	char *filename;
	struct stat fstat;
	float	vol = 0.;

	if (buf && handler->bufferptr){
		type = subnode2int (handler->bufferptr,"type");
		filename = subnode2string (handler->bufferptr,"filename");

		if (type == BUFFER_TYPE_DISCSTREAM){
			buffer_open_discstream(buf,filename,handler->samplerate);
		}else{
			/* old configfiles don't have a type for buffers 
							-> check for filenames */
			if (filename && !stat(filename,&fstat)) file_ok = 1;
		 	if ((type == BUFFER_TYPE_FILEBUFFER) || ((type == 0) && (file_ok == 1))){
				buffer_loadfile(buf,filename,handler->samplerate);
			}else{
				buffer_resize(buf,
					subnode2long(handler->bufferptr,"size"));
				buffer_set_shortname(buf,
                               		subnode2string(handler->bufferptr,"shortname"));
				buffer_set_channels(buf,
                                        subnode2int(handler->bufferptr,"channels"));
				buf->pending = BUFFER_STATUS_READY;
			}
		}
		vol = subnode2double(handler->bufferptr,"volumefactor");
		if(vol) buffer_set_volume_factor(buf,vol);
	}
	return 0;
}
