// Datatypes sound player - replacement for englock
// WAS: play8svx.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos/dos.h>
#include <clib/datatypes_protos.h>
#include <clib/dos_protos.h>
#include <clib/exec_protos.h>
#include <clib/alib_protos.h>
#include <clib/intuition_protos.h>
#include <datatypes/datatypesclass.h>
#include <datatypes/soundclass.h>
#include <intuition/classes.h>
#include <pragmas/xpkmaster_pragmas.h>
#include <libraries/xpk.h>
#include <libraries/xpksub.h>

extern struct Library *AslBase;
extern struct IntuitionBase *IntuitionBase;
extern struct GfxBase *GfxBase;
extern struct Library *UtilityBase;
extern struct Library *GadToolsBase;
extern struct Library *DiskfontBase;
extern struct Library *IFFParseBase;
extern struct Library *DataTypesBase;
extern struct Library *TranslatorBase;
extern struct Library *DOSBase; 
extern struct IntuiText ok_text;

struct Library *XpkBase;

void msg(char *msg); // Traditionally defined in here!
char *checkxpk(char *name);


struct IntuiText msg_text={
      1,0,JAM1,16,9,NULL,NULL,NULL };

int playsam(char *esvxname);
char *analysis(char *fname);

int playsam(char *esvxname) {
	// Returns:
		// 1 = OK
		
	struct dtTrigger Play;
	struct DataType *dt;
	struct DataTypeHeader *head;
	Object *sound = NULL;
	BPTR lock;
	struct MsgPort *finish;
	long bit;

	// WOn't continue with a non-null filename

	if(!(esvxname)) 
		return(0);

	// Check whether file is compressed or not

	esvxname=(UBYTE *)checkxpk(esvxname);

	// OPen the lib first

	if(!(DataTypesBase=OpenLibrary("datatypes.library",0))) {
		msg("Sound: Unable to open datatypes library");
		return(2);
	}

	if(!(lock=Lock(esvxname,ACCESS_READ))) {
		msg("Sound: Could not find file!");
		CloseLibrary(DataTypesBase);
		return(3);
	}

	if(!(dt=ObtainDataTypeA(DTST_FILE, (APTR)lock, NULL))) {
		msg("Sound: Could not access file!");
		UnLock(lock);
		CloseLibrary(DataTypesBase);
		return(4);
	}

	if(!(finish=CreateMsgPort())) {
		msg("Sound: Unable to set up reply port!");
		UnLock(lock);
		CloseLibrary(DataTypesBase);
		ReleaseDataType(dt); 
		return(5);
	}

	bit=1<<finish->mp_SigBit;

	head=dt->dtn_Header;
	
	
	if(head->dth_GroupID!=GID_SOUND) {
		msg("Sound: File is not a sound type supported by system");
		UnLock(lock);
		CloseLibrary(DataTypesBase);
		ReleaseDataType(dt);
		DeleteMsgPort(finish);
		return(6);
	}

	ReleaseDataType(dt);
	UnLock(lock);

   
	if( sound = NewDTObject(esvxname,
			DTA_GroupID, GID_SOUND, 
			SDTA_Volume, 64, 
			SDTA_Cycles, 1, 
			SDTA_SignalTask, FindTask(NULL), 
			SDTA_SignalBit, bit, 
			TAG_DONE)) {

		Play.MethodID = DTM_TRIGGER;
		Play.dtt_GInfo = NULL;
		Play.dtt_Function = STM_PLAY;
		Play.dtt_Data = NULL;
        
		DoDTMethodA(sound, NULL, NULL, (Msg)&Play);
        
		Wait(bit);
		
		DeleteMsgPort(finish);
		DisposeDTObject(sound);
		CloseLibrary(DataTypesBase);
	}

}

char *analysis(char *fname) {
	char text[500];
	struct DataType *dt;
	struct DataTypeHeader *head;
	BPTR lock;
	char type[100];
	char newname[200];

	strcpy(newname,(UBYTE *)checkxpk(fname));

	// OPen the lib first

	if(!(DataTypesBase=OpenLibrary("datatypes.library",0))) {
		msg("Sound: Unable to open datatypes library");
		return(NULL);
	}

	if(!(lock=Lock(&newname[0],ACCESS_READ))) {
		msg("Sound: Could not find file!");
		CloseLibrary(DataTypesBase);
		return(NULL);
	}

	if(!(dt=ObtainDataTypeA(DTST_FILE, (APTR)lock, NULL))) {
		msg("Sound: Could not access file!");
		UnLock(lock);
		CloseLibrary(DataTypesBase);
		return(NULL);
	}

	head=dt->dtn_Header;

	
	// Quick anaylsis

	// File can be:
		// GID_PICTURE
		// GID_SOUND
		// GID_SYSTEM - dir, exe, font, device, lib, etc.
		// GID_TEXT 
		// GID_DOCUMENT
		// GID_MUSIC
		// GID_INSTRUMENT
		// GID_ANIMATION
		// GID_MOVIE
	
	

	if(head->dth_GroupID==GID_PICTURE) strcpy(type,"Picture"); else
	if(head->dth_GroupID==GID_SOUND) {
		sprintf(text,"Accepted! %s %s",head->dth_Name,"Sound");
		msg(text);
		ReleaseDataType(dt);
		UnLock(lock);

		return(fname);
	}
	else

	if(head->dth_GroupID==GID_SYSTEM) strcpy(type,"System File"); else
	if(head->dth_GroupID==GID_TEXT) strcpy(type,"Text File"); else
	if(head->dth_GroupID==GID_DOCUMENT) strcpy(type,"Document"); else
	if(head->dth_GroupID==GID_MUSIC) strcpy(type,"Music file"); else
	if(head->dth_GroupID==GID_INSTRUMENT) strcpy(type,"Instrument"); else
	if(head->dth_GroupID==GID_ANIMATION) strcpy(type,"Animation"); else
	if(head->dth_GroupID==GID_MOVIE) strcpy(type,"Movie");

	sprintf(text,"Sorry file is in wrong format! (%s %s)",head->dth_Name, type);
	msg(text);

	ReleaseDataType(dt);
	UnLock(lock);
	CloseLibrary(DataTypesBase);

	return(NULL);
}

void msg(char *msg) {
	msg_text.IText=msg;
	ok_text.IText="Continue";
	AutoRequest(NULL, &msg_text, NULL, &ok_text, (ULONG)NULL, (ULONG)NULL, 320, 100 );
}
char *checkxpk(char *name) {
	struct XpkFib xfib;
	BPTR file;
	struct TagItem tags1[]={
		XPK_InName,NULL,
		TAG_DONE
	};
	struct TagItem tags2[]={
		XPK_InName,NULL,
		XPK_OutName,NULL,
		TAG_DONE
	};
	
	tags1[0].ti_Data=(ULONG)name;
				
	if(!(XpkBase=OpenLibrary("xpkmaster.library",0))) {
		/* Cannot open xpk! */
		return(name);
	}

	/* Is it packed ? */
	XpkExamine(&xfib,tags1);

	if(xfib.Type!=XPKTYPE_PACKED) {
		/* Not packed */
		CloseLibrary(XpkBase);
		return(name);
	} else {
		/* Packed so unpack it first */
		/* set up tags */
		tags2[0].ti_Data=(ULONG)name;
		tags2[1].ti_Data=(ULONG)"ram:engclock.temp";	

		XpkUnpack(tags2);
		/* Check if we wrote anything... */
		file=Open("ram:engclock.temp",MODE_OLDFILE);
		if(file) {
			if(FGetC(file)==EOF) {
				msg("Error unpacking file! 1");
				CloseLibrary(XpkBase);
				Close(file);
				return(0L);
			}
		} else {
			msg("Error unpacking file! 2");
			CloseLibrary(XpkBase);
			return(0L);
		}
		CloseLibrary(XpkBase);
		Close(file);
		return("ram:engclock.temp");

	}
}