/*

TCLLIST.C

Description:
TCL/TK interface to handle the playlist.

Peter Amstutz <amstpi@freenet.tlh.fl.us>


HISTORY 
======

v1.00 (20/01/97) - first version
v1.01 (29/03/97) - PL_DelCurrent() and PL_GetRandom() actually do something
					now...
v1.02 (22/04/97) - PL_GetCurrent() works now too, also collected
					redundant code in GetCurrent(), GetNext(), and GetPrev()

*/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#include <unistd.h>
#include "mikmod.h"

extern int readme, writeme;

void GetLine(char *bar)
{
	struct timeval tv;
	char string[80];
	fd_set rfds;
	int i;
	char c;

	FD_ZERO(&rfds);
	FD_SET(readme, &rfds);
	tv.tv_sec=0;
	tv.tv_usec=500;

	memset(string,0,sizeof(string));
	/* only read to a newline.  Should prevent command 'stacking'
		from screwing things up, since the low-level read()
		function doesn't stop at a \n 
		also make _absolutly sure_ there is a character waiting
		for us to be read.  otherwise the mod play pauses
		a sits there polling the command pipe... which is not
		good.  everything halts until something trickles in...
	*/
	for(i=0, c=0; 
		select(readme+1, &rfds, NULL, NULL, &tv)!=0
		&& c!='\n'
		&& i<sizeof(string);
		i++) 
	{
		FD_ZERO(&rfds);
		FD_SET(readme, &rfds);
		tv.tv_sec=0;
		tv.tv_usec=50;
		if(select(readme+1, &rfds, NULL, NULL, &tv)) 
		{
			read(readme,&c,1);
			string[i]=c;
		}
	}
	strcpy(bar,string);
}

void SplitPath(char *string, char *retfile, char *retarc)
{
	char *a, *p;
	a=strrchr(string,'(');
	if(a!=NULL && a[1]=='i' && a[2]=='n' && a[3]==')')
	{
/* cool tricky stuff with pointers here... */
		p=strrchr(string,'/');
		if(p!=NULL) {*p=0; p++;}
		else p=string;
		strcpy(retarc,string);
		strcat(retarc,"/");
		a+=5;
		strcat(retarc,a);
		a-=6;
		*a=0;
		strcpy(retfile,p);
	}
	else 
	{
		strcpy(retfile,string);
		strcpy(retarc,"");
	}
}

void PL_InitList(PLAYLIST *pl)
{}

void PL_ClearList(PLAYLIST *pl)
{
	write(writeme,".top1.fra2.fra18.lis18 delete 0 end\n",36);
}

int PL_GetCurrent(PLAYLIST *pl, char *retfile, char *retarc)
{
	char *string, *str2, *a, *p, c;
	int i;

	string=(char *)malloc(255);
	memset(string,0,255);
	write(writeme,"getcurrent\n",11);
	GetLine(string);
	string[strlen(string)-1]=0;
	if(string[0]=='=') 
	{
		str2=(char *)malloc(255);
		sprintf(str2,"puts \"%s\"\n",string);
		write(writeme,str2,strlen(str2));
	}
	if(string[0]!='*') return 1;
	string++;
	SplitPath(string,retfile,retarc);
	if(retfile[0]==0) return 1;

	return 0;
}

int PL_GetNext(PLAYLIST *pl, char *retfile, char *retarc)
{
	char *string, *str2, *a, *p, c;
	int i;

	string=(char *)malloc(255);
	memset(string,0,255);
	write(writeme,"getnext\n",8);
	GetLine(string);
	string[strlen(string)-1]=0;
	if(string[0]=='=') 
	{
		str2=(char *)malloc(255);
		sprintf(str2,"puts \"%s\"\n",string);
		write(writeme,str2,strlen(str2));
	}
	if(string[0]!='*') return 1;
	string++;
	SplitPath(string,retfile,retarc);
	if(retfile[0]==0) return 1;

	return 0;
}

int PL_GetPrev(PLAYLIST *pl, char *retfile, char *retarc)
{
	char *string, *a, *p, c;
	int i;

	string=(char *)malloc(255);

	memset(string,0,255);
	write(writeme,"getprev\n",8);
	GetLine(string);
	if(string[0]!='*') return 1;
	string++;
	if(retfile==NULL) return 0;
	string[strlen(string)-1]=0;
	SplitPath(string,retfile,retarc);
	if(retfile[0]==0) return 1;

	return 0;
}

int PL_GetRandom(PLAYLIST *pl, char *retfile, char *retarc)
{
	write(writeme, "set current [expr [rand [.top1.fra2.fra15.lis18 size]] - 1]\n",60);
	return PL_GetNext(pl, retfile, retarc);
}

int PL_DelCurrent(PLAYLIST *pl)
{
	write(writeme,"delcurrent\n",11);
	return 1;
}

	/* may or may not work right */
void PL_Add(PLAYLIST *pl, char *file, char *arc)
{
	char string[255];
	char str2[255];
	char *a;

	strcpy(str2,file);
	a=strrchr(str2,'/');
	if(a!=NULL) {
		*a=0;
		sprintf(string,"set mainpaths [linsert $mainpaths end %s/]\n",str2);
		write(writeme,string,strlen(string));
		a++;
	}

	if(arc==NULL) sprintf(string,".top1.fra2.fra15.lis18 insert end %s\n",a!=NULL ? a : file);
	else sprintf(string,".top1.fra2.fra15.lis18 insert end \"%s (in) %s\"\n",a!=NULL ? a : file,arc); 
	write(writeme,string,strlen(string));
}

	/* untested! */
void PL_Load(PLAYLIST *pl, char *filename)
{
	FILE *f;
	char file[255];
	char *arc;

	if((f=fopen(filename,"r"))==NULL) {
		perror("Error loading playlist\n");
		return;
	}

	while(!feof(f))
	{
		fgets(file,255,f);
		if(file[strlen(file)-1]=='\n') file[strlen(file)-1]=0;
		arc=strchr(file,'|');
		if(arc==NULL)
		{
			PL_Add(pl, file, NULL);
		}
		else 
		{
			*arc=0;
			arc++;
			PL_Add(pl, file, arc);
		}
	}
	fclose(f);
}

	/* untested! */
void PL_Save(PLAYLIST *pl, char *savefile)
{
	FILE *f;
	int i;

	if((f=fopen(savefile,"r"))==NULL) {
		perror("Error saving playlist\n");
		return;
	}

	for(i=0;i<pl->numused;i++)
	{
		fprintf(f,"%s",pl->file[i]);
		if(pl->file_in_arc!=NULL) fprintf(f,"|%s",pl->file_in_arc[i]);
		fprintf(f,"\n");
	}
	fclose(f);
}
