
/*
 *  SoundDT41 prefsed -- A free release of the sounddt41 prefsed source code
 *  Copyright (C) 1998/99  Stephan Rupprecht
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */
 
#include <dos/dosextens.h>
#include <dos/var.h>
#include <dos/dostags.h>
#include <dos/rdargs.h>
#include <devices/ahi.h>
#include <libraries/gtlayout.h>
#include <gadgets/colorwheel.h>
#include <gadgets/gradientslider.h>

#include <inline/gtlayout.h>
#include <inline/intuition.h>
#include <inline/graphics.h>
#include <inline/dos.h>
#include <inline/exec.h>
#include <inline/ahi.h>

#define REG(reg,arg)	arg __asm(#reg)

#define TEMPLATE	"VOLUME/N/K,BUFFERSIZE/N/K,AHI/S,AHIMODEID/K,FAM=FORCEAHIMODE/S,AMF=AHIMIXFREQ/N/K,AIFF16/S,C=COMPRESS/S," \
				"W=WIDTH/N/K,H=HEIGHT/N/K,BG=BACKGROUNDCOLOR/K,WF=WAVEFORMCOLOR/K,CP=CONTROLPANEL/T,NOGTSLIDER/S"

enum {
	ID_NONE,
	ID_SAVE,
	ID_USE,
	ID_CANCEL,
	ID_PAGEDGROUP,
	ID_AHIREQ,
	ID_BGCOLORSLIDER,
	ID_WFCOLORSLIDER,
	ID_FRAME,
	ID_AHI,
	ID_FORCEMODE,
	ID_BUFFERSIZE,
	ID_CONTROLPANEL,
	ID_NOGTSLIDER
};

/****************************************************************************/

struct Library		*DOSBase,
				*SysBase,
				*GTLayoutBase,
				*AHIBase,
				*IntuitionBase,
				*GfxBase;
			
struct MsgPort	*AHImp;
struct AHIRequest	*ahir;

struct LayoutHandle	*layouthandle;
struct Window		*Wnd;
struct Screen			*screen;
ULONG				BgPen, WfPen;

struct {
	BOOL	AHI;
	BOOL	ForceAHIMode;
	ULONG	AHIModeID;
	ULONG	AHIMixFreq;
	UWORD	Width;
	UWORD	Height;
	ULONG	BgColor;
	ULONG	WfColor;
	BOOL	AIFF16;
	BOOL	Compress;
	ULONG	BufferSize;
	ULONG	Volume;
	BOOL	NoGTSlider;
	BOOL	ControlPanel;
} prefs;

TEXT AHIReqLabel[ 128 ];
			
/****************************************************************************/

BOOL openlibs( void );
void closelibs( void );
BOOL opengui( void );
void closegui( void );
void loadprefs( STRPTR path );
void saveprefs( STRPTR path );
void handleevents( void );
LONG Hex2Long( STRPTR s );
void sprintf( REG(a3,STRPTR PutChData), REG(a0, STRPTR FormatStr), STRPTR data, ... );
BOOL AHIModeRequest( void );
void Restore( void ), Quit( void ), About( void ), Defaults( void ), LastSaved( void ), init_prefs( void );
void start( void );
ULONG GetAHIDefaultFreq( void );
void errorreport( STRPTR header, LONG error );

/****************************************************************************/

void dummy( void )
{
	start();
}

/****************************************************************************/

UBYTE	VerStr[] = "$VER: SoundDT41 prefs 41.0 (27.01.99) © 1999 by Stephan Rupprecht";

void start( void )
{
	struct Process	*pr;
	struct Message	*wbmsg = NULL;

	SysBase = (*(struct Library **)4L);
	
	pr = (struct Process *) FindTask( NULL );
	
	if( ! pr->pr_CLI )
	{
		WaitPort( &pr->pr_MsgPort );
		wbmsg = GetMsg( &pr->pr_MsgPort );
	}
	
	if( openlibs() )
	{
		loadprefs( "env:datatypes/sounddt41.prefs" );
		
		if( opengui() )
		{
			handleevents();
		}

		closegui();
	}
	
	closelibs();
	
	if( wbmsg )
	{
		Forbid();
		ReplyMsg( wbmsg );
	}
}
	
/****************************************************************************/

BOOL openlibs( void )
{
	if(	( DOSBase = OpenLibrary( "dos.library", 39L ) ) &&
		( GTLayoutBase = OpenLibrary( "gtlayout.library", 0L ) ) &&
		( GfxBase = OpenLibrary( "graphics.library", 39L ) ) &&
		( IntuitionBase = OpenLibrary( "intuition.library", 39L ) ) )
	{
		AHImp = CreateMsgPort();
		if( ahir = (struct AHIRequest *) CreateIORequest( AHImp, sizeof( *ahir ) ) )
		{
			if( ! OpenDevice( "ahi.device", AHI_NO_UNIT, (struct IORequest *)ahir, 0L ) )
			{
				AHIBase = (struct Library *) ahir->ahir_Std.io_Device;
			}
		}
		
		return TRUE;
	}
	
	return FALSE;
}

/****************************************************************************/

void closelibs( void )
{
	if( AHIBase )
	{
		CloseDevice( (struct IORequest *) ahir );
	}
	
	DeleteIORequest( (struct IORequest *) ahir );
	DeleteMsgPort( AHImp );
	
	CloseLibrary( DOSBase );
	CloseLibrary( GTLayoutBase );
	CloseLibrary( IntuitionBase );
	CloseLibrary( GfxBase );
}

/****************************************************************************/

#undef LT_New

void LT_New( struct LayoutHandle *lh, ULONG tags, ... )
{
	LT_NewA( lh, (struct TagItem *)&tags );
}

/****************************************************************************/

ULONG IncHookFunc( REG(a2, ULONG val), REG(a1, LONG msg) )
{
	return val - ( msg == INCREMENTERMSG_Decrement ? 1024 : msg == INCREMENTERMSG_Increment ? -1024 : 0L );
}

/****************************************************************************/

void RefreshHookFunc( REG(a1, struct RefreshMsg *msg) )
{
	struct RastPort	*rp = Wnd->RPort;
	WORD			x = msg->Left, y = msg->Top,
					w = msg->Width, h = msg->Height;

	if( BgPen != -1L )
	{
		SetAPen( rp, BgPen );
		RectFill( rp, x,y, x+w-1, y+h-1 );
	}
	
	if( WfPen != -1L )
	{	
		LONG	i;
		
		SetAPen( rp, WfPen );
		Move( rp, x+=4, y+=2 );
		
		for( i = 0; i < (w-8); i++ )
		{
			WORD	val = RangeRand( h-4 );
			Draw( rp, x + i, y + val );
		}
	}
}

/****************************************************************************/

ULONG GetAHIDefaultFreq( void )
{
	BPTR	fh;
	ULONG	freq = AHI_DEFAULT_FREQ;
	
	if( fh = Open( "envarc:sys/ahi.prefs", MODE_OLDFILE ) )
	{
		ULONG	id;
		
		Seek( fh, 12L, OFFSET_BEGINNING );
		
		while( FRead( fh, &id, sizeof( id ), 1L ) == 1L )
		{
			if( id == ID_AHIU )
			{
				struct AHIUnitPrefs	ahiup;
				
				if( FRead( fh, &id, sizeof( id ), 1L ) == 1L )
				{
					if( FRead( fh, &ahiup, sizeof( ahiup ), 1L ) == 1L )
					{
						if( ahiup.ahiup_Unit == AHI_NO_UNIT )
						{
							freq = ahiup.ahiup_Frequency;
							break;
						}
					}
				}
			}
			else
			{
				if( FRead( fh, &id, sizeof( id ), 1L ) == 1L )
				{
					while( id-- ) FGetC( fh );
				}
			}
		}
		
		Close( fh );
	}
	
	return( freq );
}

/****************************************************************************/

BOOL opengui( void )
{	
	BOOL			okay = FALSE;
	
	if( screen = LockPubScreen( NULL ) )
	{
		static struct TagItem	menutags[] = {
			LAMN_TitleText, (ULONG) "Project",
				LAMN_ItemText, (ULONG) "?\0About",
				LAMN_UserData, (ULONG) About,
				LAMN_ItemText, (ULONG) NM_BARLABEL,
				LAMN_ItemText, (ULONG) "Q\0Quit",
				LAMN_UserData, (ULONG) Quit,
			LAMN_TitleText, (ULONG) "Edit",
				LAMN_ItemText, (ULONG) "D\0Reset To Defaults",
				LAMN_UserData, (ULONG) Defaults,
				LAMN_ItemText, (ULONG) "L\0Last Saved",
				LAMN_UserData, (ULONG) LastSaved,
				LAMN_ItemText, (ULONG) "R\0Restore",
				LAMN_UserData, (ULONG) Restore,
			TAG_DONE };
		
		BgPen = ObtainPen( screen->ViewPort.ColorMap, -1, 
			( prefs.BgColor & 0x00ff0000 ) << 8L,
			( prefs.BgColor & 0x0000ff00 ) << 16L,
			( prefs.BgColor & 0x000000ff ) << 24L,
			PEN_EXCLUSIVE );
		
		WfPen = ObtainPen( screen->ViewPort.ColorMap, -1, 
			( prefs.WfColor & 0x00ff0000 ) << 8L,
			( prefs.WfColor & 0x0000ff00 ) << 16L,
			( prefs.WfColor & 0x000000ff ) << 24L,
			PEN_EXCLUSIVE );
		
		if( layouthandle = LT_CreateHandleTags( NULL, LAHN_PubScreen, (ULONG) screen, TAG_DONE ) )
		{
			LT_New( layouthandle,
				LA_Type, VERTICAL_KIND,
				TAG_DONE );
			{
				STATIC STRPTR labels[] = { "General", "Appearance", NULL };
				
				LT_New( layouthandle,
					LA_Type, TAB_KIND,
					LATB_FullSize, TRUE,
					LATB_AutoPageID, ID_PAGEDGROUP,
					LATB_Labels, (ULONG) labels,
					TAG_DONE );
				
				LT_New( layouthandle,
					LA_Type, VERTICAL_KIND,
					LAGR_ActivePage, 0L,
					LA_ID, ID_PAGEDGROUP,
					TAG_DONE );
				{
					LT_New( layouthandle,
						LA_Type, VERTICAL_KIND,
						TAG_DONE );
					{
						LT_New( layouthandle,
							LA_Type, VERTICAL_KIND,
							LA_LabelText, (ULONG) "Misc",
							TAG_DONE );
						{
							STATIC struct Hook	IncHook = { NULL, NULL, (HOOKFUNC) IncHookFunc, NULL, NULL };
							
							LT_New( layouthandle,
								LA_Type, HORIZONTAL_KIND,
								TAG_DONE );
							{	
								LT_New( layouthandle,
									LA_Type, CHECKBOX_KIND,
									LA_LabelText, (ULONG) "Compress",
									LA_BOOL, (ULONG) &prefs.Compress,
									TAG_DONE );
				
								LT_New( layouthandle,
									LA_Type, CHECKBOX_KIND,
									LA_LabelText, (ULONG) "AIFF16",
									LA_BOOL, (ULONG) &prefs.AIFF16,
									TAG_DONE );
							}
							LT_EndGroup( layouthandle );
						
							LT_New( layouthandle,
								LA_Type, INTEGER_KIND,
								LA_LabelText, (ULONG) "Buffersize",
								LA_ULONG, (ULONG) &prefs.BufferSize,
								LAIN_Min, 1024L,
								LAIN_Max, 131072L,
								LAIN_UseIncrementers, TRUE,
								LAIN_IncrementerHook, &IncHook,
								GA_Disabled, (ULONG) prefs.AHI,
								LA_ID, ID_BUFFERSIZE,
								TAG_DONE );
								
							LT_New( layouthandle,
								LA_Type, SLIDER_KIND,
								LA_LabelText, (ULONG) "Volume",
								GTSL_LevelFormat, (ULONG) "%2ld",
								LA_ULONG, (ULONG) &prefs.Volume,
								GTSL_Min, 0,
								GTSL_Max, 64,
								TAG_DONE );
						}
						LT_EndGroup( layouthandle );
					
						if( AHIBase )
						{
							TEXT	driver[ 32 ];
							ULONG	audioid, freq = prefs.AHIMixFreq;
							
							if( freq == AHI_DEFAULT_FREQ )
							{
								freq = GetAHIDefaultFreq();
							}
							
							LT_New( layouthandle,
								LA_Type, HORIZONTAL_KIND,
								LA_LabelText, (ULONG) "AHI settings",
								TAG_DONE );
							{
								LT_New( layouthandle,
									LA_Type, VERTICAL_KIND,
									TAG_DONE );
								{
									LT_New( layouthandle,
										LA_Type, CHECKBOX_KIND,
										LA_LabelText, (ULONG) "AHI",
										LA_BOOL, (ULONG) &prefs.AHI,
										LA_ID, ID_AHI,
										TAG_DONE );
										
									LT_New( layouthandle,
										LA_Type, CHECKBOX_KIND,
										LA_LabelText, (ULONG) "Force mode",
										LA_BOOL, (ULONG) &prefs.ForceAHIMode,
										GA_Disabled, (ULONG) ! prefs.AHI,
										LA_ID, ID_FORCEMODE,
										TAG_DONE );
								}
								LT_EndGroup( layouthandle );
								
								if( AHI_GetAudioAttrs( prefs.AHIModeID, NULL, 
									AHIDB_Name, (ULONG) &driver,
									AHIDB_BufferLen, 32L,
									AHIDB_AudioID, (ULONG) &audioid,
									TAG_DONE ) )
								{
									sprintf( AHIReqLabel, "%s\nID 0x%08lx\n%ld hz", driver, audioid, freq );
								}
								else
								{
									sprintf( AHIReqLabel, "Driver N/A\nID 0x%08lx\n%ld hz", driver, prefs.AHIModeID, freq );
								}	
								
								LT_New( layouthandle,
									LA_Type, BUTTON_KIND,
									LA_ID, ID_AHIREQ,
									LA_LabelText, (ULONG) AHIReqLabel,
									GA_Disabled, (ULONG) ! prefs.AHI,
									TAG_DONE );
							}
							LT_EndGroup( layouthandle );
						}
					}
					LT_EndGroup( layouthandle );
					
					LT_New( layouthandle,
						LA_Type, VERTICAL_KIND,
						TAG_DONE );
					{	
						LT_New( layouthandle,
							LA_Type, VERTICAL_KIND,
							LAGR_SameSize, TRUE,
							TAG_DONE );
						{	
							STATIC struct Hook	RefreshHook = { NULL, NULL, (HOOKFUNC) RefreshHookFunc, NULL, NULL };
							
							LT_New( layouthandle,
								LA_Type, FRAME_KIND,
								LA_ID, ID_FRAME,
								LAFR_RefreshHook, (ULONG) &RefreshHook,
								LAFR_DrawBox, FALSE,
								TAG_DONE );
							
							LT_New( layouthandle, 
								LA_Type, HORIZONTAL_KIND,
					
								TAG_DONE );
							{
								LT_New( layouthandle,
									LA_Type, VERTICAL_KIND,
									LA_LabelText, (ULONG) "Background",
									TAG_DONE );
								{
									LT_New( layouthandle, 
										LA_Type, SLIDER_KIND,
										LA_LabelText, (ULONG) "Red",
										LA_UBYTE, (ULONG) &prefs.BgColor+1,
										LA_Chars, 10L,
										GTSL_LevelFormat, (ULONG) "%3ld",
										GTSL_Min, 0,
										GTSL_Max, 255,
										GA_Immediate, TRUE,
										LA_ID, ID_BGCOLORSLIDER,
										TAG_DONE );
										
									LT_New( layouthandle, 
										LA_Type, SLIDER_KIND,
										LA_LabelText, (ULONG) "Green",
										GTSL_LevelFormat, (ULONG) "%3ld",
										LA_UBYTE, (ULONG) &prefs.BgColor+2,
										GTSL_Min, 0,
										GTSL_Max, 255,
										GA_Immediate, TRUE,
										LA_ID, ID_BGCOLORSLIDER,
										TAG_DONE );
				
									LT_New( layouthandle, 
										LA_Type, SLIDER_KIND,
										LA_LabelText, (ULONG) "Blue",
										GTSL_LevelFormat, (ULONG) "%3ld",
										LA_UBYTE, (ULONG) &prefs.BgColor+3,
										GTSL_Min, 0,
										GTSL_Max, 255,
										GA_Immediate, TRUE,
										LA_ID, ID_BGCOLORSLIDER,
										TAG_DONE );
								}
								LT_EndGroup( layouthandle );
								
								LT_New( layouthandle,
									LA_Type, VERTICAL_KIND,
									LA_LabelText, (ULONG) "Waveform",						
									TAG_DONE );
								{							
									LT_New( layouthandle, 
										LA_Type, SLIDER_KIND,
										LA_LabelText, (ULONG) "Red",
										LA_Chars, 10L,
										GTSL_LevelFormat, (ULONG) "%3ld",
										LA_UBYTE, (ULONG) &prefs.WfColor+1,
										GTSL_Min, 0,
										GTSL_Max, 255,
										LA_ID, ID_WFCOLORSLIDER,
										GA_Immediate, TRUE,
										TAG_DONE );
										
									LT_New( layouthandle, 
										LA_Type, SLIDER_KIND,
										LA_LabelText, (ULONG) "Green",
										LA_UBYTE, (ULONG) &prefs.WfColor+2,
										GTSL_LevelFormat, (ULONG) "%3ld",
										GTSL_Min, 0,
										GTSL_Max, 255,
										LA_ID, ID_WFCOLORSLIDER,
										GA_Immediate, TRUE,
										TAG_DONE );
				
									LT_New( layouthandle, 
										LA_Type, SLIDER_KIND,
										LA_LabelText, (ULONG) "Blue",
										LA_UBYTE, (ULONG) &prefs.WfColor+3,
										GTSL_LevelFormat, (ULONG) "%3ld",
										GTSL_Min, 0,
										GTSL_Max, 255,
										LA_ID, ID_WFCOLORSLIDER,
										GA_Immediate, TRUE,
										TAG_DONE );
								}
								LT_EndGroup( layouthandle );
							}
							LT_EndGroup( layouthandle );
						}
						LT_EndGroup( layouthandle );
							
						LT_New( layouthandle,
							LA_Type, HORIZONTAL_KIND,
							LA_LabelText, (ULONG) "Default Size",
							LAGR_SameSize, TRUE,
							LAGR_Spread, TRUE,
							TAG_DONE );
						{
							LT_New( layouthandle,
								LA_Type, SLIDER_KIND,
								LA_LabelText, (ULONG) "Width",
								LA_UWORD, (ULONG) &prefs.Width,
								LA_Chars, 10L,
								GTSL_LevelFormat, (ULONG) "%4ld",
								GTSL_Min, 16,
								GTSL_Max, 1024,
								TAG_DONE );
						
							LT_New( layouthandle,
								LA_Type, SLIDER_KIND,
								LA_LabelText, (ULONG) "Height",
								LA_UWORD, (ULONG) &prefs.Height,
								GTSL_LevelFormat, (ULONG) "%4ld",
								GTSL_Min, 16,
								GTSL_Max, 1024,
								TAG_DONE );
						}
						LT_EndGroup( layouthandle );
						
						LT_New( layouthandle,
							LA_Type, HORIZONTAL_KIND,
							LA_LabelText, (ULONG) "Tapedeck",
							LAGR_Spread, TRUE,
							TAG_DONE );
						{
							LT_New( layouthandle,
								LA_Type, CHECKBOX_KIND,
								LA_LabelText, (ULONG) "ControlPanel",
								LA_BOOL, (ULONG) &prefs.ControlPanel,
								LA_ID, ID_CONTROLPANEL,
								TAG_DONE );
		
							LT_New( layouthandle,
								LA_Type, CHECKBOX_KIND,
								LA_LabelText, (ULONG) "NoGTSlider",
								LA_BOOL, (ULONG) &prefs.NoGTSlider,
								LA_ID, ID_NOGTSLIDER,
								GA_Disabled, (ULONG) ! prefs.ControlPanel,
								TAG_DONE );
						}
						LT_EndGroup( layouthandle );
					}
					LT_EndGroup( layouthandle );
				}		
				LT_EndGroup( layouthandle );
						
				LT_New( layouthandle,
					LA_Type, XBAR_KIND,
					LAXB_FullSize, TRUE,
					TAG_DONE );
				
				LT_New( layouthandle,
					LA_Type, HORIZONTAL_KIND,
					LAGR_Spread, TRUE,
					LAGR_SameSize, TRUE,
					TAG_DONE );
				{
					LT_New( layouthandle,
						LA_Type, BUTTON_KIND,
						LA_LabelText, (ULONG) "Save",
						LA_ID, ID_SAVE,
						LABT_ReturnKey, TRUE,
						TAG_DONE );
					
					LT_New( layouthandle,
						LA_Type, BUTTON_KIND,
						LA_LabelText, (ULONG) "Use",
						LA_ID, ID_USE,
						TAG_DONE );
						
					LT_New( layouthandle,
						LA_Type, BUTTON_KIND,
						LA_LabelText, (ULONG) "Cancel",
						LA_ID, ID_CANCEL,
						LABT_EscKey, TRUE,
						TAG_DONE );
				}
				LT_EndGroup( layouthandle );
			}
			LT_EndGroup( layouthandle );
				
			if( Wnd = LT_Build( layouthandle,
				LAWN_Title, (ULONG) "SoundDT v41 prefs",
				LAWN_IDCMP, IDCMP_CLOSEWINDOW,
				LAWN_SmartZoom, TRUE,
				LAWN_Show, TRUE,
				LAWN_MenuTags, (ULONG) menutags,
				WA_Flags, WFLG_ACTIVATE | WFLG_CLOSEGADGET | 
						WFLG_DEPTHGADGET | WFLG_DRAGBAR,
				WA_ScreenTitle, (ULONG) &VerStr[6],
				TAG_DONE ) )
			{
				okay = TRUE;
			}
		}
	}

	if( ! okay )
	{
		closegui();
	}

	return okay;
}
		
/****************************************************************************/

void closegui( void )
{
	ReleasePen( screen->ViewPort.ColorMap, BgPen );
	ReleasePen( screen->ViewPort.ColorMap, WfPen );
	LT_DeleteHandle( layouthandle );
	UnlockPubScreen( NULL, screen );
	layouthandle = NULL;
}

/****************************************************************************/

void handleevents( void )
{
	struct IntuiMessage	*Message;
	ULONG				MsgQualifier,
						MsgClass;
	UWORD                		MsgCode;
	struct Gadget       		*MsgGadget;
	BOOL				quit = FALSE;
	
	do 
	{
		WaitPort( Wnd->UserPort );
		
		while( Message = LT_GetIMsg( layouthandle ) )
		{
			MsgClass	= Message->Class;
			MsgCode	= Message->Code;
			MsgQualifier	= Message->Qualifier;
			MsgGadget	= Message->IAddress;
		
			LT_ReplyIMsg( Message );
	
			switch(MsgClass)
			{
				case IDCMP_CLOSEWINDOW:
					quit = TRUE;
				break;
				
				case IDCMP_GADGETUP:
					switch( MsgGadget->GadgetID )
					{
						case ID_AHIREQ:
							if( AHIModeRequest() )
							{
								closegui();
								quit = ! opengui();
							}
						break;
						
						case ID_SAVE:
							saveprefs( "envarc:datatypes/sounddt41.prefs" );
						case ID_USE:
							saveprefs( "env:datatypes/sounddt41.prefs" );
						case ID_CANCEL:
							quit = TRUE;
						break;
						
						case ID_AHI:
							LT_SetAttributes( layouthandle, ID_AHIREQ, GA_Disabled, (ULONG) ! prefs.AHI, TAG_DONE );
							LT_SetAttributes( layouthandle, ID_FORCEMODE, GA_Disabled, (ULONG) ! prefs.AHI, TAG_DONE );
							LT_SetAttributes( layouthandle, ID_BUFFERSIZE, GA_Disabled, (ULONG) prefs.AHI, TAG_DONE );
						break;
						
						case ID_CONTROLPANEL:
							LT_SetAttributes( layouthandle, ID_NOGTSLIDER, GA_Disabled, (ULONG) ! prefs.ControlPanel, TAG_DONE );
						break;
					}
				break;
				
				case IDCMP_MOUSEMOVE:
					if( ! MsgGadget ) break;
					
					switch( MsgGadget->GadgetID )
					{
						case ID_BGCOLORSLIDER:
							if( BgPen != -1L )
							{
								SetRGB32( &screen->ViewPort, BgPen,
									( prefs.BgColor & 0x00ff0000 ) << 8L,
									( prefs.BgColor & 0x0000ff00 ) << 16L,
									( prefs.BgColor & 0x000000ff ) << 24L );
							}
						break;
						
						case ID_WFCOLORSLIDER:
							if( WfPen != -1L )
							{
								SetRGB32( &screen->ViewPort, WfPen,
									( prefs.WfColor & 0x00ff0000 ) << 8L,
									( prefs.WfColor & 0x0000ff00 ) << 16L,
									( prefs.WfColor & 0x000000ff ) << 24L );
							}
						break;
					}
				break;
				
				case IDCMP_MENUPICK:
				{
					struct MenuItem *item = ItemAddress( layouthandle->Menu, MsgCode );
					
					if( item )
					{
						((void (*)())LAMN_Item_UserData(item))();
						/*- return if hide -*/
						if( ! layouthandle ) return;
	                   		}
	                   	}
				break;
			}
		}		
	}
	while( ! quit );
}

/****************************************************************************/

void errorreport( STRPTR header, LONG error )
{
	TEXT			buf[ FAULT_MAX + 128 ];
	struct EasyStruct	es = { sizeof(struct EasyStruct), NULL, "SoundDT v41 prefs", buf, "Okay" };
				
	if( Fault( error, header, buf, sizeof( buf ) ) )
	{
		EasyRequestArgs( NULL, &es, NULL, NULL );
	}
}

/****************************************************************************/

void init_prefs( void )
{
	prefs.AHI		= FALSE;
	prefs.AHIModeID	= AHI_DEFAULT_ID;
	prefs.ForceAHIMode = FALSE;
	prefs.AHIMixFreq	= AHI_DEFAULT_FREQ;
	prefs.Compress	= FALSE;
	prefs.AIFF16		= FALSE;
	prefs.Width		= 160;
	prefs.Height		= 100;
	prefs.BgColor		= 0L;
	prefs.WfColor	= ( 35 << 16 ) | ( 204 << 8 ) | ( 23 );
	prefs.BufferSize	= 65536L;
	prefs.Volume		= 64L;
	prefs.ControlPanel	= FALSE;
	prefs.NoGTSlider	= FALSE;
}

/****************************************************************************/

void loadprefs( STRPTR path )
{
	TEXT			buf[256];
	LONG			len;

	init_prefs();

	if( ( len = GetVar( path, buf, sizeof( buf )-1, GVF_GLOBAL_ONLY ) ) > 0 )
	{
		struct RDArgs	*rdargs;
		
		if( rdargs = AllocDosObject( DOS_RDARGS, NULL ) )
		{
			struct RDArgs	*freeargs;
			struct {
				LONG	*volume;
				LONG	*buffersize;
				LONG	ahi;
				STRPTR	ahimodeid;
				LONG	forceahimode;
				LONG	*mixfreq;
				LONG	aiff;
				LONG	compress;
				LONG	*width, *height;
				STRPTR	bg, wf;
				LONG	cp;
				LONG	nogtsl;			
			} args = { };
		
			/* prepare rdargs */
			buf[len++] = '\n';
			rdargs->RDA_Source.CS_Buffer = buf;
			rdargs->RDA_Source.CS_Length = len;
			rdargs->RDA_Flags = RDAF_NOPROMPT;
		
			if( freeargs = ReadArgs( TEMPLATE, (LONG *)&args, rdargs ) )
			{
				if( args.ahi )
				{
					prefs.AHI = TRUE;
				}
				
				if( args.ahimodeid )
				{
					prefs.AHIModeID = Hex2Long( args.ahimodeid );
				}
				
				if( args.forceahimode )
				{
					prefs.ForceAHIMode = TRUE;
				}
				
				if( args.mixfreq )
				{
					prefs.AHIMixFreq = *args.mixfreq;
				}
				
				if( args.aiff )
				{
					prefs.AIFF16 = TRUE;
				}
				
				if( args.compress )
				{
					prefs.Compress = TRUE;
				}
				
				if( args.width )
				{
					prefs.Width = *args.width;
				}
				
				if( args.height )
				{
					prefs.Height = *args.height;
				}
				
				if( args.wf )
				{
					prefs.WfColor = Hex2Long( args.wf );
				}
				
				if( args.bg )
				{
					prefs.BgColor = Hex2Long( args.bg );
				}
				
				if( args.buffersize )
				{
					LONG	bufsize = *args.buffersize;
					
					if( bufsize > 1023 && bufsize < 131073 )
					{
						prefs.BufferSize = bufsize;
					}
				}
				
				if( args.cp )
				{
					prefs.ControlPanel = TRUE;
				}
				
				if( args.volume )
				{
					prefs.Volume = *args.volume;
				}
				
				if( args.nogtsl )
				{
					prefs.NoGTSlider = TRUE;
				}
				
				FreeArgs( freeargs );
			}
			else
			{
				errorreport( path, IoErr() );
			}

			FreeDosObject( DOS_RDARGS, rdargs );
		}
		else
		{
			errorreport( path, ERROR_NO_FREE_STORE );
		}
	}
}

/****************************************************************************/

void saveprefs( STRPTR path )
{
	BPTR	fh;
	
	if( fh = Open( path, MODE_NEWFILE ) )
	{
		if( prefs.AHI )
		{
			FPuts( fh, "AHI " );
		}
		
		if( prefs.AHIModeID != AHI_DEFAULT_ID )
		{
			FPrintf( fh, "AHIMODEID=0x%08lx ", prefs.AHIModeID );
		}
		
		if( prefs.AHIMixFreq != AHI_DEFAULT_FREQ )
		{
			FPrintf( fh, "AHIMIXFREQ=%ld ", prefs.AHIMixFreq );
		}
		
		if( prefs.ForceAHIMode )
		{
			FPrintf( fh, "FORCEAHIMODE " );
		}
		
		if( prefs.Volume != 64L )
		{
			FPrintf( fh, "VOLUME=%ld ", prefs.Volume );
		}
		
		if( prefs.BufferSize != 65536 )
		{
			FPrintf( fh, "BUFFERSIZE=%ld ", prefs.BufferSize );
		}
		
		if( prefs.AIFF16 )
		{
			FPrintf( fh, "AIFF16 " );
		}
		
		if( prefs.Compress )
		{
			FPrintf( fh, "COMPRESS " );
		}
		
		if( prefs.ControlPanel )
		{
			FPrintf( fh, "CONTROLPANEL=YES " );
		}
		
		if( prefs.NoGTSlider )
		{
			FPrintf( fh, "NOGTSLIDER " );
		}
		
		if( prefs.Width != 160 )
		{
			FPrintf( fh, "WIDTH=%ld ", prefs.Width );
		}
		
		if( prefs.Height != 100 )
		{
			FPrintf( fh, "HEIGHT=%ld ", prefs.Height );
		}
		
		if( prefs.BgColor != 0 )
		{
			FPrintf( fh, "BG=0x%08lx ", prefs.BgColor );
		}
		
		if( prefs.WfColor != ( ( 35 << 16 ) | ( 204 << 8 ) | ( 23 ) ) )
		{
			FPrintf( fh, "WF=0x%08lx ", prefs.WfColor );
		}
		
		Close( fh );
	}
	else
	{
		errorreport( path, IoErr() );
	}
}

/****************************************************************************/

LONG Hex2Long( STRPTR s )
{
	LONG	a = 0L;
	BYTE	c;
	
	if( s && ( c = *s++ ) && ( c == '$' || (c == '0' && *s++ == 'x' ) ) ) 
	{
		while( c = *s++ )
		{
			if ( c > '9' )
			{
				c &= 0x5f;
			}
			
			if( ( c -= '0' ) < 0 || ( c > 9 && ( c -= 7 ) >15 ) )
			{
				break;
			}
			
			a = a << 4 | c;
		}
	}
	
	return a;
}

/****************************************************************************/

void sprintf( REG(a3,STRPTR PutChData), REG(a0, STRPTR FormatStr), STRPTR data, ... )
{
	struct Library	*SysBase = (*(struct Library **)4L);
	
	RawDoFmt(FormatStr, &data, (void (*)())"\x16\xc0\x4e\x75", PutChData);
}

/****************************************************************************/

BOOL AHIModeRequest( void )
{
	struct AHIAudioModeRequester	*req;
	BOOL						ret = FALSE;
	
	if( req = AHI_AllocAudioRequest( NULL ) )
	{
		ULONG	audioid = prefs.AHIModeID,
				freq = prefs.AHIMixFreq;
		
		if( audioid == AHI_DEFAULT_ID )
		{
			AHI_GetAudioAttrs( audioid, NULL, 
				AHIDB_AudioID, (ULONG) &audioid,
				TAG_DONE );
		}
		
		if( freq == AHI_DEFAULT_FREQ )
		{
			freq = GetAHIDefaultFreq();
		}
		
		if( ret = AHI_AudioRequest( req,
			AHIR_Window, (ULONG)Wnd,
			AHIR_SleepWindow, TRUE,
			AHIR_InitialAudioID, audioid,
			AHIR_InitialMixFreq, freq,
			AHIR_DoMixFreq, TRUE,
			TAG_DONE ) )
		{
			prefs.AHIModeID = req->ahiam_AudioID;
			prefs.AHIMixFreq = req->ahiam_MixFreq;
		}
		
		AHI_FreeAudioRequest( req );
	}
	
	return ret;
}

/****************************************************************************/

void Quit( void )
{
	closegui();
}

/****************************************************************************/

void About( void )
{
	TEXT			buf[ 256 ];
	struct EasyStruct	es = {
		sizeof(struct EasyStruct),
		NULL, 
		"SoundDT v41 prefs", 
		buf,
		"Okay" };
		
	sprintf( buf, "%.31s\n%s\n\nstephan.rupprecht@gmx.de", &VerStr[6], &VerStr[38] );
	
	EasyRequestArgs( NULL, &es, NULL, NULL );
}

/****************************************************************************/

void Defaults( void )
{
	closegui();
	init_prefs();
	opengui();
}

/****************************************************************************/

void LastSaved( void )
{
	closegui();
	loadprefs( "envarc:datatypes/sounddt41.prefs" );
	opengui();
}

/****************************************************************************/

void Restore( void )
{
	closegui();
	loadprefs( "env:datatypes/sounddt41.prefs" );
	opengui();
}

/****************************************************************************/
