{ SoundEx -- Version 3.0 }

{******************************************************************************
*
* Developer Technical Support Apple II Sample Code
*
* doLoad:		This routine allocates a buffer and reads the desired file 
*				into the buffer.   If a buffer has already been allocated, 
*				It will be disposed.  Note that it also sets the global 
*				variables BuffHndl and BuffSize.
*
* Inputs:		pathString contains the pathname of the file.
* Outputs:		NONE
* Calls:		NONE
}

procedure doLoad(pathString : GSString255Ptr);

var
	opRGS :	OpenRecGS;
	eofGS : EOFRecGS;
	ioRGS : IORecGS;
	rnRGS : RefNumRecGS;
	
begin
	opRGS.pCount := 2;
	opRGS.pathname := pathString;
	OpenGS (OpRGS);

	eofGS.pCount := 2;
	eofGS.refNum := opRGS.refnum;
	GetEOFGS (eofGS);
	BuffSize := trunc(eofGS.eof);
	
	if BuffHndl <> NIL then			
	  	begin
			HUnlock(BuffHndl);
			DisposeHandle(BuffHndl);
		end;

	BuffHndl := NewHandle (Buffsize, MyMemoryID, $C00C, NIL);
	HLock(BuffHndl);
	
	iorGS.pCount := 4;
    iorGS.refNum := opRGS.refnum;
    iorGS.dataBuffer := BuffHndl^;
    iorGS.requestCount := BuffSize;
	ReadGS (ioRGS);

	rnRGS.pCount := 1;
	rnRGS.refNum := opRGS.refnum;
	CloseGS (rnRGS);
end;

{******************************************************************************
*
* doLoadFile:	Puts up SFGetFile, calls doLoad with the desired pathName,
*				updates the paramText for the staticText controls.
*
* Inputs:		NONE
* Outputs:		NONE
* Calls:		doLoad
}
procedure doLoadFile;

var
	myReply	: SFReplyRec2;
	promptStr,
	tempStr	: String255;
	x	: integer;

begin
	myReply.nameRefDesc := refIsNewHandle;
	myReply.pathRefDesc := refIsNewHandle;
	promptStr := 'Select a Sound File to Load:';
	SFGetFile2(
		10, 35,
		teRefIsPtr,
		Ref(@promptStr),
		NIL,			{ filter proc }
		NIL,			{ type list   }
		myReply
	);

	if myReply.good then 
		begin
			{update the file name for display }
			moveleft(Handle(myReply.nameRef)^^,tempStr,255);
			tempStr[3] := tempStr[2];
			
			for x := 0 to length(tempStr) - 3 do   {moveleft won't do this}
				tempStr[x] := tempStr[x+3];
				
			paramRec1.Str[1] := tempStr;				{ set the paramText }
			DrawOneCtl(GetCtlHandleFromID(OurWindow,curfileID));

			{set up the pathRef for the doLoad call }
			moveleft(Handle(myReply.pathRef)^^,tempStr,255);
			
			for x := 0 to length(tempStr) - 2 do   {moveleft won't do this}
				tempStr[x] := tempStr[x+2];
				
			doLoad(@tempStr);
			
			{ set up the buffer pointer for display }
			tempStr := '        ';
			Long2Hex (longint(BuffHndl^), Ptr(Longint(@tempStr)+1),8);
			
			paramRec1.Str[2] := tempStr;
			DrawOneCtl(GetCtlHandleFromID(OurWindow,loadedAtID));

			{ set up the buffer size for display }
			tempStr := '    ';
			Long2Hex (BuffSize, Ptr(Longint(@tempStr)+1),4);
			
			paramRec1.Str[3] := tempStr;
			DrawOneCtl(GetCtlHandleFromID(OurWindow,buffSizeID));

			DisposeHandle(Handle(myReply.nameRef));
			DisposeHandle(Handle(myReply.pathRef));
		end
end;

{******************************************************************************
*
* setResult:	Updates the results of the last call.
*
* Inputs:		NONE
* Outputs:		NONE
* Calls:		NONE
}
procedure setResult;

var
	resultStr : String;

begin
	resultStr := '        ';
	Long2Hex (CurCmdResult, @resultStr[1],8);
	
	paramRec1.Str[4] := resultStr;
	DrawOneCtl(GetCtlHandleFromID(OurWindow,resultID));

	resultStr := '    ';
	Int2Hex (CurCmdErr,@resultStr[1],4);
	
	paramRec1.Str[5] := resultStr;
	DrawOneCtl(GetCtlHandleFromID(OurWindow,toolErrID));
end;



{******************************************************************************
*
* setEditStr:	Places a Pascal string into a LineEdit control.
*
* Inputs:		updStr is the string to be set, and ctlItemID is the LineEdit
*				control ID to set.
*
* Outputs:		NONE
* Calls:		NONE
}
procedure setEditStr(updStr : String; ctlItemID : integer);

var
	theCtl 		: CtlRecHndl;
	theLERec 	: LERecHndl;

begin
	theCtl := GetCtlHandleFromID(ourwindow, ctlItemID);
	theLERec := LERecHndl(theCtl^^.ctlData);
	
	LESetSelect(0,256,theLERec);
	LESetText(Ptr(@updStr[1]), length(updStr),
			  theLERec);
	LESetSelect(0, 256, theLERec)  ;

	DrawOneCtl(theCtl);
end;


{******************************************************************************
*
* getEditStr:	Updates a Pascal string from the contents of a LineEdit control.
*
* Inputs:		ctlItemID is the LineEdit control ID to obtain the string from.
* Outputs:		updStr contains the Pascal String.
* Calls:		NONE
}
procedure getEditStr(var updStr : String; ctlItemID : integer);

var
	theCtl 	 : CtlRecHndl;
	textHndl : Handle;
	textLen,x	 : integer;

begin
	theCtl := GetCtlHandleFromID(ourwindow, ctlItemID);
	textHndl := LEGetTextHand(LERecHndl(theCtl^^.ctlData));
	textLen := LEGetTextLen(LERecHndl(theCtl^^.ctlData));
	moveleft(textHndl^^,updStr,textLen);
	for x := textlen+1 downto 0 do
		updStr[x+1] := updStr[x];
	updStr[0] := chr(textLen);
end;

{******************************************************************************
*
* getEditInt:	Updates an integer from the contents of a LineEdit control.
*
* Inputs:		ctlItem is the LineEdit control ID to obtain the value from.
* Outputs:		the result is the integer value of the Hex String in the control.
* Calls:		getEditStr
}
function getEditInt(ctlItem : integer) : integer;

var 
	valStr : String;

begin
	getEditStr(valStr,ctlItem);
	getEditInt := Hex2Int ( @valStr[1], length(valStr));
end;

{******************************************************************************
*
* getEditLong:	Updates a long from the contents of a LineEdit control.
*
* Inputs:		ctlItem is the LineEdit control ID to obtain the value from.
* Outputs:		the result is the long value of the Hex String in the control.
* Calls:		getEditStr
}
function getEditLong(ctlItem : integer) : longint;

var 
	valStr : String;

begin
	getEditStr(valStr,ctlItem);
	getEditLong := Hex2Long ( @valStr[1], length(valStr));
end;


{******************************************************************************
*
* setEditInt:	Updates a LineEdit control to the hex string representation
*				of an integer.
*
* Inputs:		value is the integer to be converted.
*				ctlItem is the LineEdit control ID to receive the hex string.
*				strLength is the desired length of the string.				
* Outputs:		the result is the long value of the Hex String in the control.
* Calls:		setEditStr
}
procedure setEditInt(value, ctlItem, strLength : integer);

var 
	valStr : String;

begin
	Int2Hex (value, @valStr[1], strLength);
	valStr[0] := chr(strLength);
	setEditStr(valStr, ctlItem);
end;

{******************************************************************************
*
* setEditLong:	Updates a LineEdit control to the hex string representation
*				of a long value passed to it. The string is assumed to be
*				8 characters wide.
*
* Inputs:		value is the long to be converted.
*				ctlItem is the LineEdit control ID to receive the hex string.
* Outputs:		the result is the long value of the Hex String in the control.
* Calls:		setEditStr
}
procedure setEditLong(value : longint; ctlItem:integer);

var 
	valStr : String;

begin
	Long2Hex (value, @valStr[1],8);
	valStr[0] := chr(8);
	setEditStr(valStr, ctlItem);
end;


{******************************************************************************
*
* setTargetCtl:	After the proper controls have been "hilited", setTargetCtl
*				will determine which should be active and make it the 
*				current target control.
*
* Inputs:		NONE
* Outputs:		NONE
* Calls:		NONE
}
procedure setTargetCtl;

var theCtlID : integer;

begin
	theCtlID := 0;
	
	if ctlHilite.docblk then
		theCtlID := oscGenTypeID
	else if ctlHilite.sndBlk then
		theCtlID := waveStartID
	else if ctlHilite.parm[1] then
		theCtlID := parm1ID;

	if theCtlID <> 0 then
		MakeThisCtlTarget (GetCtlHandleFromID(ourwindow,theCtlID));
end;


{******************************************************************************
*
* getDocBlk:	Returns the current DocRegParamBlock values from the 
*				LineEdit controls.
*
* Inputs:		NONE
* Outputs:		docBlock is the DOC register paramBlock.
* Calls:		getEditInt
}
procedure getDocBlk(var docBlk : DocRegParamBlk);

begin
	with docBlk do
		begin
			oscGenType 	:= getEditInt(oscGenTypeID);
			freqLow1 	:= getEditInt(freqLow1ID);
			freqHigh1 	:= getEditInt(freqHigh1ID);
			vol1 		:= getEditInt(vol1ID);
			tablePtr1 	:= getEditInt(tablePtr1ID);
			control1 	:= getEditInt(control1ID);
			tableSize1 	:= getEditInt(tableSize1ID);
			freqLow2 	:= getEditInt(freqLow2ID);
			freqHigh2 	:= getEditInt(freqHigh2ID);
			vol2 		:= getEditInt(vol2ID);
			tablePtr2 	:= getEditInt(tablePtr2ID);
			control2 	:= getEditInt(control2ID);
			tableSize2 	:= getEditInt(tableSize2ID);
		end;
end;
	
{******************************************************************************
*
* getSndBlk:	Returns the current SoundParamBlock values from the 
*				LineEdit controls.
*
* Inputs:		NONE
* Outputs:		sndBlk is the Sound paramBlock.
* Calls:		getEditInt, getEditLong
}
procedure getSndBlk(var sndBlk : SoundParamBlock);

begin
	with sndBlk do
		begin
			waveStart 	:= Ptr(getEditLong(waveStartID));
			waveSize 	:= getEditInt(waveSizeID);
			freqOffset 	:= getEditInt(freqOffsetID);
			docBuffer 	:= getEditInt(docBufferID);
			bufferSize 	:= getEditInt(bufferSizeID);
			nextWavePtr := SoundPBPtr(getEditLong(nextWavePtrID));
			volSetting 	:= getEditInt(volSettingID);
		end;
end;	

{******************************************************************************
*
* setDocBlk:	Updates the LineEdit controls based on the values in the 
*				current DocRegParamBlock.
*
* Inputs:		docBlock is the DOC register paramBlock.
* Outputs:		NONE
* Calls:		setEditInt
}
procedure setDocBlk(docBlk : DocRegParamBlk);

begin
	with docBlk do
		begin
			setEditInt(oscGenType, oscGenTypeID, 4);
			setEditInt(freqLow1, freqLow1ID, 2);
			setEditInt(freqHigh1, freqHigh1ID, 2);
			setEditInt(vol1, vol1ID, 2);
			setEditInt(tablePtr1, tablePtr1ID, 2);
			setEditInt(control1, control1ID, 2);
			setEditInt(tableSize1, tableSize1ID, 2);
			setEditInt(freqLow2, freqLow2ID, 2);
			setEditInt(freqHigh2, freqHigh2ID, 2);
			setEditInt(vol2, vol2ID, 2);
			setEditInt(tablePtr2, tablePtr2ID, 2);
			setEditInt(control2, control2ID, 2);
			setEditInt(tableSize2, tableSize2ID, 2);
		end;
end;
	
{******************************************************************************
*
* setSndBlk:	Updates the LineEdit controls based on the values in the 
*				current SoundParamBlock.
*				LineEdit controls.
*
* Inputs:		sndBlk is the Sound paramBlock.
* Outputs:		NONE
* Calls:		setEditInt, setEditLong
}
procedure setSndBlk(sndBlk : SoundParamBlock);

begin
	with sndblk do
		begin
			setEditLong(longint(waveStart), waveStartID);
			setEditInt(waveSize, waveSizeID, 4);
			setEditInt(freqOffset, freqOffsetID, 4);
			setEditInt(docBuffer, docBufferID, 4);
			setEditInt(bufferSize, bufferSizeID, 4);
			setEditLong(longint(nextWavePtr), nextWavePtrID);
			setEditInt(volSetting, volSettingID, 4);
		end;
end;	

{******************************************************************************
*
* doExecute:	doExecute executes the Sound Tools command chosen in the 
*				pop-up menu.  If necessary, it gets the values from the 	
*				correct parameters (or paramBlocks) and makes the call
*				with them.  When the call is completed, it updates the
*				affected parameters, including the staticText results.
*
* Inputs:		NONE
* Outputs:		NONE
* Calls:		setTargetCtl, getEditLong, getSndBlk, setSndBlk, getDocBlk, 
*				setDocBlk, setEditLong, setResult
}
procedure doExecute;

var
	docBlk : DocRegParamBlk;
	sndBlk : SoundParamBlock;
	parm1,
	parm2,
	parm3	: longint;
	
begin
	setTargetCtl;					{ set the target control }

	{ update the parameter values to be passed to the calls }
	if ctlHilite.parm[1] then parm1 := getEditLong(Parm1ID);
	if ctlHilite.parm[2] then parm2 := getEditLong(Parm2ID);
	if ctlHilite.parm[3] then parm3 := getEditLong(Parm3ID);
	
	CurCmdErr := 0;		{ reset the result values }
	CurCmdResult := 0;

	case CurCmdNum of		{ based on the pop-up selection, make the call }
		SoundVersionID 		: CurCmdResult := SoundVersion;
		SoundToolStatusID 	: CurCmdResult := ord(SoundToolStatus);
		FFGeneratorStatusID : CurCmdResult := FFGeneratorStatus (parm1);
		FFSoundDoneStatusID : CurCmdResult := ord(FFSoundDoneStatus (parm1));
		FFSoundStatusID 	: CurCmdResult := FFSoundStatus;
		FFStartSoundID 		:
			begin
				getSndBlk(sndBlk);
				FFStartSound(trunc(parm1), @sndBlk);
				CurCmdErr := _toolErr;
				setSndBlk(sndBlk);
			end;
		FFStopSoundID 		: FFStopSound(trunc(parm1))  ;
		GetSoundVolumeID 	: CurCmdResult := GetSoundVolume (parm1);
		GetTableAddressID 	: CurCmdResult := longint(GetTableAddress);
		ReadRamBlockID 		: ReadRamBlock ( Ptr(parm1), parm2, parm3);
		SetSoundMIRQVID 	: SetSoundMIRQV (parm1);
		SetSoundVolumeID 	: SetSoundVolume (parm1, parm2);
		SetUserSoundIRQVID 	: CurCmdResult := longint(SetUserSoundIRQV (ProcPtr(parm1)));
		WriteRamBlockID 	: WriteRamBlock (Ptr(parm1), trunc(parm2), trunc(parm3));
		FFSetUpSoundID 		:
			begin
				getSndBlk(sndBlk);
				FFSetUpSound (parm1, @sndBlk);
				CurCmdErr := _toolErr;
				setSndBlk(sndBlk);
			end;
		FFStartPlayingID 	: FFStartPlaying (parm1);
		SetDOCRegID 		:
			begin
				getDocBlk(docBlk);
				SetDOCReg (docBlk)  ;
				CurCmdErr := _toolErr;
				setDocBlk(docBlk);
			end;
		ReadDOCRegID 		:
			begin
				getDocBlk(docBlk);
				ReadDOCReg (docBlk)  ;
				CurCmdErr := _toolErr;
				setDocBlk(docBlk);
			end;
	end;
	
	if CurCmdErr = 0 then CurCmdErr := _toolErr;

	if ctlHilite.parm[1] then setEditLong(Parm1, Parm1ID); { update the parameters }
	if ctlHilite.parm[2] then setEditLong(Parm2, Parm2ID);
	if ctlHilite.parm[3] then setEditLong(Parm3, Parm3ID);
	
	setResult;					{ update the result strings }
end;

{******************************************************************************
*
* editToStatic:	Replaces a LineEdit control with a staticText control.
*
* Inputs:		NONE
* Outputs:		NONE
* Calls:		getEditStr
}
procedure editToStatic(theCtlID : integer);

type 
	StaticTextTemplate = RECORD
		tpPCount 	: integer;
		tpID		: longint;
		tpRect		: rect;
		tpProcRef	: longint;
		tpFlag		: integer;
		tpMoreFlags : integer;
		tpRefCon	: longint;
		tpTextRef	: longint;
		tpTextSize	: integer;
	end;

var 
	tempString	: String;
	theCtl		: CtlRecHndl;
	theTemplate : StaticTextTemplate;

begin
	getEditStr(tempString,theCtlID);
	parmArray[theCtlID] := tempString;
	theCtl := GetCtlHandleFromID(ourWindow, theCtlID);
	with theTemplate do
		begin
			tpPcount := 8;
			tpID := theCtlID;
			tpRect := theCtl^^.ctlRect;
			tpProcRef := $81000000;
			tpFlag := 0;
			tpMoreFlags := $1000;
			tpRefCon := 0;
			tpTextRef := longint(@parmArray[theCtlID]) + 1;
			tpTextSize := ord(parmArray[theCtlID][0]);
		end;
	DisposeControl(theCtl);
	theCtl := NewControl2(ourWindow, 0, Ref(@theTemplate));
end;

{******************************************************************************
*
* staticToEdit:	Replaces a staticText control with a LineEdit control.
*
* Inputs:		theCtlID is the ID of the control to replace.
* Outputs:		NONE
* Calls:		NONE
}
procedure staticToEdit(theCtlID : integer);

Type 
	EditLineTemplate = RECORD
		tpPCount 	: integer;
		tpID		: longint;
		tpRect		: rect;
		tpProcRef	: longint;
		tpFlag		: integer;
		tpMoreFlags : integer;
		tpRefCon	: longint;
		tpMaxSize	: integer;
		tpDefaultRef: longint;
	end;

var 
	theCtl		: CtlRecHndl;
	theTemplate : EditLineTemplate;

begin
	theCtl := GetCtlHandleFromID(ourWindow, theCtlID);
	with theTemplate do
		begin
			tpPcount := 8;
			tpID := theCtlID;
			tpRect := theCtl^^.ctlRect;
			tpProcRef := $83000000;
			tpFlag := 0;
			tpMoreFlags := $7000;
			tpRefCon := 0;
			tpMaxSize := 10;
			tpDefaultRef := longint(@parmArray[theCtlID]);
		end;
	DisposeControl(theCtl);
	theCtl := NewControl2(ourWindow, 0, Ref(@theTemplate));
end;

{******************************************************************************
*
* doHilite:		Dispatches to editToStatic or staticToEdit to toggle a 
*				control between a "hilited" and "unhilited" state.
*
* Inputs:		theCtlID is the ID of the control to replace.  hiliteVal
*				determines whether the control is hilited or not.
* Outputs:		NONE
* Calls:		editToStatic, staticToEdit
}
procedure doHilite(hiliteVal : integer; theCtlID : integer);

begin
	if hiliteVal = inactiveHilite then
		begin
			editToStatic(theCtlID);
		end
	else
		begin
			staticToEdit(theCtlID);
		end;
 	MakeThisCtlTarget (GetCtlHandleFromID(ourwindow,oscGenTypeID));
	DrawOneCtl(GetCtlHandleFromID(ourWindow, theCtlID));
end;

{******************************************************************************
*
* hiliteSndBlk:	Dispatches to doHilite to toggle the controls in the 
				Sound paramBlock between a "hilited" and "unhilited" state.
*
* Inputs:		NONE
* Outputs:		NONE
* Calls:		doHilite
}
procedure hiliteSndBlk;
	
var ctlID,
	hiliteVal: integer;

begin
	if ctlHilite.sndBlk then 
		begin
			hiliteVal := inactiveHilite;
			ctlHilite.sndBlk := FALSE;
		end
	else 
		begin
			hiliteVal := noHilite;
			ctlHilite.sndBlk := TRUE;
		end;
			
						
	for ctlID := volSettingID downto waveStartID do
		doHilite(hiliteVal,ctlID);
end;

{******************************************************************************
*
* hiliteDocBlk:	Dispatches to doHilite to toggle the controls in the 
*				DOC Register paramBlock between a "hilited" and 
*				"unhilited" state.
*
* Inputs:		NONE
* Outputs:		NONE
* Calls:		doHilite
}
procedure hiliteDocBlk;
	
var ctlID,
	hiliteVal: integer;

begin
	if ctlHilite.docBlk then 
		begin
			hiliteVal := inactiveHilite;
			ctlHilite.docBlk := FALSE;
		end
	else 
		begin
			hiliteVal := noHilite;
			ctlHilite.docBlk := TRUE;
		end;
						
	for ctlID := tableSize2ID downto oscGenTypeID do
		doHilite(hiliteVal,ctlID);
end;

{******************************************************************************
*
* hiliteParmX:	Dispatches to doHilite to toggle the controls for the 
*				parameters between a "hilited" and "unhilited" state.
*				It also is responsible for the naming of the parameters:
*				
*			   -----------
*			   |$00000000|	genNumFFSynth			for a hilited parm
*			   -----------
*				
*				or
*
*			    $00000000 	Parm1					for an unhilited parm
*				    ^		  ^
*				    |		  |____________________ the description
*				    |______________________________ the parameter itself
*				
* Inputs:		parmNum is the index to the controlID.  parmString describes 
*				the parameter.
* Outputs:		NONE
* Calls:		doHilite
}
procedure hiliteParmX(parmNum : integer; parmString : String);

var setString : String;
	hiliteVal: integer;

begin
	if ctlHilite.parm[parmNum] then 
		begin
			hiliteVal := inactiveHilite;
			setString := 'ParmX';
			setString[5] := chr(48 + parmNum);
			ctlHilite.parm[parmNum] := FALSE;
		end
	else 
		begin
			hiliteVal := noHilite;
			setString := parmString;
			ctlHilite.parm[parmNum] := TRUE;
		end;
		paramRec1.Str[5 + parmNum] := setString;
		DrawOneCtl(GetCtlHandleFromID(ourwindow, 223 + parmNum));
		doHilite(hiliteVal,320 + parmNum);
end;

{******************************************************************************
*
* doHiliteCtls:	sets up the parameters for the call passed to it in cmdNum.
*				
* Inputs:		cmdNum is the call to set up for
* Outputs:		NONE
* Calls:		hiliteParmX, hiliteSndBlk, hiliteDocBlk
}
procedure doHiliteCtls(cmdNum : integer);

begin
	case cmdNum of
		SoundVersionID 		:;
		SoundToolStatusID 	:;
		FFGeneratorStatusID : hiliteParmX(1,'genNumber');
		FFSoundDoneStatusID : hiliteParmX(1,'genNumber');
		FFSoundStatusID 	:;
		FFStartSoundID 		:
			begin
				hiliteParmX(1,'genNumFFSynth');
				hiliteSndBlk;
			end;
		FFStopSoundID 		: hiliteParmX(1,'genMask');
		GetSoundVolumeID 	: hiliteParmX(1,'genNumber');
		GetTableAddressID 	:;
		ReadRamBlockID 		:
			begin
				hiliteParmX(3,'byteCount');
				hiliteParmX(2,'docStart');
				hiliteParmX(1,'destPtr');
			end;
		SetSoundMIRQVID 	: hiliteParmX(1,'sMasterIRQ');
		SetSoundVolumeID 	:
			begin
				hiliteParmX(2,'genNumber');
				hiliteParmX(1,'volume');
			end;
		SetUserSoundIRQVID 	: hiliteParmX(1,'userIRQVector');
		WriteRamBlockID 	:
			begin
				hiliteParmX(3,'byteCount');
				hiliteParmX(2,'docStart');
				hiliteParmX(1,'srcPtr');
			end;
		FFSetUpSoundID 		:
			begin
				hiliteParmX(1,'channelGen');
				hiliteSndBlk;
			end;
		FFStartPlayingID 	: hiliteParmX(1,'genWord');
		SetDocRegID			: hiliteDocBlk;
		ReadDOCRegID 		: hiliteDocBlk;
	end;
end;

{******************************************************************************
*
* doSndCmdPopUp:	Updates the current command and calls the hilite routines
*					to make the correct parameters available.
*				
* Inputs:		NONE
* Outputs:		NONE
* Calls:		doHiliteCtls, setTargetCtl
}
procedure doSndCmdPopUp;				{ update the Current Command }

var	
	theCtl : CtlRecHndl;
	theCmd : integer;

begin
	theCtl := GetCtlHandleFromID(ourwindow,sndCmdPopUp);
	theCmd := theCtl^^.ctlValue;
	doHiliteCtls(CurCmdNum);		{ unhilite the controls for the previous command }
	doHiliteCtls(theCmd);			{ hilite the controls for the current command }
	setTargetCtl;					{ Make the caret blink in the first available Ctl }
	CurCmdNum := theCmd;			{ update the global variable }
end;

{******************************************************************************
*
* doInControl:	dispatches to the correct routine depending on the control 
*				that was activated.
*				
* Inputs:		NONE
* Outputs:		NONE
* Calls:		doExecute, doLoadFile, doSndCmdPopUp
}
procedure doInControl;

var
	theID		: Integer;

begin
	theID := myEvent.wmTaskData4;				{ what control ?}
							  
	case theID of
		execbut: 		doExecute;				{ execute the current command }
		loadbut:		doLoadFile;				{ load a file }
		sndCmdPopUp:	doSndCmdPopUp;			{ handle the pop-up result }
	end;
end;

{******************************************************************************
*
* InitSoundEx:	Initializes all of the global variables.
*				
* Inputs:		NONE
* Outputs:		NONE
* Calls:		doExecute, doLoadFile, doSndCmdPopUp
}
procedure InitSoundEx;

var x : integer;

begin
	for x := 0 to 9 do			{ zero out the paramText Strings }
			begin
				paramRec1.StrPtr[x] := @paramRec1.Str[x];
				paramRec1.Str[x] := '';
			end;
			
	paramRec1.Str[0] := 'SoundVersion';		{ set them how we want them }
	paramRec1.Str[1] := 'none';
	paramRec1.Str[2] := '00000000';
	paramRec1.Str[3] := '0000';
	paramRec1.Str[4] := '00000000';
	paramRec1.Str[5] := '0000';
	
	ctlHilite.docBlk := TRUE;				{ set up the default hilites for ctls }
	ctlHilite.sndBlk := TRUE;
	for x := 1 to 3 do ctlHilite.parm[x] := TRUE;
	
	SetCtlParamPtr ( @paramRec1)  ;			{ now we can set the paramText }
	
	CurCmdNum := SoundVersionID;			{ the current command is SoundVersionID } 
	BuffHndl := NIL;						{ no buffer yet }
end;