/*  VirtualCue XMMS
 *  Copyright (C) 2005 Barraud Manuel
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public Licensse 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 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.
 */

#include "VirtualCue.h"
#include "titlestring.h"
#include <gtk/gtk.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dlfcn.h>
#include <dirent.h>
#include <string.h>
#include <pthread.h>

static pthread_t tid;
static pthread_mutex_t mutex_sync = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t mutex_stopnext = PTHREAD_MUTEX_INITIALIZER;

static GtkWidget *about_win,*infofile;

static int g_freq,g_rate,g_nch,length_song;
char FichierEnCours[1024];//nom du fichier physique en cours
char NameTrackPlayed[1024];// nom de la chanson visible sur la playlist
char FullNameTrackedPlay[1024];//chemin complet vers le nom du fichier
InputPlugin *PluginEnCours=NULL;
long seek_value=0;

//variable interne qui indique si la track dois etre joué en continue
char playcontinuous=0;
//variable qui detecte si le play file est simplement la fin d'un chanson et donc le debut d'un autre
char detectnextrack=0;


//fonction de callback de l'egaliseur
static void (*Old_add_vis_pcm) (int time, AFormat fmt, int nch, int length, void *ptr)=NULL;


int InternalTime=0;
char PlayCueInProgress=0;



InputPlugin *GiveGoodPluginForThisFile(char *directoryname,char *realfilename);








char *GeneralPluginNextFileInPlaylist(void)
{
void *handle_file;
int *value;
char *(*function)(void);
 
if ((handle_file = dlopen (XMMSGENERALLIB, RTLD_LAZY)))
	{



		if ((value=dlsym (handle_file, "_GeneralCueValue_")))
		{
		


			function=dlsym (handle_file,"GiveNextFile");
			
			if(function)
			{
				return function();
			}
			else
			printf("Can't find the GiveNextFile function in GeneralPlugin\n");
			

		}
	}
else
printf("GiveGoodPlugin: Can't open the library %s\n",XMMSGENERALLIB);


return NULL;
}


void GeneralPluginSetNextPosPlaylist(void)
{
void *handle_file;
int *value;
char *(*function)(void);
 
if ((handle_file = dlopen (XMMSGENERALLIB, RTLD_LAZY)))
	{



		if ((value=dlsym (handle_file, "_GeneralCueValue_")))
		{
			


			function=dlsym (handle_file,"SetNextPosPlaylist");
			
			if(function)
			{
				function();
			}
			else
			printf("Can't find the SetNextPosPlaylist function in GeneralPlugin\n");
			

		}
	}
else
printf("GiveGoodPlugin: Can't open the library %s\n",XMMSGENERALLIB);



}


void *TransformCue(void *args)
{
void *handle_file;
int *value;
void (*function)(char *);
 
if ((handle_file = dlopen (XMMSGENERALLIB, RTLD_LAZY)))
	{



		if ((value=dlsym (handle_file, "_GeneralCueValue_")))
		{
			


			function=dlsym (handle_file,"AddCueToPlayList");
			
			function((char *)args);

		}
		else
			printf("La librairie Generale n'es pas activé!\n");
	}
else
printf("TransformCue Can't open the library %s\n",XMMSGENERALLIB);


return NULL;
}


void TransformeCue(char *filename)
{	
	pthread_attr_t attr;
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
	pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
	pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
	pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);

	pthread_create(&tid, &attr, TransformCue, filename);
	

}

/*
void *CallNextTrack(void *args)
{
	void *handle_file;
int *value;
void (*function)(void);
 
if ((handle_file = dlopen (XMMSGENERALLIB, RTLD_LAZY)))
	{



		if ((value=dlsym (handle_file, "_GeneralCueValue_")))
		{
			


			function=dlsym (handle_file,"NextTrack");
			function();

		}
	}
else
printf("Can't open the library\n");


return NULL;
	
}
void NextTrackPlaylist(void )
{
	pthread_attr_t attr;
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
	pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
	pthread_attr_setschedpolicy(&attr, SCHED_OTHER);
	pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);

	pthread_create(&tid, &attr, CallNextTrack, NULL);
	
}
*/

static void Virtual_add_vis_pcm (int time, AFormat fmt, int nch, int length, void *ptr)
{
	int value;

	value=time-InternalTime;
	pthread_mutex_lock(&mutex_sync);
	if(Old_add_vis_pcm)
	{
	if(value<0)
	value=0;
	
	Old_add_vis_pcm(value,fmt,nch,length,ptr);
	
	}
	pthread_mutex_unlock(&mutex_sync);
}

InputPlugin VirtualCue_ip =
{
	NULL,
	NULL,
	"Virtual Cue Player 0.2.0", /* Description */
	VirtualCue_init,
	VirtualCue_about,
	NULL,
	is_our_file,
	NULL,
	play_file,
	stop,
	virtualcue_pause,
	seek,
	NULL,
	get_time,
	NULL,
	NULL,
	NULL,
	NULL,
	NULL,
	NULL,
	NULL,
	get_song_info,
	VirtualCue_file_info_box,			/* file_info_box */
	NULL
};


//cette fonction doit etre toujours incluse dans un fichier de plugin

InputPlugin *get_iplugin_info(void)
{
	//VirtualCue_ip = g_strdup_printf("Virtual Cue Player %s", VERSION);
	return &VirtualCue_ip;
}


static void VirtualCue_init(void)
{

}

static int is_our_file(char *filename)
{
	gchar *ext;
	gchar extbuff[6];

	memset(extbuff,0,6);

	ext = strrchr(filename, '.');
	if (ext)
	{
		if (!strcasecmp(ext, ".cue"))
		return TRUE;
		
		
	//si les 5 premier caractere commence par .cue# alors c une track!
		
		if(strlen(ext)>=5)
		{
		
		memcpy(extbuff,ext,5*sizeof(gchar));
		
		if (!strcasecmp(extbuff, ".cue#"))
		{
		
	
		return TRUE;
		}
	
		}
	}	

	return FALSE;
}


/* the about window */
static void VirtualCue_about(void)
{
	GtkWidget *button, *label, *bigbox, *buttonbox;

	if(about_win)
		return;
	about_win = gtk_window_new(GTK_WINDOW_DIALOG);
	gtk_window_set_title(GTK_WINDOW(about_win), ("About"));
	gtk_window_set_policy(GTK_WINDOW(about_win), FALSE, FALSE, FALSE);
	gtk_window_set_position(GTK_WINDOW(about_win), GTK_WIN_POS_MOUSE);

	bigbox = gtk_vbox_new(FALSE, 5);
	gtk_container_add(GTK_CONTAINER(about_win), bigbox);

	label = gtk_label_new(g_strconcat((gchar *)"--------------------------\n","Virtual Cue Player", (gchar *)"\n--------------------------\n\nXMMS Cue Player Plugin\n\nIt's a beta version for the moment\n\n (c) Coded By MasterGB AKA R.T.R\n\nSuggestion or Bug report : mastergb@hotmail.com", NULL));
	gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
	gtk_container_add(GTK_CONTAINER(bigbox), label);

	buttonbox = gtk_hbutton_box_new();
	gtk_button_box_set_layout(GTK_BUTTON_BOX(buttonbox), GTK_BUTTONBOX_DEFAULT_STYLE);
	gtk_button_box_set_spacing(GTK_BUTTON_BOX(buttonbox), 5);
	gtk_box_pack_start(GTK_BOX(bigbox), buttonbox, FALSE, FALSE, 0);
	gtk_signal_connect(GTK_OBJECT(about_win), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &about_win);
	button = gtk_button_new_with_label("Close");
	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
	gtk_signal_connect_object(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), (gpointer) about_win);
	gtk_box_pack_start(GTK_BOX ((buttonbox)), button, FALSE, TRUE, 5);
	gtk_widget_show_all(about_win);
}


void clicked_col(GtkCList *clist,
                                            gint row,
                                            gint column,
                                            GdkEventButton *event,
                                            gpointer user_data)
{
	
	if(row!=(int)user_data)
	gtk_clist_select_row(GTK_CLIST(clist),(int)user_data,0);
	
}
static void VirtualCue_file_info_box (char *filename)		/* Bring up an info window for the filename passed in */
{
	GtkWidget *button, *bigbox,*boxnamefile, *buttonbox,*label_file,*entry_filename,*liste_cue;
	
	char *tab[3]={"Nom de la track","Durée","Numero"};
	gchar *ext,extbuff[6],*temp,*diese,*path,*temp2,*titlebigtrack;
	int ntrack;
	InfoCue *ICue;
	int i;
	char *InsertValue[3];
	char numtrack[5];
	char duretrack[25];
	gchar *titletrack;
	InputPlugin* goodplugin;;
	gchar fullpathrealname[1024];
	long length;
	int realtime,min,sec,rowadd;
	if(infofile)
		return;
	
	infofile = gtk_window_new(GTK_WINDOW_DIALOG);
	gtk_window_set_title(GTK_WINDOW(infofile), ("Information sur la track "));
	gtk_window_set_policy(GTK_WINDOW(infofile), FALSE, FALSE, FALSE);
	gtk_window_set_position(GTK_WINDOW(infofile), GTK_WIN_POS_MOUSE);
	
	bigbox = gtk_vbox_new(FALSE, 5);
	gtk_container_add(GTK_CONTAINER(infofile), bigbox);
	
	boxnamefile=gtk_hbox_new(TRUE,0);
	gtk_container_add(GTK_CONTAINER(bigbox), boxnamefile);
	
	
	label_file = gtk_label_new((gchar *)"Nom du fichier: ");
	//gtk_label_set_justify(GTK_LABEL(label_file), GTK_JUSTIFY_CENTER);
	gtk_container_add(GTK_CONTAINER(boxnamefile), label_file);
	
	
	entry_filename=gtk_entry_new();
	
	gtk_entry_set_editable(GTK_ENTRY(entry_filename),FALSE);
	gtk_container_add(GTK_CONTAINER(boxnamefile),entry_filename);
	
	
	
	liste_cue=gtk_clist_new_with_titles(3,tab);
	
	ext = strrchr(filename, '.');
	if(ext)
	{
	
		
		memset(extbuff,0,6);
			
			
			
			if(strlen(ext)>=5)
			{
				
				memcpy(extbuff,ext,5*sizeof(gchar));
				
				if (!strcasecmp(extbuff, ".cue#"))
				{
				//on peut recupere ls infos sur la tracks
					temp = g_strdup(filename);
					diese=strrchr(temp,'#');
					//on recupere le numero de la tracks
					sscanf(diese,"#%d",&ntrack);
					*diese='\0';
					//on a dans temp le nom du fichier cue
					ICue=GetInfoCue(temp);
					
					if(!ICue)
					{
						g_free(temp);
					return;//erreur dans le cue
					}
					//le cue est au même endroit que le fichiers
						path = g_strdup(temp);
						temp2 = strrchr(path, '/');
						if (temp2)
						*temp2 = '\0';
						sprintf(fullpathrealname,"%s/%s",path,ICue->File);
						
						gtk_entry_set_text(GTK_ENTRY(entry_filename),(gchar *)temp);
						
						goodplugin=GiveGoodPluginForThisFile(XMMSPLUGININDIR,fullpathrealname);
					
						if(goodplugin)
						{
							
						goodplugin->get_song_info(fullpathrealname,&titlebigtrack,&realtime);
						g_free(titlebigtrack);
						
							
						
						for(i=1;i<=ICue->nbtrack;i++)
						{
							
							titletrack=(gchar *)g_malloc0(sizeof(gchar)*(strlen(ICue->tracks[i-1].Performer)+strlen(ICue->tracks[i-1].Title)+4));
							sprintf(titletrack,"%s - %s",ICue->tracks[i-1].Performer,ICue->tracks[i-1].Title);
							
							InsertValue[0]=titletrack;
							
							
							//on recupere la durée de la chanson
							length=GetTimeByNum(ICue,i-1,realtime);
							min=length/60000;
							sec=(length-min*60000)/1000;
							
							sprintf(duretrack,"%dmin%02d",min,sec);
							InsertValue[1]=duretrack;
							sprintf(numtrack,"#%d",i);
							InsertValue[2]=numtrack;
							rowadd=gtk_clist_append(GTK_CLIST(liste_cue),InsertValue);
							gtk_clist_set_selectable(GTK_CLIST(liste_cue),rowadd,FALSE);
							g_free(titletrack);
							
						}
					
					}
					g_free(temp);
					g_free(path);
				}
			}
	}
	
	gtk_clist_set_column_width(GTK_CLIST(liste_cue),0,gtk_clist_optimal_column_width(GTK_CLIST(liste_cue),0));
	gtk_clist_set_column_width(GTK_CLIST(liste_cue),1,gtk_clist_optimal_column_width(GTK_CLIST(liste_cue),1));
	gtk_clist_set_column_width(GTK_CLIST(liste_cue),2,gtk_clist_optimal_column_width(GTK_CLIST(liste_cue),2));
	gtk_clist_set_selectable(GTK_CLIST(liste_cue),ntrack-1,TRUE);
	gtk_clist_select_row(GTK_CLIST(liste_cue),ntrack-1,0);
	gtk_signal_connect(GTK_OBJECT(liste_cue), "select-row", GTK_SIGNAL_FUNC(clicked_col),(gpointer)(ntrack-1));
	
	gtk_container_add(GTK_CONTAINER(bigbox), liste_cue);
	
	
	buttonbox = gtk_hbutton_box_new();
	
	gtk_button_box_set_layout(GTK_BUTTON_BOX(buttonbox), GTK_BUTTONBOX_DEFAULT_STYLE);
	gtk_button_box_set_spacing(GTK_BUTTON_BOX(buttonbox), 5);
	gtk_box_pack_start(GTK_BOX(bigbox), buttonbox, FALSE, FALSE, 0);
	
	gtk_signal_connect(GTK_OBJECT(infofile), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &infofile);
	button = gtk_button_new_with_label("Close");
	GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
	gtk_signal_connect_object(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), (gpointer) infofile);
	gtk_box_pack_start(GTK_BOX ((buttonbox)), button, FALSE, TRUE, 5);
	gtk_widget_show_all(infofile);
	
	
	
}


//int nostop=0;


char IsNextFile(char *fileplayed,char *nextfile)
{
//on verifie d'abord si le fichier en cours est un cue
gchar extbuff[6];
gchar *extplayed,*extnextrack,*diese,*namecueplayed,*namecuenextfile;
int nbtrackplayed,nbnextrack;





			extplayed = strrchr(fileplayed, '.');
			
			
			memset(extbuff,0,6);
			
			
			
			if(extplayed!=NULL&&strlen(extplayed)>=5)
			{
				
				memcpy(extbuff,extplayed,5*sizeof(gchar));
				
				if (!strcasecmp(extbuff, ".cue#"))
				{
				//c'est un cue!

				namecueplayed = g_strdup(fileplayed);
				diese=strrchr(namecueplayed,'#');
					//on recupere le numero de la tracks
					sscanf(diese,"#%d",&nbtrackplayed);
					*diese='\0';
					//on a dans temp le nom du fichier cue

				printf("First track is a cue\n");

				extnextrack= strrchr(nextfile, '.');
				memset(extbuff,0,6);
					if(extnextrack!=NULL&&strlen(extnextrack)>=5)
					{
					memcpy(extbuff,extnextrack,5*sizeof(gchar));
						if (!strcasecmp(extbuff, ".cue#"))
						{
						namecuenextfile = g_strdup(nextfile);
						diese=strrchr(namecuenextfile,'#');
						sscanf(diese,"#%d",&nbnextrack);
						*diese='\0';
						
						if(!strcmp(namecuenextfile,namecueplayed)&&(nbtrackplayed+1)==nbnextrack)
						{
						g_free(namecuenextfile);
						g_free(namecueplayed);
						
						return 1;
						}


						g_free(namecuenextfile);
						}

					
					}

				
				g_free(namecueplayed);
				}
	

			}




return 0;
}

static void stop(void)
{
	printf("want stop..\n");
	
	
	
	pthread_mutex_lock(&mutex_stopnext);
	/*
	if(nostop)
	{
		pthread_mutex_unlock(&mutex_stopnext);
		return;
	}
	*/
	if(PluginEnCours)
	{
	pthread_mutex_lock(&mutex_sync);
	if(detectnextrack)
	{
		//la chanson peut etre joué en continue pour cela on va detecté si ca la suite 
		
		if(IsNextFile(FullNameTrackedPlay,GeneralPluginNextFileInPlaylist()))
		playcontinuous=1;

	detectnextrack=0;
	}
	
	if(!playcontinuous)
	{
	PluginEnCours->add_vis_pcm=Old_add_vis_pcm;
	PluginEnCours->set_info=VirtualCue_ip.set_info;
	Old_add_vis_pcm=NULL;
	}	
	pthread_mutex_unlock(&mutex_sync);
	if(!playcontinuous)
	{
	PluginEnCours->stop();
	PluginEnCours=NULL;
	}
	//InternalTime=0;
	//
	


	PlayCueInProgress=0;
			
	}
pthread_mutex_unlock(&mutex_stopnext);
	
}
static int get_time(void)
{
	int value=0;
	
if(PluginEnCours)
{
	
	
	
	

	value=PluginEnCours->get_time()-InternalTime;

	if(value<0)
	{
		value=0;
	}


	//cette valeur est la valeur du curseur en milliseconde

	if(seek_value&&PluginEnCours->get_time()==0)
	{
	PluginEnCours->seek(seek_value);
	
	}
	
	
		if(value>=(length_song)/*&&!nostop*/)
	{
		/*
		//si la prochaine track suis celle ci et que c pas en shuffle...
		namefile=GeneralPluginNextFileInPlaylist();
		if(namefile)
		printf("prochaine track:%s\n",namefile);
		//on arrete pas le lecteur on laisse suivre on change la position du curseur dans la playlist
		//on change le compteur interne evidemment
		GeneralPluginSetNextPosPlaylist();
		//on change le compteur interne
		temp = g_strdup(namefile);
		diese=strrchr(temp,'#');
		//on recupere le numero de la tracks
		sscanf(diese,"#%d",&ntrack);
		*diese='\0';
		//on a dans temp le nom du fichier cue
		ICue=GetInfoCue(temp);
		
		InternalTime=ICue->tracks[ntrack-1].time_millieme;
		
		
		value=PluginEnCours->get_time()-InternalTime;
	
		if(value<0)
		{
			value=0;
		}
		
		
		nostop=1;
		*/
		detectnextrack=1;

		
	return -1;
	}
	
	
	//printf("Appel de gettime  %d %d\n",PluginEnCours->get_time(),value);
}

return value;

}

static void virtualcue_pause(short p)
{
	if(PluginEnCours)
	{
	PluginEnCours->pause(p);
	}
}

static void seek(int time)
{
	if(PluginEnCours)
	{
	PluginEnCours->seek(time+InternalTime/1000);
	}
}



InputPlugin *LoadPlugin(char *fullpathname)
{
void *handle_file;
InputPlugin *(*function)(void);
	
	if ((handle_file = dlopen (fullpathname, RTLD_LAZY)))
	{



		
			function=dlsym (handle_file,"get_iplugin_info");
		
			return function();

		
	}
else
printf("LoadPlugin: Can't open the library %s\n",fullpathname);
return NULL;
}

InputPlugin *GiveGoodPluginForThisFile(char *directoryname,char *realfilename)
{
	DIR *directory;
	struct dirent *file;
	struct stat infofile;
	gchar fullpath[1024];
	gchar *ext;
	InputPlugin *temp;
	
		if ((directory = opendir (directoryname)))
	{

		while ((file = readdir (directory)))
		{
		
			//verification des types de fichiers
			sprintf (fullpath, "%s/%s", directoryname, file->d_name);
			lstat (fullpath, &infofile);

			if (S_ISREG (infofile.st_mode))//si c'est un fichier regulier
			{
				//on cherche les .so
				ext=strrchr(fullpath, '.');//on recherche l'extension
				
				if(!strcmp(ext,".so"))
				{
					
				temp=LoadPlugin(fullpath);
					if(temp&&temp->is_our_file(realfilename))
					return temp;
				}

			}

		}
//on ferme le repertoire
		closedir (directory);
	}
	else
	{
		
		
		
		
		printf ("Can't parse directory %s\n",directoryname);
	
		
	}	
	return NULL;
}










static void get_song_info(char *filename, char **title, int *length)
{
	
	//on verifie le format cue#number

	gchar *ext,*temp,*temp2,*diese,*titletrack,*path;
	int ntrack;
	gchar extbuff[6];
	gchar fullpathrealname[1024];
	gchar *realtitle;
	int realtime;
	InfoCue *ICue;
	InputPlugin *goodplugin;
	memset(extbuff,0,6);
	
	
	ext = strrchr(filename, '.');//on recherche l'extension
	if(strlen(ext)>=5)
	{
		
		memcpy(extbuff,ext,5*sizeof(gchar));
		
		if (!strcasecmp(extbuff, ".cue#"))
		{
		//on peut recupere ls infos sur la tracks
		
			temp = g_strdup(filename);
			diese=strrchr(temp,'#');
			//on recupere le numero de la tracks
			sscanf(diese,"#%d",&ntrack);
			*diese='\0';
			//on a dans temp le nom du fichier cue
			
			ICue=GetInfoCue(temp);
			if(!ICue)
			{
				g_free(temp);
			return;
			}
			//le cue est au même endroit que le fichiers
				path = g_strdup(temp);
				temp2 = strrchr(path, '/');
				if (temp2)
				*temp2 = '\0';
			
				sprintf(fullpathrealname,"%s/%s",path,ICue->File);
				
				
				
				goodplugin=GiveGoodPluginForThisFile(XMMSPLUGININDIR,fullpathrealname);
			
				

				if(goodplugin)
				{
					
				
				goodplugin->get_song_info(fullpathrealname,&realtitle,&realtime);
				
				g_free(realtitle);//on se sers pas du titre
				
				
			if(ntrack>0&&ntrack<=ICue->nbtrack)
			{
			titletrack=(gchar *)g_malloc0(sizeof(gchar)*(strlen(ICue->tracks[ntrack-1].Performer)+strlen(ICue->tracks[ntrack-1].Title)+4));
			sprintf(titletrack,"%s - %s",ICue->tracks[ntrack-1].Performer,ICue->tracks[ntrack-1].Title);
			*title=titletrack;
			
			
			*length=GetTimeByNum(ICue,ntrack-1,realtime);
			
			}


				}
			g_free(temp);
			free(ICue);
		
		}
		
	}
	
	

}


void set_info (char *title, int length, int rate, int freq, int nch)
{

	//si l'ancienne song joué etatit un cue et que la nouvelle non
	//xmms lance quand même une derniere fois (BUG xmms???) cette fonction dois donc regarder cette possibilité
	// if(PlayCueInProgress)
	//{
	// le plugin au dessus voudra change les informations on lui remplace avec cette fonction qui ne fait rien pour eviter qui les changes
	VirtualCue_ip.set_info(NameTrackPlayed,length_song,rate,freq,nch);	
	g_freq=freq;
	g_rate=rate;
	g_nch=nch;
	//}
	//else
	//VirtualCue_ip.set_info(title,length,rate,freq,nch);
	
	//do nothing
}

void set_info_text (char *text)
{
	//do nothing
}




static void play_file(char *filename)
{
	gchar *ext,*temp,*temp2,*diese,*path;
	int ntrack;
	gchar extbuff[6];
	InfoCue *ICue;
	char IsSimpleCue=0;
	InputPlugin *goodplugin;
	gchar *title;
	int length;
	
	printf("Play..\n");
	
	pthread_mutex_lock(&mutex_stopnext);
	/*
		if(nostop)
	{
		nostop=0;
		pthread_mutex_unlock(&mutex_stopnext);
		return;
	}
	*/
	strcpy(FullNameTrackedPlay,filename);

	ext = strrchr(filename, '.');
	if (ext)
	{
		if (!strcasecmp(ext, ".cue"))
		{
		
		TransformeCue(filename);
		IsSimpleCue=1;
		}
	}
	
	
	if(!IsSimpleCue)
	{
			//on verifie le format cue#number
			
			memset(extbuff,0,6);
			
			
			
			if(strlen(ext)>=5)
			{
				
				memcpy(extbuff,ext,5*sizeof(gchar));
				
				if (!strcasecmp(extbuff, ".cue#"))
				{
				//on peut recupere ls infos sur la tracks
					temp = g_strdup(filename);
					diese=strrchr(temp,'#');
					//on recupere le numero de la tracks
					sscanf(diese,"#%d",&ntrack);
					*diese='\0';
					//on a dans temp le nom du fichier cue
					ICue=GetInfoCue(temp);
					
					if(!ICue)
					{
						//on libere le mutex
						pthread_mutex_unlock(&mutex_stopnext);	
						g_free(temp);
					return;
					}
					//le cue est au même endroit que le fichiers
						path = g_strdup(temp);
						temp2 = strrchr(path, '/');
						if (temp2)
						*temp2 = '\0';
						sprintf(FichierEnCours,"%s/%s",path,ICue->File);
						
						//printf("le fichier c'est %s\n",fullpathrealname);				
						if(!playcontinuous)
						goodplugin=GiveGoodPluginForThisFile(XMMSPLUGININDIR,FichierEnCours);
						else
						goodplugin=PluginEnCours;

					
						if(goodplugin)
						{
							
							
							
							//goodplugin->handle=VirtualCue_ip.handle;
							if(!playcontinuous)
							{
							goodplugin->filename=NULL;
							goodplugin->output=VirtualCue_ip.output;
							
							goodplugin->set_info=set_info;
							goodplugin->set_info_text=set_info_text;
							
							PluginEnCours=goodplugin;
							PlayCueInProgress=1;
							}

							InternalTime=ICue->tracks[ntrack-1].time_millieme;
							
							
							get_song_info(filename, &title,&length);
							length_song=length;

							VirtualCue_ip.set_info(title,length,g_rate,g_freq,g_nch);
							strcpy(NameTrackPlayed,title);
						
							pthread_mutex_lock(&mutex_sync);
							if(goodplugin->add_vis_pcm&&!playcontinuous)
							{
								
								Old_add_vis_pcm=goodplugin->add_vis_pcm;
								goodplugin->add_vis_pcm=Virtual_add_vis_pcm;
								
							}
							pthread_mutex_unlock(&mutex_sync);
							
							if(!playcontinuous)
							goodplugin->play_file(FichierEnCours);
							
							
							seek_value=ICue->tracks[ntrack-1].time_millieme/1000;
							
							
							
							playcontinuous=0;
							g_free(title);
							
							
						}
						

					g_free(temp);
					free(ICue);
				}
				
			}
			

	

		
	}

pthread_mutex_unlock(&mutex_stopnext);
	
}
