/* SampleWindow.c */
/*****************************************************************************/
/*                                                                           */
/*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
/*    Copyright (C) 1994  Thomas R. Lawrence                                 */
/*                                                                           */
/*    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.              */
/*                                                                           */
/*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
/*                                                                           */
/*****************************************************************************/

#include "MiscInfo.h"
#include "Audit.h"
#include "Debug.h"
#include "Definitions.h"

#include "SampleWindow.h"
#include "Memory.h"
#include "MainWindowStuff.h"
#include "CodeCenter.h"
#include "SampleObject.h"
#include "SampleView.h"
#include "TextEdit.h"
#include "WindowDispatcher.h"
#include "Alert.h"
#include "GrowIcon.h"
#include "SampleTestPlay.h"
#include "DataMunging.h"
#include "Main.h"
#include "Numbers.h"
#include "PcodeStack.h"
#include "PcodeSystem.h"
#include "Scroll.h"
#include "SampleList.h"
#include "EditImages.h"
#include "IconButton.h"
#include "SampleStorageActual.h"
#include "SampleStorageDisplay.h"
#include "FindDialog.h"
#include "GlobalWindowMenuList.h"
#include "CompilerRoot.h"
#include "FunctionCode.h"
#include "ExportWAVSample.h"
#include "ExportRAWSample.h"
#include "ExportAIFFSample.h"


#define OVERLINEHEIGHT (13)

#define ZOOMFACTOR (2) /* zoom doubles / halves the resolution */

#define WINDOWXSIZE (512 - 4 - 4)
#define WINDOWYSIZE (342 - 20 - 20 - 4 - 4)

#define EXPRESSIONEDITX (-1)
#define EXPRESSIONEDITWIDTH(WindowWidth) ((WindowWidth) + 2)
#define EXPRESSIONEDITHEIGHT (70)
#define EXPRESSIONEDITY(WindowHeight) ((WindowHeight) - EXPRESSIONEDITHEIGHT + 1)

#define SAMPLEEDITX (-1)
#define SAMPLEEDITY (41)
#define SAMPLEEDITWIDTH(WindowWidth) ((WindowWidth) + 2)
#define SAMPLEEDITHEIGHT(WindowHeight) ((WindowHeight) - SAMPLEEDITY - 70\
					- EXPRESSIONEDITHEIGHT)

#define NAMEEDITX (80)
#define NAMEEDITY (1)
#define NAMEEDITWIDTH (80)
#define NAMEEDITHEIGHT (19)

#define SAMPLINGRATEEDITX (80)
#define SAMPLINGRATEEDITY (21)
#define SAMPLINGRATEEDITWIDTH (80)
#define SAMPLINGRATEEDITHEIGHT (19)

#define ORIGINEDITX (240)
#define ORIGINEDITY (1)
#define ORIGINEDITWIDTH (80)
#define ORIGINEDITHEIGHT (19)

#define BASEFREQEDITX (240)
#define BASEFREQEDITY (21)
#define BASEFREQEDITWIDTH (80)
#define BASEFREQEDITHEIGHT (19)

#define LOOPSTARTEDITX (400)
#define LOOPSTARTEDITY (1)
#define LOOPSTARTEDITWIDTH (80)
#define LOOPSTARTEDITHEIGHT (19)

#define LOOPENDEDITX (400)
#define LOOPENDEDITY (21)
#define LOOPENDEDITWIDTH (80)
#define LOOPENDEDITHEIGHT (19)

#define SELECTSTARTEDITX (160)
#define SELECTSTARTEDITY(WinHeight) ((WinHeight) - 19 - 19 - 19 - 3\
					- EXPRESSIONEDITHEIGHT)
#define SELECTSTARTEDITWIDTH (80)
#define SELECTSTARTEDITHEIGHT (19)

#define SELECTENDEDITX (160)
#define SELECTENDEDITY(WinHeight) ((WinHeight) - 19 - 19 - 2 - EXPRESSIONEDITHEIGHT)
#define SELECTENDEDITWIDTH (80)
#define SELECTENDEDITHEIGHT (19)

#define SCALINGEDITX (330)
#define SCALINGEDITY(WinHeight) ((WinHeight) - 19 - 19 - 19 - 3 - EXPRESSIONEDITHEIGHT)
#define SCALINGEDITWIDTH (80)
#define SCALINGEDITHEIGHT (19)

#define MOUSEPOSEDITX (160)
#define MOUSEPOSEDITY(WindowHeight) ((WindowHeight) - 19 - 1 - EXPRESSIONEDITHEIGHT)
#define MOUSEPOSEDITWIDTH (80)
#define MOUSEPOSEDITHEIGHT (19)

#define BITS8X (1)
#define BITS8Y(WinHeight) ((WinHeight) - 33 - EXPRESSIONEDITHEIGHT)

#define BITS16X (BITS8X + 33)
#define BITS16Y(WinHeight) (BITS8Y(WinHeight))

#define MONOX (1)
#define MONOY(WinHeight) ((WinHeight) - 33 - 33 - 3 - EXPRESSIONEDITHEIGHT)

#define STEREOX (MONOX + 33)
#define STEREOY(WinHeight) (MONOY(WinHeight))

#define PLAYX (410 + 2)
#define PLAYY(WinHeight) ((WinHeight) - 33 - EXPRESSIONEDITHEIGHT)

#define ZOOMINX (410 + 2)
#define ZOOMINY(WinHeight) ((WinHeight) - 33 - 33 - 3 - EXPRESSIONEDITHEIGHT)

#define ZOOMOUTX (ZOOMINX + 33)
#define ZOOMOUTY(WinHeight) (ZOOMINY(WinHeight))

#define SAMPLENAMEX (3)
#define SAMPLENAMEY (4)

#define SAMPLERATEX (3)
#define SAMPLERATEY (23)

#define ORIGINX (170)
#define ORIGINY (4)

#define BASEFREQX (170)
#define BASEFREQY (23)

#define LOOPSTARTX (330)
#define LOOPSTARTY (4)

#define LOOPENDX (330)
#define LOOPENDY (23)

#define SELECTSTARTX (76)
#define SELECTSTARTY(WinHeight) ((WinHeight) - 19 - 19 - 19 - 3 + 3\
					- EXPRESSIONEDITHEIGHT)

#define SELECTENDX (76)
#define SELECTENDY(WinHeight) ((WinHeight) - 19 - 19 - 2 + 3 - EXPRESSIONEDITHEIGHT)

#define MOUSELOCX (76)
#define MOUSELOCY(WinHeight) ((WinHeight) - 19 - 1 + 3 - EXPRESSIONEDITHEIGHT)

#define SCALINGX (250)
#define SCALINGY(WinHeight) ((WinHeight) - 19 - 19 - 19 - 3 + 3 - EXPRESSIONEDITHEIGHT)


struct SampleWindowRec
	{
		MainWindowRec*			MainWindow;
		CodeCenterRec*			CodeCenter;
		SampleObjectRec*		SampleObject;
		SampleListRec*			SampleList;

		WinType*						ScreenID;
		SampleViewRec*			SampleView;
		TextEditRec*				NameEdit;
		TextEditRec*				SampleExpressionEdit;
		TextEditRec*				SamplingRateEdit;
		TextEditRec*				OriginEdit;
		TextEditRec*				NaturalFrequencyEdit;
		TextEditRec*				LoopStartEdit;
		TextEditRec*				LoopEndEdit;
		SampleLoops					EditingWhichLoop;
		TextEditRec*				SelectionStartEdit;
		TextEditRec*				SelectionEndEdit;
		TextEditRec*				ScalingEdit;
		TextEditRec*				ActiveTextEdit;
		TextEditRec*				MousePositionEdit;
		ScrollRec*					Scrollbar;
		IconButtonRec*			Bits8Button;
		IconButtonRec*			Bits16Button;
		IconButtonRec*			MonoButton;
		IconButtonRec*			StereoButton;
		IconButtonRec*			ZoomInButton;
		IconButtonRec*			ZoomOutButton;
		IconButtonRec*			PlayButton;
		GenericWindowRec*		MyGenericWindow; /* how the window event dispatcher knows us */
		MenuItemType*				MyMenuItem;
		long								UndoOrigin;
		long								UndoLoopStart1;
		long								UndoLoopStart2;
		long								UndoLoopStart3;
		long								UndoLoopEnd1;
		long								UndoLoopEnd2;
		long								UndoLoopEnd3;
	};


/* create a new sample editing window.  the function gets ownership of SampleStorage */
SampleWindowRec*		NewSampleWindow(struct MainWindowRec* MainWindow,
											struct SampleObjectRec* SampleObject,
											struct CodeCenterRec* CodeCenter,
											struct SampleStorageActualRec* SampleStorage,
											struct SampleListRec* SampleList,
											OrdType WinX, OrdType WinY, OrdType WinWidth, OrdType WinHeight)
	{
		SampleWindowRec*	Window;
		char*							StringTemp;
		NumChannelsType		NumChannels;
		SampleStorageDisplayRec*	SampleCopy;
		long							Limit;
		long							Scan;

		/* deal with window placement */
		if ((WinWidth < 100) || (WinHeight < 100) || ((eOptionKey & CheckModifiers()) != 0))
			{
				WinX = 1 + WindowOtherEdgeWidths(eDocumentWindow);
				WinY = 1 + WindowTitleBarHeight(eDocumentWindow);
				WinWidth = WINDOWXSIZE;
				WinHeight = WINDOWYSIZE;
			}
		MakeWindowFitOnScreen(&WinX,&WinY,&WinWidth,&WinHeight);

		Window = (SampleWindowRec*)AllocPtrCanFail(
			sizeof(SampleWindowRec),"SampleWindowRec");
		if (Window == NIL)
			{
			 FailurePoint1:
				AlertHalt("There is not enough memory available to "
					"display the sample editor.",NIL);
				return NIL;
			}
		Window->MainWindow = MainWindow;
		Window->SampleObject = SampleObject;
		Window->CodeCenter = CodeCenter;
		Window->SampleList = SampleList;

		Window->ScreenID = MakeNewWindow(eDocumentWindow,eWindowClosable,
			eWindowZoomable,eWindowResizable,WinX,WinY,WinWidth,WinHeight,
			(void (*)(void*))&SampleWindowUpdator,Window);
		if (Window->ScreenID == 0)
			{
			 FailurePoint2:
				ReleasePtr((char*)Window);
				goto FailurePoint1;
			}

		/* create sample editor */
		NumChannels = GetSampleStorageActualNumChannels(SampleStorage);
		SampleCopy = NewSampleStorageDisplayEmpty(
			GetSampleStorageActualNumBits(SampleStorage),NumChannels);
		if (SampleCopy == NIL)
			{
			 FailurePoint3:
				KillWindow(Window->ScreenID);
				goto FailurePoint2;
			}
		Limit = GetSampleStorageActualNumFrames(SampleStorage);
		if (!InsertSampleStorageDisplayArea(SampleCopy,0,Limit))
			{
				goto FailurePoint3;
			}
		switch (NumChannels)
			{
				default:
					EXECUTE(PRERR(ForceAbort,"NewSampleWindow:  bad num bits"));
					break;
				case eSampleMono:
					for (Scan = 0; Scan < Limit; Scan += 1)
						{
							SetSampleStorageDisplayValue(SampleCopy,Scan,eMonoChannel,
								GetSampleStorageActualValue(SampleStorage,Scan,eMonoChannel));
						}
					break;
				case eSampleStereo:
					for (Scan = 0; Scan < Limit; Scan += 1)
						{
							SetSampleStorageDisplayValue(SampleCopy,Scan,eLeftChannel,
								GetSampleStorageActualValue(SampleStorage,Scan,eLeftChannel));
							SetSampleStorageDisplayValue(SampleCopy,Scan,eRightChannel,
								GetSampleStorageActualValue(SampleStorage,Scan,eRightChannel));
						}
					break;
			}
		Window->SampleView = NewSampleView(Window->ScreenID,SAMPLEEDITX,
			SAMPLEEDITY + (3 * OVERLINEHEIGHT),SAMPLEEDITWIDTH(WinWidth),
			SAMPLEEDITHEIGHT(WinHeight) - 15 - (3 * OVERLINEHEIGHT),SampleCopy);
		if (Window->SampleView == NIL)
			{
				/* this is not a true exception point because SampleCopy is only */
				/* valid & needs to be dumped if this call fails, otherwise no. */
				DisposeSampleStorageDisplay(SampleCopy);
				goto FailurePoint3;
			}
		SampleViewHasBeenSaved(Window->SampleView);

		/* create name edit */
		Window->NameEdit = NewTextEdit(Window->ScreenID,eTENoScrollBars,
			GetScreenFont(),9,NAMEEDITX,NAMEEDITY,NAMEEDITWIDTH,NAMEEDITHEIGHT);
		if (Window->NameEdit == NIL)
			{
			 FailurePoint4:
				DisposeSampleView(Window->SampleView);
				goto FailurePoint3;
			}
		/* install new text in name edit */
		StringTemp = SampleObjectGetNameCopy(SampleObject);
		if (StringTemp == NIL)
			{
			 FailurePoint5:
				DisposeTextEdit(Window->NameEdit);
				goto FailurePoint4;
			}
		TextEditNewRawData(Window->NameEdit,StringTemp,"\x0a");
		ReleasePtr(StringTemp);
		TextEditHasBeenSaved(Window->NameEdit);

		/* create sampling rate edit */
		Window->SamplingRateEdit = NewTextEdit(Window->ScreenID,eTENoScrollBars,
			GetScreenFont(),9,SAMPLINGRATEEDITX,SAMPLINGRATEEDITY,
			SAMPLINGRATEEDITWIDTH,SAMPLINGRATEEDITHEIGHT);
		if (Window->SamplingRateEdit == NIL)
			{
			 FailurePoint6:
				goto FailurePoint5;
			}

		/* create origin edit */
		Window->OriginEdit = NewTextEdit(Window->ScreenID,eTENoScrollBars,
			GetScreenFont(),9,ORIGINEDITX,ORIGINEDITY,ORIGINEDITWIDTH,ORIGINEDITHEIGHT);
		if (Window->OriginEdit == NIL)
			{
			 FailurePoint7:
				DisposeTextEdit(Window->SamplingRateEdit);
				goto FailurePoint6;
			}

		/* create base frequency edit */
		Window->NaturalFrequencyEdit = NewTextEdit(Window->ScreenID,eTENoScrollBars,
			GetScreenFont(),9,BASEFREQEDITX,BASEFREQEDITY,BASEFREQEDITWIDTH,
			BASEFREQEDITHEIGHT);
		if (Window->NaturalFrequencyEdit == NIL)
			{
			 FailurePoint8:
				DisposeTextEdit(Window->OriginEdit);
				goto FailurePoint7;
			}

		/* create loop start edit */
		Window->LoopStartEdit = NewTextEdit(Window->ScreenID,eTENoScrollBars,
			GetScreenFont(),9,LOOPSTARTEDITX,LOOPSTARTEDITY,LOOPSTARTEDITWIDTH,
			LOOPSTARTEDITHEIGHT);
		if (Window->LoopStartEdit == NIL)
			{
			 FailurePoint9:
				DisposeTextEdit(Window->NaturalFrequencyEdit);
				goto FailurePoint8;
			}

		/* create loop end edit */
		Window->LoopEndEdit = NewTextEdit(Window->ScreenID,eTENoScrollBars,
			GetScreenFont(),9,LOOPENDEDITX,LOOPENDEDITY,LOOPENDEDITWIDTH,LOOPENDEDITHEIGHT);
		if (Window->LoopEndEdit == NIL)
			{
			 FailurePoint10:
				DisposeTextEdit(Window->LoopStartEdit);
				goto FailurePoint9;
			}

		Window->EditingWhichLoop = eSampleLoop1;

		/* create selection start edit */
		Window->SelectionStartEdit = NewTextEdit(Window->ScreenID,eTENoScrollBars,
			GetScreenFont(),9,SELECTSTARTEDITX,SELECTSTARTEDITY(WinHeight),
			SELECTSTARTEDITWIDTH,SELECTSTARTEDITHEIGHT);
		if (Window->SelectionStartEdit == NIL)
			{
			 FailurePoint11:
				DisposeTextEdit(Window->LoopEndEdit);
				goto FailurePoint10;
			}

		/* create selection end edit */
		Window->SelectionEndEdit = NewTextEdit(Window->ScreenID,eTENoScrollBars,
			GetScreenFont(),9,SELECTENDEDITX,SELECTENDEDITY(WinHeight),
			SELECTENDEDITWIDTH,SELECTENDEDITHEIGHT);
		if (Window->SelectionEndEdit == NIL)
			{
			 FailurePoint12:
				DisposeTextEdit(Window->SelectionStartEdit);
				goto FailurePoint11;
			}

		/* create scaling edit */
		Window->ScalingEdit = NewTextEdit(Window->ScreenID,eTENoScrollBars,
			GetScreenFont(),9,SCALINGEDITX,SCALINGEDITY(WinHeight),
			SCALINGEDITWIDTH,SCALINGEDITHEIGHT);
		if (Window->ScalingEdit == NIL)
			{
			 FailurePoint13:
				DisposeTextEdit(Window->SelectionEndEdit);
				goto FailurePoint12;
			}

		/* create place to show mouse position */
		Window->MousePositionEdit = NewTextEdit(Window->ScreenID,eTENoScrollBars,
			GetScreenFont(),9,MOUSEPOSEDITX,MOUSEPOSEDITY(WinHeight),
			MOUSEPOSEDITWIDTH,MOUSEPOSEDITHEIGHT);
		if (Window->MousePositionEdit == NIL)
			{
			 FailurePoint14:
				DisposeTextEdit(Window->ScalingEdit);
				goto FailurePoint13;
			}

		/* expression editor */
		Window->SampleExpressionEdit = NewTextEdit(Window->ScreenID,
			(TEScrollType)(eTEVScrollBar | eTEHScrollBar),GetMonospacedFont(),9,
			EXPRESSIONEDITX,EXPRESSIONEDITY(WinHeight),EXPRESSIONEDITWIDTH(WinWidth),
			EXPRESSIONEDITHEIGHT);
		if (Window->SampleExpressionEdit == NIL)
			{
			 FailurePoint15:
				DisposeTextEdit(Window->MousePositionEdit);
				goto FailurePoint14;
			}
		StringTemp = SampleObjectGetFormulaCopy(SampleObject);
		if (StringTemp == NIL)
			{
			 FailurePoint16:
				DisposeTextEdit(Window->SampleExpressionEdit);
				goto FailurePoint15;
			}
		SetTextEditAutoIndent(Window->SampleExpressionEdit,True);
		SetTextEditTabSize(Window->SampleExpressionEdit,MainWindowGetTabSize(MainWindow));
		TextEditNewRawData(Window->SampleExpressionEdit,StringTemp,"\x0a");
		ReleasePtr(StringTemp);

		Window->Scrollbar = NewScrollBar(Window->ScreenID,eHScrollBar,SAMPLEEDITX,
			SAMPLEEDITY + SAMPLEEDITHEIGHT(WinHeight) - 16,SAMPLEEDITWIDTH(WinWidth));
		if (Window->Scrollbar == NIL)
			{
			 FailurePoint17:
				goto FailurePoint16;
			}

		Window->Bits8Button = NewIconButtonPreparedBitmaps(Window->ScreenID,BITS8X,
			BITS8Y(WinHeight),32,32,Bits8Unselected,Bits8MouseDown,
			Bits8Selected,Bits8Selected,eIconRadioMode);
		if (Window->Bits8Button == NIL)
			{
			 FailurePoint18:
				DisposeScrollBar(Window->Scrollbar);
				goto FailurePoint17;
			}

		Window->Bits16Button = NewIconButtonPreparedBitmaps(Window->ScreenID,BITS16X,
			BITS16Y(WinHeight),32,32,Bits16Unselected,Bits16MouseDown,
			Bits16Selected,Bits16Selected,eIconRadioMode);
		if (Window->Bits16Button == NIL)
			{
			 FailurePoint19:
				DisposeIconButton(Window->Bits8Button);
				goto FailurePoint18;
			}

		switch (SampleObjectGetNumBits(SampleObject))
			{
				case eSample8bit:
					SetIconButtonState(Window->Bits8Button,True);
					break;
				case eSample16bit:
					SetIconButtonState(Window->Bits16Button,True);
					break;
				default:
					EXECUTE(PRERR(ForceAbort,"NewSampleWindow:  bad number of bits value"));
					break;
			}

		Window->MonoButton = NewIconButtonPreparedBitmaps(Window->ScreenID,MONOX,
			MONOY(WinHeight),32,32,MonoUnselected,MonoMouseDown,
			MonoSelected,MonoSelected,eIconRadioMode);
		if (Window->MonoButton == NIL)
			{
			 FailurePoint20:
				DisposeIconButton(Window->Bits16Button);
				goto FailurePoint19;
			}

		Window->StereoButton = NewIconButtonPreparedBitmaps(Window->ScreenID,STEREOX,
			STEREOY(WinHeight),32,32,StereoUnselected,StereoMouseDown,
			StereoSelected,StereoSelected,eIconRadioMode);
		if (Window->StereoButton == NIL)
			{
			 FailurePoint21:
				DisposeIconButton(Window->MonoButton);
				goto FailurePoint20;
			}

		switch (SampleObjectGetNumChannels(SampleObject))
			{
				case eSampleMono:
					SetIconButtonState(Window->MonoButton,True);
					break;
				case eSampleStereo:
					SetIconButtonState(Window->StereoButton,True);
					break;
				default:
					EXECUTE(PRERR(ForceAbort,"NewSampleWindow:  bad num channels value"));
					break;
			}

		Window->ZoomInButton = NewIconButtonPreparedBitmaps(Window->ScreenID,ZOOMINX,
			ZOOMINY(WinHeight),32,32,ZoomInMouseUp,ZoomInMouseDown,
			ZoomInMouseUp,ZoomInMouseDown,eIconSimpleMode);
		if (Window->ZoomInButton == NIL)
			{
			 FailurePoint22:
				DisposeIconButton(Window->StereoButton);
				goto FailurePoint21;
			}

		Window->ZoomOutButton = NewIconButtonPreparedBitmaps(Window->ScreenID,ZOOMOUTX,
			ZOOMOUTY(WinHeight),32,32,ZoomOutMouseUp,ZoomOutMouseDown,
			ZoomOutMouseUp,ZoomOutMouseDown,eIconSimpleMode);
		if (Window->ZoomOutButton == NIL)
			{
			 FailurePoint23:
				DisposeIconButton(Window->ZoomInButton);
				goto FailurePoint22;
			}

		Window->PlayButton = NewIconButtonPreparedBitmaps(Window->ScreenID,PLAYX,
			PLAYY(WinHeight),32,32,PlayMouseUp,PlayMouseDown,
			PlayMouseUp,PlayMouseDown,eIconSimpleMode);
		if (Window->PlayButton == NIL)
			{
			 FailurePoint24:
				DisposeIconButton(Window->ZoomOutButton);
				goto FailurePoint23;
			}

		/* notify window management */
		Window->MyGenericWindow = CheckInNewWindow(Window->ScreenID,Window,
			(void (*)(void*,MyBoolean,OrdType,OrdType,ModifierFlags))&SampleWindowDoIdle,
			(void (*)(void*))&SampleWindowBecomeActive,
			(void (*)(void*))&SampleWindowBecomeInactive,
			(void (*)(void*))&SampleWindowJustResized,
			(void (*)(OrdType,OrdType,ModifierFlags,void*))&SampleWindowDoMouseDown,
			(void (*)(unsigned char,ModifierFlags,void*))&SampleWindowDoKeyDown,
			(void (*)(void*))&SampleWindowClose,
			(void (*)(void*))&SampleWindowMenuSetup,
			(void (*)(void*,MenuItemType*))&SampleWindowDoMenuCommand);
		if (Window->MyGenericWindow == NIL)
			{
			 FailurePoint25:
				DisposeIconButton(Window->PlayButton);
				goto FailurePoint24;
			}

		Window->MyMenuItem = MakeNewMenuItem(mmWindowMenu,"x",0);
		if (Window->MyMenuItem == NIL)
			{
			 FailurePoint26:
				CheckOutDyingWindow(Window->MyGenericWindow);
				goto FailurePoint25;
			}
		if (!RegisterWindowMenuItem(Window->MyMenuItem,(void (*)(void*))&ActivateThisWindow,
			Window->ScreenID))
			{
			 FailurePoint27:
				KillMenuItem(Window->MyMenuItem);
				goto FailurePoint26;
			}

		Window->ActiveTextEdit = NIL;

		/* install new data into all the edits */
		SampleWindowPutSelectStart(Window);
		SampleWindowPutSelectEnd(Window);
		SampleWindowPutScalingFactor(Window);
		SampleWindowPutOrigin(Window,SampleObjectGetOrigin(SampleObject));
		SampleWindowPutLoopStart(Window,SampleObjectGetLoopStart1(SampleObject));
		SampleWindowPutLoopEnd(Window,SampleObjectGetLoopEnd1(SampleObject));
		SampleWindowPutSamplingRate(Window,SampleObjectGetSamplingRate(SampleObject));
		SampleWindowPutNaturalFrequency(Window,SampleObjectGetNaturalFrequency(SampleObject));
		TextEditHasBeenSaved(Window->SelectionStartEdit);
		TextEditHasBeenSaved(Window->SelectionEndEdit);
		TextEditHasBeenSaved(Window->ScalingEdit);
		TextEditHasBeenSaved(Window->OriginEdit);
		TextEditHasBeenSaved(Window->LoopStartEdit);
		TextEditHasBeenSaved(Window->LoopEndEdit);
		TextEditHasBeenSaved(Window->SamplingRateEdit);
		TextEditHasBeenSaved(Window->NaturalFrequencyEdit);
		UpdateSampleWindowScrollbar(Window);

		SampleWindowResetTitlebar(Window);

		return Window;
	}


/* dispose of the window and write all modified data back */
void								DisposeSampleWindow(SampleWindowRec* Window)
	{
		CheckPtrExistence(Window);

		/* save the data */
		if (!SampleWindowWritebackModifiedData(Window))
			{
				/* failed -- now what? */
			}

		/* now that we've recovered all the data, we can delete the things */
		SampleObjectClosingWindowNotify(Window->SampleObject,
			GetWindowXStart(Window->ScreenID),GetWindowYStart(Window->ScreenID),
			GetWindowWidth(Window->ScreenID),GetWindowHeight(Window->ScreenID));
		DeregisterWindowMenuItem(Window->MyMenuItem);
		KillMenuItem(Window->MyMenuItem);
		CheckOutDyingWindow(Window->MyGenericWindow);
		DisposeSampleView(Window->SampleView);
		DisposeTextEdit(Window->NameEdit);
		DisposeTextEdit(Window->SamplingRateEdit);
		DisposeTextEdit(Window->OriginEdit);
		DisposeTextEdit(Window->NaturalFrequencyEdit);
		DisposeTextEdit(Window->LoopStartEdit);
		DisposeTextEdit(Window->LoopEndEdit);
		DisposeTextEdit(Window->SelectionStartEdit);
		DisposeTextEdit(Window->SelectionEndEdit);
		DisposeTextEdit(Window->ScalingEdit);
		DisposeTextEdit(Window->MousePositionEdit);
		DisposeTextEdit(Window->SampleExpressionEdit);
		DisposeScrollBar(Window->Scrollbar);
		DisposeIconButton(Window->Bits8Button);
		DisposeIconButton(Window->Bits16Button);
		DisposeIconButton(Window->MonoButton);
		DisposeIconButton(Window->StereoButton);
		DisposeIconButton(Window->ZoomInButton);
		DisposeIconButton(Window->ZoomOutButton);
		DisposeIconButton(Window->PlayButton);
		KillWindow(Window->ScreenID);
		ReleasePtr((char*)Window);
	}


/* returns True if any data has been changed since the last time the file was saved */
MyBoolean						HasSampleWindowBeenModified(SampleWindowRec* Window)
	{
		CheckPtrExistence(Window);
		return DoesSampleViewNeedToBeSaved(Window->SampleView)
			|| TextEditDoesItNeedToBeSaved(Window->NameEdit)
			|| TextEditDoesItNeedToBeSaved(Window->SamplingRateEdit)
			|| TextEditDoesItNeedToBeSaved(Window->OriginEdit)
			|| TextEditDoesItNeedToBeSaved(Window->NaturalFrequencyEdit)
			|| TextEditDoesItNeedToBeSaved(Window->LoopStartEdit)
			|| TextEditDoesItNeedToBeSaved(Window->LoopEndEdit)
			|| TextEditDoesItNeedToBeSaved(Window->SampleExpressionEdit);
	}


/* bring the window to the top and give it the focus */
void								SampleWindowBringToTop(SampleWindowRec* Window)
	{
		CheckPtrExistence(Window);
		ActivateThisWindow(Window->ScreenID);
	}


void								SampleWindowDoIdle(SampleWindowRec* Window,
											MyBoolean CheckCursorFlag, OrdType XLoc, OrdType YLoc,
											ModifierFlags Modifiers)
	{
		CheckPtrExistence(Window);
		if (Window->ActiveTextEdit != NIL)
			{
				TextEditUpdateCursor(Window->ActiveTextEdit);
			}
		SampleWindowPutMousePosition(Window);
		if (CheckCursorFlag)
			{
				if (TextEditIBeamTest(Window->NameEdit,XLoc,YLoc)
					|| TextEditIBeamTest(Window->SamplingRateEdit,XLoc,YLoc)
					|| TextEditIBeamTest(Window->OriginEdit,XLoc,YLoc)
					|| TextEditIBeamTest(Window->NaturalFrequencyEdit,XLoc,YLoc)
					|| TextEditIBeamTest(Window->LoopStartEdit,XLoc,YLoc)
					|| TextEditIBeamTest(Window->LoopEndEdit,XLoc,YLoc)
					|| TextEditIBeamTest(Window->SelectionStartEdit,XLoc,YLoc)
					|| TextEditIBeamTest(Window->SelectionEndEdit,XLoc,YLoc)
					|| TextEditIBeamTest(Window->ScalingEdit,XLoc,YLoc)
					|| TextEditIBeamTest(Window->SampleExpressionEdit,XLoc,YLoc))
					{
						SetIBeamCursor();
					}
				else if ((XLoc >= SAMPLEEDITX) && (YLoc >= SAMPLEEDITY)
					&& (XLoc < SAMPLEEDITX + SAMPLEEDITWIDTH(GetWindowWidth(Window->ScreenID)))
					&& (YLoc < SAMPLEEDITY
					+ SAMPLEEDITHEIGHT(GetWindowHeight(Window->ScreenID)) - 15))
					{
						SetSampleInsertionCursor();
					}
				else
					{
						SetArrowCursor();
					}
			}
	}


void								SampleWindowBecomeActive(SampleWindowRec* Window)
	{
		OrdType						XSize;
		OrdType						YSize;

		CheckPtrExistence(Window);
		if (Window->ActiveTextEdit != NIL)
			{
				EnableTextEditSelection(Window->ActiveTextEdit);
			}
		EnableScrollBar(Window->Scrollbar);
		XSize = GetWindowWidth(Window->ScreenID);
		YSize = GetWindowHeight(Window->ScreenID);
		SetClipRect(Window->ScreenID,XSize - 15,YSize - 15,XSize,YSize);
		DrawBitmap(Window->ScreenID,XSize-15,YSize-15,GetGrowIcon(True/*enablegrowicon*/));
	}


void								SampleWindowBecomeInactive(SampleWindowRec* Window)
	{
		OrdType						XSize;
		OrdType						YSize;

		CheckPtrExistence(Window);
		if (Window->ActiveTextEdit != NIL)
			{
				DisableTextEditSelection(Window->ActiveTextEdit);
			}
		DisableScrollBar(Window->Scrollbar);
		XSize = GetWindowWidth(Window->ScreenID);
		YSize = GetWindowHeight(Window->ScreenID);
		SetClipRect(Window->ScreenID,XSize - 15,YSize - 15,XSize,YSize);
		DrawBitmap(Window->ScreenID,XSize-15,YSize-15,GetGrowIcon(False/*disablegrowicon*/));
	}


void								SampleWindowJustResized(SampleWindowRec* Window)
	{
		OrdType						XSize;
		OrdType						YSize;

		CheckPtrExistence(Window);
		XSize = GetWindowWidth(Window->ScreenID);
		YSize = GetWindowHeight(Window->ScreenID);
		SetClipRect(Window->ScreenID,0,0,XSize,YSize);
		DrawBoxErase(Window->ScreenID,0,0,XSize,YSize);

		SetSampleViewLocation(Window->SampleView,SAMPLEEDITX,
			SAMPLEEDITY + (3 * OVERLINEHEIGHT),
			SAMPLEEDITWIDTH(XSize),SAMPLEEDITHEIGHT(YSize) - 15 - (3 * OVERLINEHEIGHT));
		SetTextEditPosition(Window->SelectionStartEdit,SELECTSTARTEDITX,
			SELECTSTARTEDITY(YSize),SELECTSTARTEDITWIDTH,SELECTSTARTEDITHEIGHT);
		SetTextEditPosition(Window->SelectionEndEdit,SELECTENDEDITX,
			SELECTENDEDITY(YSize),SELECTENDEDITWIDTH,SELECTENDEDITHEIGHT);
		SetTextEditPosition(Window->ScalingEdit,SCALINGEDITX,SCALINGEDITY(YSize),
			SCALINGEDITWIDTH,SCALINGEDITHEIGHT);
		SetTextEditPosition(Window->MousePositionEdit,MOUSEPOSEDITX,
			MOUSEPOSEDITY(YSize),MOUSEPOSEDITWIDTH,MOUSEPOSEDITHEIGHT);
		SetTextEditPosition(Window->SampleExpressionEdit,EXPRESSIONEDITX,
			EXPRESSIONEDITY(YSize),EXPRESSIONEDITWIDTH(XSize),EXPRESSIONEDITHEIGHT);
		SetScrollLocation(Window->Scrollbar,SAMPLEEDITX,SAMPLEEDITY
			+ SAMPLEEDITHEIGHT(YSize) - 16,SAMPLEEDITWIDTH(XSize));
		SetIconButtonLocation(Window->Bits8Button,BITS8X,BITS8Y(YSize));
		SetIconButtonLocation(Window->Bits16Button,BITS16X,BITS16Y(YSize));
		SetIconButtonLocation(Window->MonoButton,MONOX,MONOY(YSize));
		SetIconButtonLocation(Window->StereoButton,STEREOX,STEREOY(YSize));
		SetIconButtonLocation(Window->ZoomInButton,ZOOMINX,ZOOMINY(YSize));
		SetIconButtonLocation(Window->ZoomOutButton,ZOOMOUTX,ZOOMOUTY(YSize));
		SetIconButtonLocation(Window->PlayButton,PLAYX,PLAYY(YSize));
	}


/* helper function to set up the undo & present the user with a dialog */
/* asking if he wants to continue if undo information couldn't be saved. */
/* it returns True if the operation should continue. */
static MyBoolean		SampleWindowUndoSetupReturnTrueIfGoAhead(SampleWindowRec* Window)
	{
		CheckPtrExistence(Window);
		SampleWindowFinalizeCurrentEdit(Window);
		Window->UndoOrigin = SampleObjectGetOrigin(Window->SampleObject);
		Window->UndoLoopStart1 = SampleObjectGetLoopStart1(Window->SampleObject);
		Window->UndoLoopStart2 = SampleObjectGetLoopStart2(Window->SampleObject);
		Window->UndoLoopStart3 = SampleObjectGetLoopStart3(Window->SampleObject);
		Window->UndoLoopEnd1 = SampleObjectGetLoopEnd1(Window->SampleObject);
		Window->UndoLoopEnd2 = SampleObjectGetLoopEnd2(Window->SampleObject);
		Window->UndoLoopEnd3 = SampleObjectGetLoopEnd3(Window->SampleObject);
		if (!SampleViewSetupForUndo(Window->SampleView))
			{
				switch (AskYesNoCancel("There is not enough memory available to save undo "
					"information.  Do you want to continue anyway?",NIL,"Continue","Cancel",NIL))
					{
						default:
							EXECUTE(PRERR(ForceAbort,"SampleWindowUndoSetupReturnTrueIfGoAhead:  "
								"bad value from AskYesNoCancel"));
							break;
						case eYes:
							return True;
						case eNo:
							return False;
					}
			}
		return True;
	}


void								SampleWindowDoMouseDown(OrdType XLoc, OrdType YLoc,
											ModifierFlags Modifiers, SampleWindowRec* Window)
	{
		CheckPtrExistence(Window);
		if ((XLoc >= GetWindowWidth(Window->ScreenID) - 15)
			&& (XLoc <= GetWindowWidth(Window->ScreenID))
			&& (YLoc >= GetWindowHeight(Window->ScreenID) - 15)
			&& (YLoc <= GetWindowHeight(Window->ScreenID)))
			{
				UserGrowWindow(Window->ScreenID,XLoc,YLoc);
				SampleWindowJustResized(Window);
			}
		else if ((XLoc >= SAMPLEEDITX) && (YLoc >= SAMPLEEDITY)
			&& (XLoc < SAMPLEEDITX + SAMPLEEDITWIDTH(GetWindowWidth(Window->ScreenID)))
			&& (YLoc < SAMPLEEDITY + SAMPLEEDITHEIGHT(GetWindowHeight(Window->ScreenID))))
			{
				SampleWindowFinalizeCurrentEdit(Window);
				SampleWindowDoMouseDownInEdit(Window,XLoc,YLoc);
			}
		else if (TextEditHitTest(Window->SampleExpressionEdit,XLoc,YLoc))
			{
				if (Window->ActiveTextEdit != Window->SampleExpressionEdit)
					{
						SampleWindowFinalizeCurrentEdit(Window);
						Window->ActiveTextEdit = Window->SampleExpressionEdit;
						EnableTextEditSelection(Window->ActiveTextEdit);
					}
				TextEditDoMouseDown(Window->SampleExpressionEdit,XLoc,YLoc,Modifiers);
			}
		else if (TextEditHitTest(Window->NameEdit,XLoc,YLoc))
			{
				if (Window->ActiveTextEdit != Window->NameEdit)
					{
						SampleWindowFinalizeCurrentEdit(Window);
						Window->ActiveTextEdit = Window->NameEdit;
						EnableTextEditSelection(Window->ActiveTextEdit);
					}
				TextEditDoMouseDown(Window->NameEdit,XLoc,YLoc,Modifiers);
			}
		else if (TextEditHitTest(Window->SamplingRateEdit,XLoc,YLoc))
			{
				if (Window->ActiveTextEdit != Window->SamplingRateEdit)
					{
						SampleWindowFinalizeCurrentEdit(Window);
						Window->ActiveTextEdit = Window->SamplingRateEdit;
						EnableTextEditSelection(Window->ActiveTextEdit);
					}
				TextEditDoMouseDown(Window->SamplingRateEdit,XLoc,YLoc,Modifiers);
			}
		else if (TextEditHitTest(Window->OriginEdit,XLoc,YLoc))
			{
				if (Window->ActiveTextEdit != Window->OriginEdit)
					{
						SampleWindowFinalizeCurrentEdit(Window);
						Window->ActiveTextEdit = Window->OriginEdit;
						EnableTextEditSelection(Window->ActiveTextEdit);
					}
				TextEditDoMouseDown(Window->OriginEdit,XLoc,YLoc,Modifiers);
			}
		else if (TextEditHitTest(Window->NaturalFrequencyEdit,XLoc,YLoc))
			{
				if (Window->ActiveTextEdit != Window->NaturalFrequencyEdit)
					{
						SampleWindowFinalizeCurrentEdit(Window);
						Window->ActiveTextEdit = Window->NaturalFrequencyEdit;
						EnableTextEditSelection(Window->ActiveTextEdit);
					}
				TextEditDoMouseDown(Window->NaturalFrequencyEdit,XLoc,YLoc,Modifiers);
			}
		else if (TextEditHitTest(Window->LoopStartEdit,XLoc,YLoc))
			{
				if (Window->ActiveTextEdit != Window->LoopStartEdit)
					{
						SampleWindowFinalizeCurrentEdit(Window);
						Window->ActiveTextEdit = Window->LoopStartEdit;
						EnableTextEditSelection(Window->ActiveTextEdit);
					}
				TextEditDoMouseDown(Window->LoopStartEdit,XLoc,YLoc,Modifiers);
			}
		else if (TextEditHitTest(Window->LoopEndEdit,XLoc,YLoc))
			{
				if (Window->ActiveTextEdit != Window->LoopEndEdit)
					{
						SampleWindowFinalizeCurrentEdit(Window);
						Window->ActiveTextEdit = Window->LoopEndEdit;
						EnableTextEditSelection(Window->ActiveTextEdit);
					}
				TextEditDoMouseDown(Window->LoopEndEdit,XLoc,YLoc,Modifiers);
			}
		else if (TextEditHitTest(Window->SelectionStartEdit,XLoc,YLoc))
			{
				if (Window->ActiveTextEdit != Window->SelectionStartEdit)
					{
						SampleWindowFinalizeCurrentEdit(Window);
						Window->ActiveTextEdit = Window->SelectionStartEdit;
						EnableTextEditSelection(Window->ActiveTextEdit);
					}
				TextEditDoMouseDown(Window->SelectionStartEdit,XLoc,YLoc,Modifiers);
			}
		else if (TextEditHitTest(Window->SelectionEndEdit,XLoc,YLoc))
			{
				if (Window->ActiveTextEdit != Window->SelectionEndEdit)
					{
						SampleWindowFinalizeCurrentEdit(Window);
						Window->ActiveTextEdit = Window->SelectionEndEdit;
						EnableTextEditSelection(Window->ActiveTextEdit);
					}
				TextEditDoMouseDown(Window->SelectionEndEdit,XLoc,YLoc,Modifiers);
			}
		else if (TextEditHitTest(Window->ScalingEdit,XLoc,YLoc))
			{
				if (Window->ActiveTextEdit != Window->ScalingEdit)
					{
						SampleWindowFinalizeCurrentEdit(Window);
						Window->ActiveTextEdit = Window->ScalingEdit;
						EnableTextEditSelection(Window->ActiveTextEdit);
					}
				TextEditDoMouseDown(Window->ScalingEdit,XLoc,YLoc,Modifiers);
			}
		else if (IconButtonHitTest(Window->Bits8Button,XLoc,YLoc))
			{
				if (IconButtonMouseDown(Window->Bits8Button,XLoc,YLoc,NIL,NIL))
					{
						if (SampleWindowUndoSetupReturnTrueIfGoAhead(Window))
							{
								if (!SetSampleViewNumBits(Window->SampleView,eSample8bit))
									{
										AlertHalt("There is not enough memory available to convert the "
											"sample to 8-bit format.",NIL);
									}
								 else
									{
										SetIconButtonState(Window->Bits16Button,False);
									}
								SampleWindowRedrawThangs(Window);
							}
					}
			}
		else if (IconButtonHitTest(Window->Bits16Button,XLoc,YLoc))
			{
				if (IconButtonMouseDown(Window->Bits16Button,XLoc,YLoc,NIL,NIL))
					{
						if (SampleWindowUndoSetupReturnTrueIfGoAhead(Window))
							{
								if (!SetSampleViewNumBits(Window->SampleView,eSample16bit))
									{
										AlertHalt("There is not enough memory available to convert the "
											"sample to 16-bit format.",NIL);
									}
								 else
									{
										SetIconButtonState(Window->Bits8Button,False);
									}
								SampleWindowRedrawThangs(Window);
							}
					}
			}
		else if (IconButtonHitTest(Window->MonoButton,XLoc,YLoc))
			{
				if (IconButtonMouseDown(Window->MonoButton,XLoc,YLoc,NIL,NIL))
					{
						if (SampleWindowUndoSetupReturnTrueIfGoAhead(Window))
							{
								if (!SetSampleViewNumChannels(Window->SampleView,eSampleMono))
									{
										AlertHalt("There is not enough memory available to convert the "
											"sample to mono format.",NIL);
									}
								 else
									{
										SetIconButtonState(Window->StereoButton,False);
									}
								SampleWindowRedrawThangs(Window);
							}
					}
			}
		else if (IconButtonHitTest(Window->StereoButton,XLoc,YLoc))
			{
				if (IconButtonMouseDown(Window->StereoButton,XLoc,YLoc,NIL,NIL))
					{
						if (SampleWindowUndoSetupReturnTrueIfGoAhead(Window))
							{
								if (!SetSampleViewNumChannels(Window->SampleView,eSampleStereo))
									{
										AlertHalt("There is not enough memory available to convert the "
											"sample to stereo format.",NIL);
									}
								 else
									{
										SetIconButtonState(Window->MonoButton,False);
									}
								SampleWindowRedrawThangs(Window);
							}
					}
			}
		else if (IconButtonHitTest(Window->ZoomInButton,XLoc,YLoc))
			{
				if (IconButtonMouseDown(Window->ZoomInButton,XLoc,YLoc,NIL,NIL))
					{
						double					NewValue;

						NewValue = GetSampleViewHorizontalScale(Window->SampleView) / ZOOMFACTOR;
						if (NewValue < MINIMUMHORIZSCALE)
							{
								NewValue = MINIMUMHORIZSCALE;
							}
						SetSampleViewHorizontalScale(Window->SampleView,NewValue);
						SampleWindowRedrawThangs(Window);
						SampleWindowPutScalingFactor(Window);
						UpdateSampleWindowScrollbar(Window);
					}
			}
		else if (IconButtonHitTest(Window->ZoomOutButton,XLoc,YLoc))
			{
				if (IconButtonMouseDown(Window->ZoomOutButton,XLoc,YLoc,NIL,NIL))
					{
						double					NewValue;

						NewValue = GetSampleViewHorizontalScale(Window->SampleView) * ZOOMFACTOR;
						SetSampleViewHorizontalScale(Window->SampleView,NewValue);
						SampleWindowRedrawThangs(Window);
						SampleWindowPutScalingFactor(Window);
						UpdateSampleWindowScrollbar(Window);
					}
			}
		else if (IconButtonHitTest(Window->PlayButton,XLoc,YLoc))
			{
				SampleTestRec*			TestPlayer;

				TestPlayer = NewSampleTestPlayer(Window);
				if (TestPlayer != NIL)
					{
						IconButtonMouseDown(Window->PlayButton,XLoc,YLoc,
							(void (*)(void*, MyBoolean))&SampleTestPlayCallback,TestPlayer);
						FinishAndDisposeSampleTestPlayer(TestPlayer);
					}
				 else
					{
						AlertHalt("There is not enough memory available to play the sample.",NIL);
					}
			}
		else
			{
				/* finalize edit for click outside any known area */
				SampleWindowFinalizeCurrentEdit(Window);
			}
	}


void								SampleWindowDoKeyDown(unsigned char KeyCode,
											ModifierFlags Modifiers,SampleWindowRec* Window)
	{
		CheckPtrExistence(Window);
		if ((KeyCode == 13) && (Window->ActiveTextEdit != Window->SampleExpressionEdit))
			{
				SampleWindowFinalizeCurrentEdit(Window);
			}
		else if ((KeyCode == 9) && (Window->ActiveTextEdit != Window->SampleExpressionEdit))
			{
				TextEditRec*			WasTheActiveTextEdit;

				WasTheActiveTextEdit = Window->ActiveTextEdit;
				SampleWindowFinalizeCurrentEdit(Window);
				if ((Modifiers & eShiftKey) != 0)
					{
						if (WasTheActiveTextEdit == Window->ScalingEdit)
							{
								Window->ActiveTextEdit = Window->SelectionEndEdit;
							}
						else if (WasTheActiveTextEdit == Window->SelectionEndEdit)
							{
								Window->ActiveTextEdit = Window->SelectionStartEdit;
							}
						else if (WasTheActiveTextEdit == Window->SelectionEndEdit)
							{
								Window->ActiveTextEdit = Window->SelectionStartEdit;
							}
						else if (WasTheActiveTextEdit == Window->SelectionStartEdit)
							{
								Window->ActiveTextEdit = Window->LoopEndEdit;
							}
						else if (WasTheActiveTextEdit == Window->LoopEndEdit)
							{
								Window->ActiveTextEdit = Window->LoopStartEdit;
							}
						else if (WasTheActiveTextEdit == Window->LoopStartEdit)
							{
								Window->ActiveTextEdit = Window->NaturalFrequencyEdit;
							}
						else if (WasTheActiveTextEdit == Window->NaturalFrequencyEdit)
							{
								Window->ActiveTextEdit = Window->OriginEdit;
							}
						else if (WasTheActiveTextEdit == Window->OriginEdit)
							{
								Window->ActiveTextEdit = Window->SamplingRateEdit;
							}
						else if (WasTheActiveTextEdit == Window->SamplingRateEdit)
							{
								Window->ActiveTextEdit = Window->NameEdit;
							}
						else
							{
								Window->ActiveTextEdit = Window->ScalingEdit;
							}
					}
				 else
					{
						if (WasTheActiveTextEdit == Window->NameEdit)
							{
								Window->ActiveTextEdit = Window->SamplingRateEdit;
							}
						else if (WasTheActiveTextEdit == Window->SamplingRateEdit)
							{
								Window->ActiveTextEdit = Window->OriginEdit;
							}
						else if (WasTheActiveTextEdit == Window->OriginEdit)
							{
								Window->ActiveTextEdit = Window->NaturalFrequencyEdit;
							}
						else if (WasTheActiveTextEdit == Window->NaturalFrequencyEdit)
							{
								Window->ActiveTextEdit = Window->LoopStartEdit;
							}
						else if (WasTheActiveTextEdit == Window->LoopStartEdit)
							{
								Window->ActiveTextEdit = Window->LoopEndEdit;
							}
						else if (WasTheActiveTextEdit == Window->LoopEndEdit)
							{
								Window->ActiveTextEdit = Window->SelectionStartEdit;
							}
						else if (WasTheActiveTextEdit == Window->SelectionStartEdit)
							{
								Window->ActiveTextEdit = Window->SelectionEndEdit;
							}
						else if (WasTheActiveTextEdit == Window->SelectionEndEdit)
							{
								Window->ActiveTextEdit = Window->ScalingEdit;
							}
						else
							{
								Window->ActiveTextEdit = Window->NameEdit;
							}
					}
				EnableTextEditSelection(Window->ActiveTextEdit);
				TextEditDoMenuSelectAll(Window->ActiveTextEdit);
			}
		else if ((KeyCode == 8) && (Window->ActiveTextEdit == NIL))
			{
				/* for delete key with no text box open, delete any selected range */
				/* of the sample.  since ActiveTextEdit == NIL, this will be sent */
				/* to the appropriate handler.  however, we must make sure there is */
				/* a valid selection first, since SampleWindowMenuSetup usually does that. */
				if (SampleViewIsThereValidSelection(Window->SampleView))
					{
						SampleWindowDoMenuCommand(Window,mClear);
					}
			}
		else
			{
				if (Window->ActiveTextEdit != NIL)
					{
						TextEditDoKeyPressed(Window->ActiveTextEdit,KeyCode,Modifiers);
					}
			}
	}


void								SampleWindowClose(SampleWindowRec* Window)
	{
		CheckPtrExistence(Window);
		DisposeSampleWindow(Window);
	}


void								SampleWindowUpdator(SampleWindowRec* Window)
	{
		OrdType						Height;
		OrdType						Width;
		FontType					ScreenFont;

		CheckPtrExistence(Window);

		Width = GetWindowWidth(Window->ScreenID);
		Height = GetWindowHeight(Window->ScreenID);
		ScreenFont = GetScreenFont();

		/* redraw edit boxes */
		RedrawSampleView(Window->SampleView);
		SampleWindowRedrawThangs(Window);
		TextEditFullRedraw(Window->NameEdit);
		TextEditFullRedraw(Window->SamplingRateEdit);
		TextEditFullRedraw(Window->OriginEdit);
		TextEditFullRedraw(Window->NaturalFrequencyEdit);
		TextEditFullRedraw(Window->LoopStartEdit);
		TextEditFullRedraw(Window->LoopEndEdit);
		TextEditFullRedraw(Window->SelectionStartEdit);
		TextEditFullRedraw(Window->SelectionEndEdit);
		TextEditFullRedraw(Window->ScalingEdit);
		TextEditFullRedraw(Window->MousePositionEdit);
		TextEditFullRedraw(Window->SampleExpressionEdit);
		RedrawScrollBar(Window->Scrollbar);
		RedrawIconButton(Window->Bits8Button);
		RedrawIconButton(Window->Bits16Button);
		RedrawIconButton(Window->MonoButton);
		RedrawIconButton(Window->StereoButton);
		RedrawIconButton(Window->ZoomInButton);
		RedrawIconButton(Window->ZoomOutButton);
		RedrawIconButton(Window->PlayButton);

		/* redraw static titles */
		SetClipRect(Window->ScreenID,0,0,Width,Height);
		DrawTextLine(Window->ScreenID,ScreenFont,9,"Sample Name:",12,
			SAMPLENAMEX,SAMPLENAMEY,ePlain);
		DrawTextLine(Window->ScreenID,ScreenFont,9,"Sampling Rate:",14,
			SAMPLERATEX,SAMPLERATEY,ePlain);
		DrawTextLine(Window->ScreenID,ScreenFont,9,"Origin:",7,ORIGINX,ORIGINY,ePlain);
		DrawTextLine(Window->ScreenID,ScreenFont,9,"Natural Freq:",13,
			BASEFREQX,BASEFREQY,ePlain);
		switch (Window->EditingWhichLoop)
			{
				default:
					EXECUTE(PRERR(ForceAbort,"SampleWindowUpdator:  bad value in EditingWhichLoop"));
					break;
				case eSampleLoop1:
					DrawTextLine(Window->ScreenID,ScreenFont,9,"Loop Start 1:",13,
						LOOPSTARTX,LOOPSTARTY,ePlain);
					break;
				case eSampleLoop2:
					DrawTextLine(Window->ScreenID,ScreenFont,9,"Loop Start 2:",13,
						LOOPSTARTX,LOOPSTARTY,ePlain);
					break;
				case eSampleLoop3:
					DrawTextLine(Window->ScreenID,ScreenFont,9,"Loop Start 3:",13,
						LOOPSTARTX,LOOPSTARTY,ePlain);
					break;
			}
		switch (Window->EditingWhichLoop)
			{
				default:
					EXECUTE(PRERR(ForceAbort,"SampleWindowUpdator:  bad value in EditingWhichLoop"));
					break;
				case eSampleLoop1:
					DrawTextLine(Window->ScreenID,ScreenFont,9,"Loop End 1:",11,
						LOOPENDX,LOOPENDY,ePlain);
					break;
				case eSampleLoop2:
					DrawTextLine(Window->ScreenID,ScreenFont,9,"Loop End 2:",11,
						LOOPENDX,LOOPENDY,ePlain);
					break;
				case eSampleLoop3:
					DrawTextLine(Window->ScreenID,ScreenFont,9,"Loop End 3:",11,
						LOOPENDX,LOOPENDY,ePlain);
					break;
			}
		DrawTextLine(Window->ScreenID,ScreenFont,9,"Select Start:",13,
			SELECTSTARTX,SELECTSTARTY(Height),ePlain);
		DrawTextLine(Window->ScreenID,ScreenFont,9,"Select End:",11,
			SELECTENDX,SELECTENDY(Height),ePlain);
		DrawTextLine(Window->ScreenID,ScreenFont,9,"Mouse Location:",15,
			MOUSELOCX,MOUSELOCY(Height),ePlain);
		DrawTextLine(Window->ScreenID,ScreenFont,9,"Scaling Factor:",15,
			SCALINGX,SCALINGY(Height),ePlain);

		/* grow icon */
		SetClipRect(Window->ScreenID,Width - 15,Height - 15,Width,Height);
		DrawBitmap(Window->ScreenID,Width - 15,Height - 15,
			GetGrowIcon(Window->MyGenericWindow == GetCurrentWindowID()));
	}


void								SampleWindowMenuSetup(SampleWindowRec* Window)
	{
		CheckPtrExistence(Window);
		MainWindowEnableGlobalMenus(Window->MainWindow);

		if (Window->ActiveTextEdit != NIL)
			{
				/* editing text, enable menu items for text entry */
				EnableMenuItem(mPaste);
				ChangeItemName(mPaste,"Paste Text");
				if (TextEditIsThereValidSelection(Window->ActiveTextEdit))
					{
						EnableMenuItem(mCut);
						ChangeItemName(mCut,"Cut Text");
						EnableMenuItem(mCopy);
						ChangeItemName(mCopy,"Copy Text");
						EnableMenuItem(mClear);
						ChangeItemName(mClear,"Clear Text");
					}
				EnableMenuItem(mSelectAll);
				ChangeItemName(mSelectAll,"Select All Text");
				if (TextEditCanWeUndo(Window->ActiveTextEdit))
					{
						EnableMenuItem(mUndo);
						ChangeItemName(mUndo,"Undo Text Change");
					}
				EnableMenuItem(mShiftLeft);
				EnableMenuItem(mShiftRight);
				EnableMenuItem(mBalanceParens);
				EnableMenuItem(mFind);
				if (PtrSize(GlobalSearchString) != 0)
					{
						EnableMenuItem(mFindAgain);
						if (TextEditIsThereValidSelection(Window->ActiveTextEdit))
							{
								EnableMenuItem(mReplace);
								EnableMenuItem(mReplaceAndFindAgain);
							}
					}
				if (TextEditIsThereValidSelection(Window->ActiveTextEdit))
					{
						EnableMenuItem(mEnterSelection);
					}
				EnableMenuItem(mShowSelection);
			}
		 else
			{
				/* editing the sample */
				EnableMenuItem(mPaste);
				ChangeItemName(mPaste,"Paste Sample");
				if (SampleViewIsThereValidSelection(Window->SampleView))
					{
						EnableMenuItem(mCut);
						ChangeItemName(mCut,"Cut Sample");
						EnableMenuItem(mCopy);
						ChangeItemName(mCopy,"Copy Sample");
						EnableMenuItem(mClear);
						ChangeItemName(mClear,"Clear Sample");
					}
				EnableMenuItem(mSelectAll);
				ChangeItemName(mSelectAll,"Select All Sample");
				if (SampleViewUndoAvailable(Window->SampleView))
					{
						EnableMenuItem(mUndo);
						ChangeItemName(mUndo,"Undo Sample Edit");
					}
			}

		EnableMenuItem(mCloseFile);
		ChangeItemName(mCloseFile,"Close Sample Editor");
		EnableMenuItem(mEvaluateCalc);
		ChangeItemName(mDeleteObject,"Delete Sample");
		EnableMenuItem(mDeleteObject);

		EnableMenuItem(mSampleEditLoop1);
		EnableMenuItem(mSampleEditLoop2);
		EnableMenuItem(mSampleEditLoop3);
		switch (Window->EditingWhichLoop)
			{
				default:
					EXECUTE(PRERR(ForceAbort,
						"SampleWindowMenuSetup:  bad value in EditingWhichLoop"));
					break;
				case eSampleLoop1:
					SetItemCheckmark(mSampleEditLoop1);
					break;
				case eSampleLoop2:
					SetItemCheckmark(mSampleEditLoop2);
					break;
				case eSampleLoop3:
					SetItemCheckmark(mSampleEditLoop3);
					break;
			}

		EnableMenuItem(mExportWAVFormat);
		EnableMenuItem(mExportRAWFormat);
		EnableMenuItem(mExportAIFFFormat);

		SetItemCheckmark(Window->MyMenuItem);
	}


void								SampleWindowDoMenuCommand(SampleWindowRec* Window,
											MenuItemType* MenuItem)
	{
		CheckPtrExistence(Window);
		if (MainWindowDoGlobalMenuItem(Window->MainWindow,MenuItem))
			{
			}
		else if (MenuItem == mPaste)
			{
				if (Window->ActiveTextEdit != NIL)
					{
						TextEditDoMenuPaste(Window->ActiveTextEdit);
					}
				 else
					{
						long												SelectStart;
						long												SelectEnd;
						SampleStorageDisplayRec*		ClipboardData;
						long												NetInsertedFrames;

						/* paste sample */
						if (!SampleWindowUndoSetupReturnTrueIfGoAhead(Window))
							{
								/* set up undo; ask user whether to continue if not saved ya? */
								return;
							}
						ClipboardData = GetSampleStorageDisplayFromClipboard();
						if (ClipboardData == NIL)
							{
							 PasteFailurePoint1:
								return;
							}
						SelectStart = GetSampleViewSelectStart(Window->SampleView);
						SelectEnd = GetSampleViewSelectEnd(Window->SampleView);
						NetInsertedFrames = - (SelectEnd - SelectStart);
						if (!DeleteSampleViewArea(Window->SampleView,SelectStart,
							SelectEnd - SelectStart))
							{
							 PasteFailurePoint2:
								DisposeSampleStorageDisplay(ClipboardData);
								goto PasteFailurePoint1;
							}
						if (!InsertSampleViewSection(Window->SampleView,SelectStart,ClipboardData))
							{
							 PasteFailurePoint3:
								goto PasteFailurePoint2;
							}
						NetInsertedFrames += GetSampleStorageDisplayNumFrames(ClipboardData);
						DisposeSampleStorageDisplay(ClipboardData);
						UpdateSampleWindowScrollbar(Window);
						SampleWindowRedrawUnderThangs(Window);
						SampleWindowShiftPoints(Window,SelectStart,NetInsertedFrames);
						AdjustSampleWindowThangs(Window);
						SampleWindowRedrawThangs(Window);
						SampleWindowPutSelectStart(Window);
						SampleWindowPutSelectEnd(Window);
					}
			}
		else if (MenuItem == mCut)
			{
				if (Window->ActiveTextEdit != NIL)
					{
						TextEditDoMenuCut(Window->ActiveTextEdit);
					}
				 else
					{
						SampleStorageDisplayRec*		DeletedData;
						long												SelectStart;
						long												SelectEnd;
						long												NetInsertedFrames;

						/* sample cut */
						if (!SampleWindowUndoSetupReturnTrueIfGoAhead(Window))
							{
								/* set up undo; ask user whether to continue if not saved ya? */
								return;
							}
						SelectStart = GetSampleViewSelectStart(Window->SampleView);
						SelectEnd = GetSampleViewSelectEnd(Window->SampleView);
						NetInsertedFrames = - (SelectEnd - SelectStart);
						DeletedData = ExtractSampleViewSection(Window->SampleView,SelectStart,
							SelectEnd - SelectStart);
						if (DeletedData == NIL)
							{
							 CutSampleFailurePoint:
								AlertHalt("There is not enough memory available to "
									"complete the cut operation.",NIL);
								return;
							}
						PutSampleStorageDisplayOnClipboard(DeletedData); /* put it on the clipboard */
						DisposeSampleStorageDisplay(DeletedData);
						if (!DeleteSampleViewArea(Window->SampleView,SelectStart,
							SelectEnd - SelectStart))
							{
								goto CutSampleFailurePoint;
							}
						UpdateSampleWindowScrollbar(Window);
						SampleWindowRedrawUnderThangs(Window);
						SampleWindowShiftPoints(Window,SelectStart,NetInsertedFrames);
						AdjustSampleWindowThangs(Window);
						SampleWindowRedrawThangs(Window);
						SampleWindowPutSelectStart(Window);
						SampleWindowPutSelectEnd(Window);
					}
			}
		else if (MenuItem == mCopy)
			{
				if (Window->ActiveTextEdit != NIL)
					{
						TextEditDoMenuCopy(Window->ActiveTextEdit);
					}
				 else
					{
						SampleStorageDisplayRec*		CopiedData;
						long												SelectStart;
						long												SelectEnd;

						SelectStart = GetSampleViewSelectStart(Window->SampleView);
						SelectEnd = GetSampleViewSelectEnd(Window->SampleView);
						CopiedData = ExtractSampleViewSection(Window->SampleView,SelectStart,
							SelectEnd - SelectStart);
						if (CopiedData == NIL)
							{
								AlertHalt("There is not enough memory available to "
									"complete the copy operation.",NIL);
								return;
							}
						PutSampleStorageDisplayOnClipboard(CopiedData); /* put it on the clipboard */
						DisposeSampleStorageDisplay(CopiedData);
					}
			}
		else if (MenuItem == mClear)
			{
				if (Window->ActiveTextEdit != NIL)
					{
						TextEditDoMenuClear(Window->ActiveTextEdit);
					}
				 else
					{
						long								SelectStart;
						long								SelectEnd;
						long								NetInsertedFrames;

						/* sample delete */
						if (!SampleWindowUndoSetupReturnTrueIfGoAhead(Window))
							{
								/* set up undo; ask user whether to continue if not saved ya? */
								return;
							}
						SelectStart = GetSampleViewSelectStart(Window->SampleView);
						SelectEnd = GetSampleViewSelectEnd(Window->SampleView);
						NetInsertedFrames = - (SelectEnd - SelectStart);
						if (!DeleteSampleViewArea(Window->SampleView,SelectStart,
							SelectEnd - SelectStart))
							{
								AlertHalt("There is not enough memory available to "
									"complete the clear operation.",NIL);
								return;
							}
						UpdateSampleWindowScrollbar(Window);
						SampleWindowRedrawUnderThangs(Window);
						SampleWindowShiftPoints(Window,SelectStart,NetInsertedFrames);
						AdjustSampleWindowThangs(Window);
						SampleWindowRedrawThangs(Window);
						SampleWindowPutSelectStart(Window);
						SampleWindowPutSelectEnd(Window);
					}
			}
		else if (MenuItem == mSelectAll)
			{
				if (Window->ActiveTextEdit != NIL)
					{
						TextEditDoMenuSelectAll(Window->ActiveTextEdit);
					}
				 else
					{
						SetSampleViewSelection(Window->SampleView,0,
							GetSampleViewNumFrames(Window->SampleView));
						SampleWindowPutSelectStart(Window);
						SampleWindowPutSelectEnd(Window);
					}
			}
		else if (MenuItem == mShowSelection)
			{
				if (Window->ActiveTextEdit != NIL)
					{
						TextEditShowSelection(Window->ActiveTextEdit);
					}
				 else
					{
					}
			}
		else if (MenuItem == mUndo)
			{
				if (Window->ActiveTextEdit != NIL)
					{
						/* this is the one for text editing */
						TextEditDoMenuUndo(Window->ActiveTextEdit);
					}
				 else
					{
						/* this is the one for samples */
						SampleWindowFinalizeCurrentEdit(Window);
						if (!SampleViewUndo(Window->SampleView))
							{
								AlertHalt("There was not enough memory available to undo the sample "
									"edit.  Try closing some other windows to free up memory.",NIL);
							}
						switch (GetSampleViewNumChannels(Window->SampleView))
							{
								case eSampleMono:
									SetIconButtonState(Window->MonoButton,True);
									SetIconButtonState(Window->StereoButton,False);
									break;
								case eSampleStereo:
									SetIconButtonState(Window->MonoButton,False);
									SetIconButtonState(Window->StereoButton,True);
									break;
								default:
									EXECUTE(PRERR(ForceAbort,
										"SampleWindowDoMenuCommand:  bad num channels value"));
									break;
							}
						switch (GetSampleViewNumBits(Window->SampleView))
							{
								case eSample8bit:
									SetIconButtonState(Window->Bits8Button,True);
									SetIconButtonState(Window->Bits16Button,False);
									break;
								case eSample16bit:
									SetIconButtonState(Window->Bits8Button,False);
									SetIconButtonState(Window->Bits16Button,True);
									break;
								default:
									EXECUTE(PRERR(ForceAbort,
										"SampleWindowDoMenuCommand:  bad number of bits value"));
									break;
							}
						/* restore some crud */
						SampleObjectPutOrigin(Window->SampleObject,Window->UndoOrigin);
						SampleObjectPutLoopStart1(Window->SampleObject,Window->UndoLoopStart1);
						SampleObjectPutLoopStart2(Window->SampleObject,Window->UndoLoopStart2);
						SampleObjectPutLoopStart3(Window->SampleObject,Window->UndoLoopStart3);
						SampleObjectPutLoopEnd1(Window->SampleObject,Window->UndoLoopEnd1);
						SampleObjectPutLoopEnd2(Window->SampleObject,Window->UndoLoopEnd2);
						SampleObjectPutLoopEnd3(Window->SampleObject,Window->UndoLoopEnd3);
						/* fix up edit versions */
						SampleWindowPutOrigin(Window,Window->UndoOrigin);
						switch (Window->EditingWhichLoop)
							{
								default:
									EXECUTE(PRERR(ForceAbort,
										"SampleWindowDoMenuCommand:  bad value in EditingWhichLoop"));
									break;
								case eSampleLoop1:
									SampleWindowPutLoopStart(Window,Window->UndoLoopStart1);
									SampleWindowPutLoopEnd(Window,Window->UndoLoopEnd1);
									break;
								case eSampleLoop2:
									SampleWindowPutLoopStart(Window,Window->UndoLoopStart2);
									SampleWindowPutLoopEnd(Window,Window->UndoLoopEnd2);
									break;
								case eSampleLoop3:
									SampleWindowPutLoopStart(Window,Window->UndoLoopStart3);
									SampleWindowPutLoopEnd(Window,Window->UndoLoopEnd3);
									break;
							}
					}
			}
		else if (MenuItem == mCloseFile)
			{
				SampleWindowClose(Window);
			}
		else if (MenuItem == mEvaluateCalc)
			{
				if (!SampleWindowUndoSetupReturnTrueIfGoAhead(Window))
					{
						/* set up undo; ask user whether to continue if not saved ya? */
						return;
					}
				if (Window->ActiveTextEdit != Window->SampleExpressionEdit)
					{
						SampleWindowFinalizeCurrentEdit(Window);
					}
				SampleWindowPerformCalculation(Window);
			}
		else if (MenuItem == mShiftLeft)
			{
				TextEditShiftSelectionLeftOneTab(Window->ActiveTextEdit);
			}
		else if (MenuItem == mShiftRight)
			{
				TextEditShiftSelectionRightOneTab(Window->ActiveTextEdit);
			}
		else if (MenuItem == mBalanceParens)
			{
				TextEditBalanceParens(Window->ActiveTextEdit);
			}
		else if (MenuItem == mDeleteObject)
			{
				SampleListDeleteSample(Window->SampleList,Window->SampleObject);
			}
		else if (MenuItem == mSampleEditLoop1)
			{
				OrdType						XSize;
				OrdType						YSize;

				SampleWindowFinalizeCurrentEdit(Window);
				switch (Window->EditingWhichLoop)
					{
						default:
							EXECUTE(PRERR(ForceAbort,
								"SampleWindowDoMenuCommand:  bad value in EditingWhichLoop"));
							break;
						case eSampleLoop1:
							/* switch from 1 to 1 -- no change */
							break;
						case eSampleLoop2:
							/* put away 2 */
							SampleObjectPutLoopStart2(Window->SampleObject,
								SampleWindowGetLoopStart(Window));
							SampleObjectPutLoopEnd2(Window->SampleObject,
								SampleWindowGetLoopEnd(Window));
							/* load 1 */
							SampleWindowPutLoopStart(Window,
								SampleObjectGetLoopStart1(Window->SampleObject));
							SampleWindowPutLoopEnd(Window,
								SampleObjectGetLoopEnd1(Window->SampleObject));
							break;
						case eSampleLoop3:
							/* put away 3 */
							SampleObjectPutLoopStart3(Window->SampleObject,
								SampleWindowGetLoopStart(Window));
							SampleObjectPutLoopEnd3(Window->SampleObject,
								SampleWindowGetLoopEnd(Window));
							/* load 1 */
							SampleWindowPutLoopStart(Window,
								SampleObjectGetLoopStart1(Window->SampleObject));
							SampleWindowPutLoopEnd(Window,
								SampleObjectGetLoopEnd1(Window->SampleObject));
							break;
					}
				Window->EditingWhichLoop = eSampleLoop1;
				XSize = GetWindowWidth(Window->ScreenID);
				YSize = GetWindowHeight(Window->ScreenID);
				SetClipRect(Window->ScreenID,0,0,XSize,YSize);
				DrawBoxErase(Window->ScreenID,0,0,XSize,YSize);
				SampleWindowUpdator(Window);
			}
		else if (MenuItem == mSampleEditLoop2)
			{
				OrdType						XSize;
				OrdType						YSize;

				SampleWindowFinalizeCurrentEdit(Window);
				switch (Window->EditingWhichLoop)
					{
						default:
							EXECUTE(PRERR(ForceAbort,
								"SampleWindowDoMenuCommand:  bad value in EditingWhichLoop"));
							break;
						case eSampleLoop1:
							/* put away 1 */
							SampleObjectPutLoopStart1(Window->SampleObject,
								SampleWindowGetLoopStart(Window));
							SampleObjectPutLoopEnd1(Window->SampleObject,
								SampleWindowGetLoopEnd(Window));
							/* load 2 */
							SampleWindowPutLoopStart(Window,
								SampleObjectGetLoopStart2(Window->SampleObject));
							SampleWindowPutLoopEnd(Window,
								SampleObjectGetLoopEnd2(Window->SampleObject));
							break;
						case eSampleLoop2:
							/* switch from 2 to 2 -- no change */
							break;
						case eSampleLoop3:
							/* put away 3 */
							SampleObjectPutLoopStart3(Window->SampleObject,
								SampleWindowGetLoopStart(Window));
							SampleObjectPutLoopEnd3(Window->SampleObject,
								SampleWindowGetLoopEnd(Window));
							/* load 2 */
							SampleWindowPutLoopStart(Window,
								SampleObjectGetLoopStart2(Window->SampleObject));
							SampleWindowPutLoopEnd(Window,
								SampleObjectGetLoopEnd2(Window->SampleObject));
							break;
					}
				Window->EditingWhichLoop = eSampleLoop2;
				XSize = GetWindowWidth(Window->ScreenID);
				YSize = GetWindowHeight(Window->ScreenID);
				SetClipRect(Window->ScreenID,0,0,XSize,YSize);
				DrawBoxErase(Window->ScreenID,0,0,XSize,YSize);
				SampleWindowUpdator(Window);
			}
		else if (MenuItem == mSampleEditLoop3)
			{
				OrdType						XSize;
				OrdType						YSize;

				SampleWindowFinalizeCurrentEdit(Window);
				switch (Window->EditingWhichLoop)
					{
						default:
							EXECUTE(PRERR(ForceAbort,
								"SampleWindowDoMenuCommand:  bad value in EditingWhichLoop"));
							break;
						case eSampleLoop1:
							/* put away 1 */
							SampleObjectPutLoopStart1(Window->SampleObject,
								SampleWindowGetLoopStart(Window));
							SampleObjectPutLoopEnd1(Window->SampleObject,
								SampleWindowGetLoopEnd(Window));
							/* load 3 */
							SampleWindowPutLoopStart(Window,
								SampleObjectGetLoopStart3(Window->SampleObject));
							SampleWindowPutLoopEnd(Window,
								SampleObjectGetLoopEnd3(Window->SampleObject));
							break;
						case eSampleLoop2:
							/* put away 2 */
							SampleObjectPutLoopStart2(Window->SampleObject,
								SampleWindowGetLoopStart(Window));
							SampleObjectPutLoopEnd2(Window->SampleObject,
								SampleWindowGetLoopEnd(Window));
							/* load 3 */
							SampleWindowPutLoopStart(Window,
								SampleObjectGetLoopStart3(Window->SampleObject));
							SampleWindowPutLoopEnd(Window,
								SampleObjectGetLoopEnd3(Window->SampleObject));
							break;
						case eSampleLoop3:
							/* switch from 3 to 3 -- no change */
							break;
					}
				Window->EditingWhichLoop = eSampleLoop3;
				XSize = GetWindowWidth(Window->ScreenID);
				YSize = GetWindowHeight(Window->ScreenID);
				SetClipRect(Window->ScreenID,0,0,XSize,YSize);
				DrawBoxErase(Window->ScreenID,0,0,XSize,YSize);
				SampleWindowUpdator(Window);
			}
		else if (MenuItem == mFind)
			{
				if (Window->ActiveTextEdit != Window->SampleExpressionEdit)
					{
						SampleWindowFinalizeCurrentEdit(Window);
						Window->ActiveTextEdit = Window->SampleExpressionEdit;
						EnableTextEditSelection(Window->ActiveTextEdit);
					}
				switch (DoFindDialog(&GlobalSearchString,&GlobalReplaceString,
					mCut,mPaste,mCopy,mUndo,mSelectAll,mClear))
					{
						default:
							EXECUTE(PRERR(ForceAbort,
								"SampleWindowDoMenuCommand:  bad value from DoFindDialog"));
							break;
						case eFindCancel:
						case eDontFind:
							break;
						case eFindFromStart:
							SetTextEditInsertionPoint(Window->ActiveTextEdit,0,0);
							TextEditFindAgain(Window->ActiveTextEdit,GlobalSearchString);
							TextEditShowSelection(Window->ActiveTextEdit);
							break;
						case eFindAgain:
							TextEditFindAgain(Window->ActiveTextEdit,GlobalSearchString);
							TextEditShowSelection(Window->ActiveTextEdit);
							break;
					}
			}
		else if (MenuItem == mFindAgain)
			{
				if (Window->ActiveTextEdit != Window->SampleExpressionEdit)
					{
						SampleWindowFinalizeCurrentEdit(Window);
						Window->ActiveTextEdit = Window->SampleExpressionEdit;
						EnableTextEditSelection(Window->ActiveTextEdit);
					}
				TextEditFindAgain(Window->ActiveTextEdit,GlobalSearchString);
				TextEditShowSelection(Window->ActiveTextEdit);
			}
		else if (MenuItem == mReplace)
			{
				if (Window->ActiveTextEdit != Window->SampleExpressionEdit)
					{
						SampleWindowFinalizeCurrentEdit(Window);
						Window->ActiveTextEdit = Window->SampleExpressionEdit;
						EnableTextEditSelection(Window->ActiveTextEdit);
					}
				if (TextEditIsThereValidSelection(Window->ActiveTextEdit))
					{
						TextEditInsertRawDataWithUndo(Window->ActiveTextEdit,GlobalReplaceString,
							SYSTEMLINEFEED);
					}
			}
		else if (MenuItem == mReplaceAndFindAgain)
			{
				if (Window->ActiveTextEdit != Window->SampleExpressionEdit)
					{
						SampleWindowFinalizeCurrentEdit(Window);
						Window->ActiveTextEdit = Window->SampleExpressionEdit;
						EnableTextEditSelection(Window->ActiveTextEdit);
					}
				if (TextEditIsThereValidSelection(Window->ActiveTextEdit))
					{
						TextEditInsertRawDataWithUndo(Window->ActiveTextEdit,GlobalReplaceString,
							SYSTEMLINEFEED);
						TextEditFindAgain(Window->ActiveTextEdit,GlobalSearchString);
						TextEditShowSelection(Window->ActiveTextEdit);
					}
			}
		else if (MenuItem == mEnterSelection)
			{
				if (Window->ActiveTextEdit != NIL)
					{
						char*						NewString;

						NewString = TextEditGetSelection(Window->ActiveTextEdit);
						if (NewString != NIL)
							{
								ReleasePtr(GlobalSearchString);
								GlobalSearchString = NewString;
							}
					}
			}
		else if (MenuItem == mExportWAVFormat)
			{
				SampleStorageActualRec*		TheStuff;

				TheStuff = SampleWindowGetTheSampleActual(Window);
				if (TheStuff != NIL)
					{
						ExportWAVSample(TheStuff,SampleWindowGetSamplingRate(Window));
						DisposeSampleStorageActual(TheStuff);
					}
				 else
					{
						AlertHalt("There is not enough memory available to export the sample.",NIL);
					}
			}
		else if (MenuItem == mExportRAWFormat)
			{
				SampleStorageActualRec*		TheStuff;

				TheStuff = SampleWindowGetTheSampleActual(Window);
				if (TheStuff != NIL)
					{
						ExportRAWSample(TheStuff);
						DisposeSampleStorageActual(TheStuff);
					}
				 else
					{
						AlertHalt("There is not enough memory available to export the sample.",NIL);
					}
			}
		else if (MenuItem == mExportAIFFFormat)
			{
				SampleStorageActualRec*		TheStuff;

				TheStuff = SampleWindowGetTheSampleActual(Window);
				if (TheStuff != NIL)
					{
						ExportAIFFSample(TheStuff,SampleWindowGetSamplingRate(Window));
						DisposeSampleStorageActual(TheStuff);
					}
				 else
					{
						AlertHalt("There is not enough memory available to export the sample.",NIL);
					}
			}
		else
			{
				EXECUTE(PRERR(AllowResume,"SampleWindowDoMenuCommand:  unknown menu command"));
			}
	}


/* copy data in the currently active text edit field to wherever it belongs */
void								SampleWindowFinalizeCurrentEdit(SampleWindowRec* Window)
	{
		CheckPtrExistence(Window);
		if (Window->ActiveTextEdit != NIL)
			{
				if (Window->ActiveTextEdit == Window->SampleExpressionEdit)
					{
					}
				else if (Window->ActiveTextEdit == Window->NameEdit)
					{
					}
				else if (Window->ActiveTextEdit == Window->SamplingRateEdit)
					{
						long					Temp;

						Temp = SampleWindowGetSamplingRate(Window);
						if (Temp < MINSAMPLINGRATE)
							{
								SampleWindowPutSamplingRate(Window,MINSAMPLINGRATE);
							}
						if (Temp > MAXSAMPLINGRATE)
							{
								SampleWindowPutSamplingRate(Window,MAXSAMPLINGRATE);
							}
					}
				else if (Window->ActiveTextEdit == Window->NaturalFrequencyEdit)
					{
						double				Temp;

						Temp = SampleWindowGetNaturalFrequency(Window);
						if (Temp < MINNATURALFREQ)
							{
								SampleWindowPutNaturalFrequency(Window,MINNATURALFREQ);
							}
						if (Temp > MAXNATURALFREQ)
							{
								SampleWindowPutNaturalFrequency(Window,MAXNATURALFREQ);
							}
					}
				else if (Window->ActiveTextEdit == Window->OriginEdit)
					{
						AdjustSampleWindowThangs(Window);
						SampleWindowUpdator(Window);
					}
				else if (Window->ActiveTextEdit == Window->LoopStartEdit)
					{
						AdjustSampleWindowThangs(Window);
						SampleWindowUpdator(Window);
					}
				else if (Window->ActiveTextEdit == Window->LoopEndEdit)
					{
						AdjustSampleWindowThangs(Window);
						SampleWindowUpdator(Window);
					}
				else if (Window->ActiveTextEdit == Window->SelectionStartEdit)
					{
						char*							StringTemp;

						StringTemp = TextEditGetRawData(Window->SelectionStartEdit,"\x0a");
						if (StringTemp != NIL)
							{
								SetSampleViewSelection(Window->SampleView,
									StringToInteger(StringTemp,PtrSize(StringTemp)),
									GetSampleViewSelectEnd(Window->SampleView));
								SampleWindowPutSelectStart(Window);
								SampleWindowPutSelectEnd(Window);
								SampleWindowRedrawThangs(Window);
								ReleasePtr(StringTemp);
							}
					}
				else if (Window->ActiveTextEdit == Window->SelectionEndEdit)
					{
						char*							StringTemp;

						StringTemp = TextEditGetRawData(Window->SelectionEndEdit,"\x0a");
						if (StringTemp != NIL)
							{
								SetSampleViewSelection(Window->SampleView,
									GetSampleViewSelectStart(Window->SampleView),
									StringToInteger(StringTemp,PtrSize(StringTemp)));
								SampleWindowPutSelectStart(Window);
								SampleWindowPutSelectEnd(Window);
								SampleWindowRedrawThangs(Window);
								ReleasePtr(StringTemp);
							}
					}
				else if (Window->ActiveTextEdit == Window->ScalingEdit)
					{
						char*							StringTemp;

						StringTemp = TextEditGetRawData(Window->ScalingEdit,"\x0a");
						if (StringTemp != NIL)
							{
								SetSampleViewHorizontalScale(Window->SampleView,
									StringToLongDouble(StringTemp,PtrSize(StringTemp)));
								SampleWindowPutScalingFactor(Window);
								SampleWindowRedrawThangs(Window);
								UpdateSampleWindowScrollbar(Window);
								ReleasePtr(StringTemp);
							}
					}
				else
					{
						EXECUTE(PRERR(AllowResume,"SampleWindowFinalizeCurrentEdit:  "
							"an unknown text edit is in the ActiveTextEdit field."));
					}
				DisableTextEditSelection(Window->ActiveTextEdit);
				Window->ActiveTextEdit = NIL;
			}
	}


/* get the editing version of the origin point */
long								SampleWindowGetOrigin(SampleWindowRec* Window)
	{
		long							ReturnValue;
		char*							StringTemp;

		CheckPtrExistence(Window);
		StringTemp = TextEditGetRawData(Window->OriginEdit,"\x0a");
		if (StringTemp != NIL)
			{
				ReturnValue = StringToInteger(StringTemp,PtrSize(StringTemp));
				ReleasePtr(StringTemp);
			}
		 else
			{
				ReturnValue = 0;
			}
		return ReturnValue;
	}


/* get the current loop start point */
long								SampleWindowGetLoopStart(SampleWindowRec* Window)
	{
		long							ReturnValue;
		char*							StringTemp;

		CheckPtrExistence(Window);
		StringTemp = TextEditGetRawData(Window->LoopStartEdit,"\x0a");
		if (StringTemp != NIL)
			{
				ReturnValue = StringToInteger(StringTemp,PtrSize(StringTemp));
				ReleasePtr(StringTemp);
			}
		 else
			{
				ReturnValue = 0;
			}
		return ReturnValue;
	}


/* get the current loop end point */
long								SampleWindowGetLoopEnd(SampleWindowRec* Window)
	{
		long							ReturnValue;
		char*							StringTemp;

		CheckPtrExistence(Window);
		StringTemp = TextEditGetRawData(Window->LoopEndEdit,"\x0a");
		if (StringTemp != NIL)
			{
				ReturnValue = StringToInteger(StringTemp,PtrSize(StringTemp));
				ReleasePtr(StringTemp);
			}
		 else
			{
				ReturnValue = 0;
			}
		return ReturnValue;
	}


/* get the sampling rate */
long								SampleWindowGetSamplingRate(SampleWindowRec* Window)
	{
		long							ReturnValue;
		char*							StringTemp;

		CheckPtrExistence(Window);
		StringTemp = TextEditGetRawData(Window->SamplingRateEdit,"\x0a");
		if (StringTemp != NIL)
			{
				ReturnValue = StringToInteger(StringTemp,PtrSize(StringTemp));
				ReleasePtr(StringTemp);
			}
		 else
			{
				ReturnValue = 0;
			}
		return ReturnValue;
	}


/* get the natural recorded pitch */
double							SampleWindowGetNaturalFrequency(SampleWindowRec* Window)
	{
		double						ReturnValue;
		char*							StringTemp;

		CheckPtrExistence(Window);
		StringTemp = TextEditGetRawData(Window->NaturalFrequencyEdit,"\x0a");
		if (StringTemp != NIL)
			{
				ReturnValue = StringToLongDouble(StringTemp,PtrSize(StringTemp));
				ReleasePtr(StringTemp);
			}
		 else
			{
				ReturnValue = 0;
			}
		return ReturnValue;
	}


/* copy the select start point from the sample view to the edit box */
void								SampleWindowPutSelectStart(SampleWindowRec* Window)
	{
		char*							StringTemp;

		CheckPtrExistence(Window);
		StringTemp = IntegerToString(GetSampleViewSelectStart(Window->SampleView));
		if (StringTemp != NIL)
			{
				TextEditNewRawData(Window->SelectionStartEdit,StringTemp,"\x0a");
				ReleasePtr(StringTemp);
			}
	}


/* copy the select end point from the sample view to the edit box */
void								SampleWindowPutSelectEnd(SampleWindowRec* Window)
	{
		char*							StringTemp;

		CheckPtrExistence(Window);
		StringTemp = IntegerToString(GetSampleViewSelectEnd(Window->SampleView));
		if (StringTemp != NIL)
			{
				TextEditNewRawData(Window->SelectionEndEdit,StringTemp,"\x0a");
				ReleasePtr(StringTemp);
			}
	}


/* copy the scaling factor from the sample view to the edit box */
void								SampleWindowPutScalingFactor(SampleWindowRec* Window)
	{
		char*							StringTemp;

		CheckPtrExistence(Window);
		StringTemp = LongDoubleToString(
			GetSampleViewHorizontalScale(Window->SampleView),10,1e-4,1e6);
		if (StringTemp != NIL)
			{
				TextEditNewRawData(Window->ScalingEdit,StringTemp,"\x0a");
				ReleasePtr(StringTemp);
			}
	}


/* put a new origin point into the edit box */
void								SampleWindowPutOrigin(SampleWindowRec* Window, long NewOrigin)
	{
		char*							StringTemp;

		CheckPtrExistence(Window);
		SampleWindowRedrawUnderThangs(Window);
		StringTemp = IntegerToString(NewOrigin);
		if (StringTemp != NIL)
			{
				TextEditNewRawData(Window->OriginEdit,StringTemp,"\x0a");
				ReleasePtr(StringTemp);
				AdjustSampleWindowThangs(Window);
				SampleWindowRedrawThangs(Window);
			}
	}


/* put a new loop start into the current loop start edit box */
void								SampleWindowPutLoopStart(SampleWindowRec* Window, long NewLoopStart)
	{
		char*							StringTemp;

		CheckPtrExistence(Window);
		SampleWindowRedrawUnderThangs(Window);
		StringTemp = IntegerToString(NewLoopStart);
		if (StringTemp != NIL)
			{
				TextEditNewRawData(Window->LoopStartEdit,StringTemp,"\x0a");
				ReleasePtr(StringTemp);
				AdjustSampleWindowThangs(Window);
				SampleWindowRedrawThangs(Window);
			}
	}


/* put a new loop end into the current loop end edit box */
void								SampleWindowPutLoopEnd(SampleWindowRec* Window, long NewLoopEnd)
	{
		char*							StringTemp;

		CheckPtrExistence(Window);
		SampleWindowRedrawUnderThangs(Window);
		StringTemp = IntegerToString(NewLoopEnd);
		if (StringTemp != NIL)
			{
				TextEditNewRawData(Window->LoopEndEdit,StringTemp,"\x0a");
				ReleasePtr(StringTemp);
				AdjustSampleWindowThangs(Window);
				SampleWindowRedrawThangs(Window);
			}
	}


/* put a new sampling rate into the sampling rate edit box */
void								SampleWindowPutSamplingRate(SampleWindowRec* Window,
											long NewSamplingRate)
	{
		char*							StringTemp;

		CheckPtrExistence(Window);
		StringTemp = IntegerToString(NewSamplingRate);
		if (StringTemp != NIL)
			{
				TextEditNewRawData(Window->SamplingRateEdit,StringTemp,"\x0a");
				ReleasePtr(StringTemp);
			}
	}


/* put a new natural recorded pitch into the natural frequency edit box */
void								SampleWindowPutNaturalFrequency(SampleWindowRec* Window,
											double NewNaturalFrequency)
	{
		char*							StringTemp;

		CheckPtrExistence(Window);
		StringTemp = LongDoubleToString(NewNaturalFrequency,13,1e-4,1e6);
		if (StringTemp != NIL)
			{
				TextEditNewRawData(Window->NaturalFrequencyEdit,StringTemp,"\x0a");
				ReleasePtr(StringTemp);
			}
	}


/* find the current mouse position and put it in the box */
void								SampleWindowPutMousePosition(SampleWindowRec* Window)
	{
		char*							StringTemp;
		OrdType						MouseXPosition;
		OrdType						StupidYPosition;
		long							CalculatedOffset;

		CheckPtrExistence(Window);
		GetMousePosition(&MouseXPosition,&StupidYPosition);
		CalculatedOffset = ((MouseXPosition - 1 - GetSampleViewXLoc(Window->SampleView))
			* GetSampleViewHorizontalScale(Window->SampleView))
			+ GetSampleViewXOffset(Window->SampleView);
		StringTemp = IntegerToString(CalculatedOffset);
		if (StringTemp != NIL)
			{
				TextEditNewRawData(Window->MousePositionEdit,StringTemp,"\x0a");
				ReleasePtr(StringTemp);
			}
	}


/* get the number of bits used to store the sample */
NumBitsType					SampleWindowGetNumBits(SampleWindowRec* Window)
	{
		CheckPtrExistence(Window);
		return GetSampleViewNumBits(Window->SampleView);
	}


/* get the number of channels the sample has */
NumChannelsType			SampleWindowGetNumChannels(SampleWindowRec* Window)
	{
		CheckPtrExistence(Window);
		return GetSampleViewNumChannels(Window->SampleView);
	}


/* get a copy of the name of the sample */
char*								SampleWindowGetNameCopy(SampleWindowRec* Window)
	{
		char*							ReturnValue;

		CheckPtrExistence(Window);
		ReturnValue = TextEditGetRawData(Window->NameEdit,"\x0a");
		if (ReturnValue != NIL)
			{
				SetTag(ReturnValue,"SampWindowNameCopy");
			}
		return ReturnValue;
	}


/* get the number of frames in the current sample */
long								SampleWindowGetNumFrames(SampleWindowRec* Window)
	{
		CheckPtrExistence(Window);
		return GetSampleViewNumFrames(Window->SampleView);
	}


/* get a copy of the formula text */
char*								SampleWindowGetFormulaCopy(SampleWindowRec* Window)
	{
		char*							TextCopy;

		CheckPtrExistence(Window);
		TextCopy = TextEditGetRawData(Window->SampleExpressionEdit,"\x0a");
		if (TextCopy != NIL)
			{
				SetTag(TextCopy,"SampWinFormulaCopy");
			}
		return TextCopy;
	}


/* get a copy of the left channel for a stereo sample. */
largefixedsigned*		SampleWindowGetFixedArrayLeft(SampleWindowRec* Window)
	{
		CheckPtrExistence(Window);
		return SampleViewGetChannelFixed(Window->SampleView,eLeftChannel);
	}


/* get a copy of the right channel for a stereo sample. */
largefixedsigned*		SampleWindowGetFixedArrayRight(SampleWindowRec* Window)
	{
		CheckPtrExistence(Window);
		return SampleViewGetChannelFixed(Window->SampleView,eRightChannel);
	}


/* get a copy of a mono sample. */
largefixedsigned*		SampleWindowGetFixedArrayMono(SampleWindowRec* Window)
	{
		CheckPtrExistence(Window);
		return SampleViewGetChannelFixed(Window->SampleView,eMonoChannel);
	}


/* put a new name in.  the caller is responsible for deleting NewName */
void								SampleWindowObjectNameChange(SampleWindowRec* Window, char* NewName)
	{
		CheckPtrExistence(Window);
		CheckPtrExistence(NewName);
		/* we only use the name, but we don't dispose it */
		TextEditNewRawData(Window->NameEdit,NewName,"\x0a");
		TextEditHasBeenSaved(Window->NameEdit);
	}


/* this is the argument list for stereo sample */
static FunctionParamRec		StereoArgList[] =
	{
		{"loopstart",eInteger},
		{"loopend",eInteger},
		{"origin",eInteger},
		{"samplingrate",eInteger},
		{"naturalfrequency",eDouble},
		{"selectstart",eInteger},
		{"selectend",eInteger},
		{"leftdata",eArrayOfFixed},
		{"rightdata",eArrayOfFixed}
	};
#define STEREOARGLISTLENGTH (sizeof(StereoArgList) / sizeof(StereoArgList[0]))


/* this is the argument list for mono sample */
static FunctionParamRec		MonoArgList[] =
	{
		{"loopstart",eInteger},
		{"loopend",eInteger},
		{"origin",eInteger},
		{"samplingrate",eInteger},
		{"naturalfrequency",eDouble},
		{"selectstart",eInteger},
		{"selectend",eInteger},
		{"data",eArrayOfFixed}
	};
#define MONOARGLISTLENGTH (sizeof(MonoArgList) / sizeof(MonoArgList[0]))


/* evaluate the formula and modify the sample */
void								SampleWindowPerformCalculation(SampleWindowRec* Window)
	{
		char*								Blob;
		PcodeRec*						FuncCode;
		CompileErrors				Error;
		long								LineNumber;
		ParamStackRec*			ParamList;
		EvalErrors					OtherError;
		OpcodeRec*					ErrorOpcode;
		long								OffendingInstruction;
		DataTypes						ReturnType;

		CheckPtrExistence(Window);

		/* bring the world up to date */
		if (!MainWindowMakeUpToDateFunctions(Window->MainWindow))
			{
				return;
			}

		/* prepare the text blob to be evaluated */
		Blob = TextEditGetRawData(Window->SampleExpressionEdit,"\x0a");
		if (Blob == NIL)
			{
			 FailurePoint1:
				AlertHalt("There is not enough memory available to compile the expression.",NIL);
				return;
			}

		/* perform compilation */
		Error = CompileSpecialFunction((GetSampleViewNumChannels(Window->SampleView)
			== eSampleStereo) ? StereoArgList : MonoArgList,(GetSampleViewNumChannels(
			Window->SampleView) == eSampleStereo) ? STEREOARGLISTLENGTH : MONOARGLISTLENGTH,
			&LineNumber,&ReturnType,Blob,&FuncCode);
		ReleasePtr(Blob);
		if (Error != eCompileNoError)
			{
				SetTextEditSelection(Window->SampleExpressionEdit,LineNumber - 1,0,LineNumber,0);
				TextEditShowSelection(Window->SampleExpressionEdit);
				AlertHalt("A compile error occurred:  _",GetCompileErrorString(Error));
				return;
			}

		/* try to evaluate the code */
		ParamList = NewParamStack();
		if (ParamList == NIL)
			{
			 SecondFailurePoint1:
				DisposePcode(FuncCode);
				AlertHalt("There is not enough memory available to evaluate the expression.",NIL);
				return;
			}
		/* add a space for the return value */
		if (!AddIntegerToStack(ParamList,0))
			{
			 SecondFailurePoint2:
				DisposeParamStack(ParamList);
				goto SecondFailurePoint1;
			}
		/* add the special parameters (SymbolStack order MUST be the same */
		/* order as that used for the Parameterlist) */
		/* loopstart */
		if (!AddIntegerToStack(ParamList,SampleWindowGetLoopStart(Window)))
			{
				goto SecondFailurePoint2;
			}
		/* loopend */
		if (!AddIntegerToStack(ParamList,SampleWindowGetLoopEnd(Window)))
			{
				goto SecondFailurePoint2;
			}
		/* origin */
		if (!AddIntegerToStack(ParamList,SampleWindowGetOrigin(Window)))
			{
				goto SecondFailurePoint2;
			}
		/* samplingrate */
		if (!AddIntegerToStack(ParamList,SampleWindowGetSamplingRate(Window)))
			{
				goto SecondFailurePoint2;
			}
		/* basefrequency */
		if (!AddDoubleToStack(ParamList,SampleWindowGetNaturalFrequency(Window)))
			{
				goto SecondFailurePoint2;
			}
		/* selectstart */
		if (!AddIntegerToStack(ParamList,GetSampleViewSelectStart(Window->SampleView)))
			{
				goto SecondFailurePoint2;
			}
		/* selectend */
		if (!AddIntegerToStack(ParamList,GetSampleViewSelectEnd(Window->SampleView)))
			{
				goto SecondFailurePoint2;
			}
		/* data (the actual thing is added, so we don't have to dispose it!) */
		if (GetSampleViewNumChannels(Window->SampleView) == eSampleStereo)
			{
				largefixedsigned*		DataBlock;

				/* left channel */
				DataBlock = SampleViewGetChannelFixed(Window->SampleView,eLeftChannel);
				if (DataBlock == NIL)
					{
						goto SecondFailurePoint2;
					}
				if (!AddArrayToStack(ParamList,DataBlock))
					{
						ReleasePtr((char*)DataBlock);
						goto SecondFailurePoint2;
					}
				/* right channel */
				DataBlock = SampleViewGetChannelFixed(Window->SampleView,eRightChannel);
				if (DataBlock == NIL)
					{
						goto SecondFailurePoint2;
					}
				if (!AddArrayToStack(ParamList,DataBlock))
					{
						ReleasePtr((char*)DataBlock);
						goto SecondFailurePoint2;
					}
			}
		 else
			{
				largefixedsigned*		DataBlock;

				DataBlock = SampleViewGetChannelFixed(Window->SampleView,eMonoChannel);
				if (DataBlock == NIL)
					{
						goto SecondFailurePoint2;
					}
				if (!AddArrayToStack(ParamList,DataBlock))
					{
						ReleasePtr((char*)DataBlock);
						goto SecondFailurePoint2;
					}
			}

		/* executing the actual code */
		OtherError = EvaluatePcode(ParamList,FuncCode,
			Window->CodeCenter,&ErrorOpcode,&OffendingInstruction,Window->MainWindow,
			(SampleErrors (*)(void*,char*,largefixedsigned**))&MainWindowGetSampleLeftCopy,
			(SampleErrors (*)(void*,char*,largefixedsigned**))&MainWindowGetSampleRightCopy,
			(SampleErrors (*)(void*,char*,largefixedsigned**))&MainWindowGetSampleMonoCopy,
			(SampleErrors (*)(void*,char*,long*))&MainWindowGetWaveTableFrameCount,
			(SampleErrors (*)(void*,char*,long*))&MainWindowGetWaveTableTableCount,
			(SampleErrors (*)(void*,char*,largefixedsigned**))&MainWindowGetWaveTableArray,
			Window->MainWindow,
			(struct InteractionWindowRec* (*)(void*))&MainWindowGetInteractionWindow);
		if (OtherError != eEvalNoError)
			{
				char*					FuncNameString;
				FuncCodeRec*	ErrorFunction;
				MyBoolean			SuccessFlag;

				/* present error message */
				SuccessFlag = False;
				ErrorFunction = GetFunctionFromOpcode(Window->CodeCenter,ErrorOpcode);
				if (ErrorFunction == NIL)
					{
						FuncNameString = StringToBlockCopy("<anonymous>");
					}
				 else
					{
						FuncNameString = CopyPtr(GetFunctionName(ErrorFunction));
					}
				if (FuncNameString != NIL)
					{
						char*					Key;

						Key = StringToBlockCopy("_");
						if (Key != NIL)
							{
								char*					BaseMessage;

								BaseMessage = StringFromRaw("Error in function _, instruction _:  _");
								if (BaseMessage != NIL)
									{
										char*					FixedMessage1;

										FixedMessage1 = ReplaceBlockCopy(BaseMessage,Key,FuncNameString);
										if (FixedMessage1 != NIL)
											{
												char*					NumberStr;

												NumberStr = IntegerToString(OffendingInstruction);
												if (NumberStr != NIL)
													{
														char*					FixedMessage2;

														FixedMessage2 = ReplaceBlockCopy(FixedMessage1,Key,NumberStr);
														if (FixedMessage2 != NIL)
															{
																AlertHalt(FixedMessage2,GetPcodeErrorMessage(OtherError));
																SuccessFlag = True;
																ReleasePtr(FixedMessage2);
															}
														ReleasePtr(NumberStr);
													}
												ReleasePtr(FixedMessage1);
											}
										ReleasePtr(BaseMessage);
									}
								ReleasePtr(Key);
							}
						ReleasePtr(FuncNameString);
					}
				if (!SuccessFlag)
					{
						AlertHalt("There is not enough memory available to show "
							"the compile error message.",NIL);
					}
				DisposeParamStack(ParamList);
				DisposePcode(FuncCode);
				return;
			}

		/* add the new data */
		if (GetSampleViewNumChannels(Window->SampleView) == eSampleStereo)
			{
				largefixedsigned*		Left;
				largefixedsigned*		Right;

				Left = (largefixedsigned*)GetStackArray(ParamList,8);
				Right = (largefixedsigned*)GetStackArray(ParamList,9);
				if ((Left == NIL) || (Right == NIL))
					{
						AlertHalt("NIL array returned; data not changed.",NIL);
					}
				else if (PtrSize((char*)Left) != PtrSize((char*)Right))
					{
						AlertHalt("Left and Right arrays are not the same size.",NIL);
					}
				else
					{
						ERROR(PtrSize((char*)Left) % sizeof(largefixedsigned) != 0,
							PRERR(ForceAbort,"SampleWindowPerformCalculation:  array alignment error"));
						if (!SampleViewPutStereoFixed(Window->SampleView,Left,Right))
							{
								AlertHalt("There is not enough memory available to "
									"write data back to editor.",NIL);
							}
					}
			}
		 else
			{
				largefixedsigned*		Middle;

				Middle = (largefixedsigned*)GetStackArray(ParamList,8);
				if (Middle == NIL)
					{
						AlertHalt("NIL array returned; data not changed.",NIL);
					}
				else
					{
						ERROR(PtrSize((char*)Middle) % sizeof(largefixedsigned) != 0,
							PRERR(ForceAbort,"SampleWindowPerformCalculation:  array alignment error"));
						if (!SampleViewPutMonoFixed(Window->SampleView,Middle))
							{
								AlertHalt("There is not enough memory available to "
									"write data back to editor.",NIL);
							}
					}
			}
		DisposeParamStack(ParamList);
		DisposePcode(FuncCode);
		SampleWindowPutSelectStart(Window);
		SampleWindowPutSelectEnd(Window);
		AdjustSampleWindowThangs(Window);
		UpdateSampleWindowScrollbar(Window);
	}


/* redraw the origin and loop point bars */
void								SampleWindowRedrawThangs(SampleWindowRec* Window)
	{
		long							Location;
		OrdType						XSize;
		OrdType						YSize;

		CheckPtrExistence(Window);
		XSize = GetWindowWidth(Window->ScreenID);
		YSize = GetWindowHeight(Window->ScreenID);

		/* draw the cute horizontal bars */
		SetClipRect(Window->ScreenID,SAMPLEEDITX,SAMPLEEDITY,SAMPLEEDITWIDTH(XSize),
			SAMPLEEDITHEIGHT(YSize) - 15);
		DrawBoxFrame(Window->ScreenID,eBlack,SAMPLEEDITX,SAMPLEEDITY,
			SAMPLEEDITWIDTH(XSize),OVERLINEHEIGHT + 1);
		DrawBoxFrame(Window->ScreenID,eBlack,SAMPLEEDITX,SAMPLEEDITY + OVERLINEHEIGHT,
			SAMPLEEDITWIDTH(XSize),OVERLINEHEIGHT + 1);
		DrawBoxFrame(Window->ScreenID,eBlack,SAMPLEEDITX,SAMPLEEDITY + (2 * OVERLINEHEIGHT),
			SAMPLEEDITWIDTH(XSize),OVERLINEHEIGHT + 1);
		DrawBoxErase(Window->ScreenID,SAMPLEEDITX + 1,SAMPLEEDITY + 1,
			SAMPLEEDITWIDTH(XSize) - 2,OVERLINEHEIGHT + 1 - 2);
		DrawBoxErase(Window->ScreenID,SAMPLEEDITX + 1,SAMPLEEDITY + OVERLINEHEIGHT + 1,
			SAMPLEEDITWIDTH(XSize) - 2,OVERLINEHEIGHT + 1 - 2);
		DrawBoxErase(Window->ScreenID,SAMPLEEDITX + 1,SAMPLEEDITY + (2 * OVERLINEHEIGHT) + 1,
			SAMPLEEDITWIDTH(XSize) - 2,OVERLINEHEIGHT + 1 - 2);
		DrawTextLine(Window->ScreenID,GetScreenFont(),9,"Origin",6,SAMPLEEDITX + 5,
			SAMPLEEDITY + 1,ePlain);
		DrawTextLine(Window->ScreenID,GetScreenFont(),9,"Loop Start",10,SAMPLEEDITX + 5,
			SAMPLEEDITY + 1 + OVERLINEHEIGHT,ePlain);
		DrawTextLine(Window->ScreenID,GetScreenFont(),9,"Loop End",8,SAMPLEEDITX + 5,
			SAMPLEEDITY + 1 + (2 * OVERLINEHEIGHT),ePlain);

		/* drawing origin thang */
		Location = (SampleWindowGetOrigin(Window)
			- GetSampleViewXOffset(Window->SampleView))
			/ GetSampleViewHorizontalScale(Window->SampleView);
		if ((Location > -16384) && (Location < 16384))
			{
				DrawTrianglePaint(Window->ScreenID,eBlack,
					SAMPLEEDITX - 4 + Location + 1,
					SAMPLEEDITY + 1,
					SAMPLEEDITX + 4 + Location + 1,
					SAMPLEEDITY + 1,
					SAMPLEEDITX + Location + 1,
					SAMPLEEDITY + 8);
				DrawLine(Window->ScreenID,eBlack,
					SAMPLEEDITX + Location + 1,
					SAMPLEEDITY + 1,
					0,SAMPLEEDITHEIGHT(YSize) - 15);
			}

		/* drawing loop start thang */
		Location = (SampleWindowGetLoopStart(Window)
			- GetSampleViewXOffset(Window->SampleView))
			/ GetSampleViewHorizontalScale(Window->SampleView);
		if ((Location > -16384) && (Location < 16384))
			{
				DrawTrianglePaint(Window->ScreenID,eBlack,
					SAMPLEEDITX - 4 + Location + 1,
					SAMPLEEDITY + 1 + OVERLINEHEIGHT,
					SAMPLEEDITX + 4 + Location + 1,
					SAMPLEEDITY + 1 + OVERLINEHEIGHT,
					SAMPLEEDITX + Location + 1,
					SAMPLEEDITY + 8 + OVERLINEHEIGHT);
				DrawLine(Window->ScreenID,eBlack,
					SAMPLEEDITX + Location + 1,
					SAMPLEEDITY + 1 + OVERLINEHEIGHT,
					0,SAMPLEEDITHEIGHT(YSize) - 15 - OVERLINEHEIGHT);
			}

		/* drawing loop end thang */
		Location = (SampleWindowGetLoopEnd(Window)
			- GetSampleViewXOffset(Window->SampleView))
			/ GetSampleViewHorizontalScale(Window->SampleView);
		if ((Location > -16384) && (Location < 16384))
			{
				DrawTrianglePaint(Window->ScreenID,eBlack,
					SAMPLEEDITX - 4 + Location + 1,
					SAMPLEEDITY + 1 + (2 * OVERLINEHEIGHT),
					SAMPLEEDITX + 4 + Location + 1,
					SAMPLEEDITY + 1 + (2 * OVERLINEHEIGHT),
					SAMPLEEDITX + Location + 1,
					SAMPLEEDITY + 8 + (2 * OVERLINEHEIGHT));
				DrawLine(Window->ScreenID,eBlack,
					SAMPLEEDITX + Location + 1,
					SAMPLEEDITY + 1 + (2 * OVERLINEHEIGHT),
					0,SAMPLEEDITHEIGHT(YSize) - 15 - (2 * OVERLINEHEIGHT));
			}
	}


/* redraw the sample points that occur under the origin and loop point bars */
void								SampleWindowRedrawUnderThangs(SampleWindowRec* Window)
	{
		long							Location;

		CheckPtrExistence(Window);
		Location = (SampleWindowGetOrigin(Window)
			- GetSampleViewXOffset(Window->SampleView))
			/ GetSampleViewHorizontalScale(Window->SampleView);
		RedrawSampleViewOneLine(Window->SampleView,Location + 1);
		Location = (SampleWindowGetLoopStart(Window)
			- GetSampleViewXOffset(Window->SampleView))
			/ GetSampleViewHorizontalScale(Window->SampleView);
		RedrawSampleViewOneLine(Window->SampleView,Location + 1);
		Location = (SampleWindowGetLoopEnd(Window)
			- GetSampleViewXOffset(Window->SampleView))
			/ GetSampleViewHorizontalScale(Window->SampleView);
		RedrawSampleViewOneLine(Window->SampleView,Location + 1);
	}


/* make sure the loop start and end are within the proper ranges */
void								AdjustSampleWindowThangs(SampleWindowRec* Window)
	{
		long							NumFrames;

		CheckPtrExistence(Window);
		NumFrames = GetSampleViewNumFrames(Window->SampleView);
		/* loop start check */
		if (SampleWindowGetLoopStart(Window) > NumFrames)
			{
				SampleWindowPutLoopStart(Window,NumFrames);
			}
		if (SampleWindowGetLoopStart(Window) < 0)
			{
				SampleWindowPutLoopStart(Window,0);
			}
		/* loop end check */
		if (SampleWindowGetLoopEnd(Window) > NumFrames)
			{
				SampleWindowPutLoopEnd(Window,NumFrames);
			}
		if (SampleWindowGetLoopEnd(Window) < SampleWindowGetLoopStart(Window))
			{
				SampleWindowPutLoopEnd(Window,SampleWindowGetLoopStart(Window));
			}
	}


/* recalculate the scroll bar displacements and redraw it */
void								UpdateSampleWindowScrollbar(SampleWindowRec* Window)
	{
		CheckPtrExistence(Window);
		SetMaxScrollIndex(Window->Scrollbar,GetSampleViewNumFrames(Window->SampleView)
			- GetSampleViewNumVisibleFrames(Window->SampleView));
		SetScrollIndex(Window->Scrollbar,GetSampleViewXOffset(Window->SampleView));
		RedrawScrollBar(Window->Scrollbar);
	}


static void					SampleWindowScrollHook(long Parameter, ScrollType How,
											SampleWindowRec* Window)
	{
		CheckPtrExistence(Window);
		switch (How)
			{
				case eScrollToPosition:
					SetSampleViewXOffset(Window->SampleView,Parameter);
					UpdateSampleWindowScrollbar(Window);
					SampleWindowRedrawThangs(Window);
					break;
				case eScrollPageMinus:
					SetSampleViewXOffset(Window->SampleView,
						GetSampleViewXOffset(Window->SampleView)
						- ((7 * GetSampleViewNumVisibleFrames(Window->SampleView)) / 8));
					UpdateSampleWindowScrollbar(Window);
					SampleWindowRedrawThangs(Window);
					break;
				case eScrollPagePlus:
					SetSampleViewXOffset(Window->SampleView,
						GetSampleViewXOffset(Window->SampleView)
						+ ((7 * GetSampleViewNumVisibleFrames(Window->SampleView)) / 8));
					UpdateSampleWindowScrollbar(Window);
					SampleWindowRedrawThangs(Window);
					break;
				case eScrollLineMinus:
					SetSampleViewXOffset(Window->SampleView,
						GetSampleViewXOffset(Window->SampleView)
						- ((1 * GetSampleViewNumVisibleFrames(Window->SampleView)) / 8));
					UpdateSampleWindowScrollbar(Window);
					SampleWindowRedrawThangs(Window);
					break;
				case eScrollLinePlus:
					SetSampleViewXOffset(Window->SampleView,
						GetSampleViewXOffset(Window->SampleView)
						+ ((1 * GetSampleViewNumVisibleFrames(Window->SampleView)) / 8));
					UpdateSampleWindowScrollbar(Window);
					SampleWindowRedrawThangs(Window);
					break;
				default:
					EXECUTE(PRERR(AllowResume,"SampleWindowScrollHook:  Unknown scroll opcode"));
					break;
			}
		SampleWindowPutMousePosition(Window);
	}


/* handle a mouse down in the sample edit area. */
void								SampleWindowDoMouseDownInEdit(SampleWindowRec* Window, OrdType OrigX,
											OrdType OrigY)
	{
		long							BaseSelectionStart;
		long							BaseSelectionEnd;
		OrdType						WhereX;
		OrdType						WhereY;

		CheckPtrExistence(Window);

		/* first, check for a scrollbar operation */
		if (ScrollHitTest(Window->Scrollbar,OrigX,OrigY))
			{
				ScrollHitProc(Window->Scrollbar,CheckModifiers(),OrigX,
					OrigY,Window,(void (*)(long,ScrollType,void*))&SampleWindowScrollHook);
				return;
			}
		/* now check for a parameter (origin, loop...) drag operation */
		if (OrigY < SAMPLEEDITY + (3 * OVERLINEHEIGHT))
			{
				MyBoolean				DoingOrigin = False;
				MyBoolean				DoingLoopStart = False;
				MyBoolean				DoingLoopEnd = False;

				if (OrigY < SAMPLEEDITY + OVERLINEHEIGHT)
					{
						DoingOrigin = True;
					}
				else if (OrigY < SAMPLEEDITY + (2 * OVERLINEHEIGHT))
					{
						DoingLoopStart = True;
					}
				else
					{
						DoingLoopEnd = True;
					}
				while (eMouseUp != GetAnEvent(&WhereX,&WhereY,NIL,NIL,NIL,NIL))
					{
						long				CurrentMouseX;

						SampleWindowPutMousePosition(Window);
						WhereX -= (GetSampleViewXLoc(Window->SampleView) + 1);
						if (WhereX < 0)
							{
								/* drag left */
								SampleWindowScrollHook(0,eScrollLineMinus,Window);
							}
						if (WhereX > SAMPLEEDITWIDTH(GetWindowWidth(Window->ScreenID)))
							{
								/* drag right */
								SampleWindowScrollHook(0,eScrollLinePlus,Window);
							}
						CurrentMouseX = WhereX * GetSampleViewHorizontalScale(Window->SampleView)
							+ GetSampleViewXOffset(Window->SampleView);
						/* perform modification & redraw */
						SampleWindowRedrawUnderThangs(Window);
						if (DoingOrigin)
							{
								SampleWindowPutOrigin(Window,CurrentMouseX);
							}
						else if (DoingLoopStart)
							{
								SampleWindowPutLoopStart(Window,CurrentMouseX);
							}
						else /* if (DoingLoopEnd) */
							{
								SampleWindowPutLoopEnd(Window,CurrentMouseX);
							}
						AdjustSampleWindowThangs(Window);
						SampleWindowRedrawThangs(Window);
					}
				SampleWindowPutMousePosition(Window);
				return;
			}

		/* convert mouse location into local coordinates */
		WhereX = OrigX - (GetSampleViewXLoc(Window->SampleView) + 1);

		/* set up base selection */
		if ((CheckModifiers() & eShiftKey) != 0)
			{
				/* extending existing selection */
				BaseSelectionStart = GetSampleViewSelectStart(Window->SampleView);
				BaseSelectionEnd = GetSampleViewSelectEnd(Window->SampleView);
			}
		 else
			{
				/* replacing existing selection */
				BaseSelectionStart = WhereX * GetSampleViewHorizontalScale(Window->SampleView)
					+ GetSampleViewXOffset(Window->SampleView);
				BaseSelectionEnd = BaseSelectionStart;
				SetSampleViewSelection(Window->SampleView,BaseSelectionStart,BaseSelectionEnd);
			}

		/* track mouse */
		while (eMouseUp != GetAnEvent(&WhereX,&WhereY,NIL,NIL,NIL,NIL))
			{
				long				CurrentMouseX;
				long				NewTempSelectStart;
				long				NewTempSelectEnd;

				SampleWindowPutMousePosition(Window);
				SampleWindowPutSelectStart(Window);
				SampleWindowPutSelectEnd(Window);
				WhereX -= (GetSampleViewXLoc(Window->SampleView) + 1);
				if (WhereX < 0)
					{
						/* drag left */
						SampleWindowScrollHook(0,eScrollLineMinus,Window);
					}
				if (WhereX > SAMPLEEDITWIDTH(GetWindowWidth(Window->ScreenID)))
					{
						/* drag right */
						SampleWindowScrollHook(0,eScrollLinePlus,Window);
					}
				/* find union of selection areas */
				CurrentMouseX = WhereX * GetSampleViewHorizontalScale(Window->SampleView)
					+ GetSampleViewXOffset(Window->SampleView);
				NewTempSelectStart = BaseSelectionStart;
				NewTempSelectEnd = BaseSelectionEnd;
				if (CurrentMouseX < NewTempSelectStart)
					{
						NewTempSelectStart = CurrentMouseX;
					}
				if (CurrentMouseX > NewTempSelectEnd)
					{
						NewTempSelectEnd = CurrentMouseX;
					}
				/* set new selection region */
				SetSampleViewSelection(Window->SampleView,NewTempSelectStart,NewTempSelectEnd);
			}
		/* now we leave, and the selection has been adjusted as desired */
		SampleWindowPutMousePosition(Window);
		SampleWindowPutSelectStart(Window);
		SampleWindowPutSelectEnd(Window);
		SampleWindowRedrawThangs(Window);
	}


/* find out which loop the sample is editing */
SampleLoops					SampleWindowEditingWhichLoop(SampleWindowRec* Window)
	{
		CheckPtrExistence(Window);
		return Window->EditingWhichLoop;
	}


/* force the sample data to be written back to the object.  this does not write */
/* back any other data. */
MyBoolean						SampleWindowForceUpdateSampleObjectData(SampleWindowRec* Window)
	{
		SampleStorageActualRec*		TheStuff;

		TheStuff = SampleWindowGetTheSampleActual(Window);
		if (TheStuff != NIL)
			{
				/* this call disposes the sample for us */
				SampleObjectPutNewSample(Window->SampleObject,TheStuff);
				SampleViewHasBeenSaved(Window->SampleView);
				return True;
			}
		 else
			{
				return False;
			}
	}


/* get the raw data for the sample, in char or short form.  the caller must NOT */
/* dispose of this data, and it will become invalid if any modifications are made */
/* to the sample.  This is basically SampleObjectGetRawData() with a call to */
/* SampleWindowForceUpdateSampleObjectData() to keep everything consistent. */
char*								SampleWindowGetRawData(SampleWindowRec* Window)
	{
		/* this is a weird routine:  it forces the sample object to be up to date, then */
		/* returns the sample object's idea of what the sample is.  Be careful because */
		/* it can lead to recursive infinite loops */
		CheckPtrExistence(Window);
		if (!SampleWindowForceUpdateSampleObjectData(Window))
			{
				/* failed */
			}
		return SampleObjectGetRawData(Window->SampleObject);
	}


/* get the raw fixedpoint data for the sample. */
largefixedsigned*		SampleWindowGetRawFixedPointData(SampleWindowRec* Window)
	{
		CheckPtrExistence(Window);
		return SampleViewGetActualRawData(Window->SampleView);
	}


/* the document title has changed, so change the window title bar.  caller is */
/* responsible for deleting the string, which should be non-null-terminated. */
void								SampleWindowGlobalNameChange(SampleWindowRec* Window,
											char* NewFilename)
	{
		char*							LocalNameCopy;

		CheckPtrExistence(Window);
		CheckPtrExistence(NewFilename);
		LocalNameCopy = TextEditGetRawData(Window->NameEdit,SYSTEMLINEFEED);
		if (LocalNameCopy != NIL)
			{
				char*							SeparatorString;

				SeparatorString = StringToBlockCopy(":  ");
				if (SeparatorString != NIL)
					{
						char*							LeftHalfOfString;

						LeftHalfOfString = ConcatBlockCopy(NewFilename,SeparatorString);
						if (LeftHalfOfString != NIL)
							{
								char*							TotalString;

								TotalString = ConcatBlockCopy(LeftHalfOfString,LocalNameCopy);
								if (TotalString != NIL)
									{
										char*							NullTerminatedString;

										NullTerminatedString = BlockToStringCopy(TotalString);
										if (NullTerminatedString != NIL)
											{
												SetWindowName(Window->ScreenID,NullTerminatedString);
												ChangeItemName(Window->MyMenuItem,NullTerminatedString);
												ReleasePtr(NullTerminatedString);
											}
										ReleasePtr(TotalString);
									}
								ReleasePtr(LeftHalfOfString);
							}
						ReleasePtr(SeparatorString);
					}
				ReleasePtr(LocalNameCopy);
			}
	}


/* force the window title bar to be renamed even if the document hasn't been renamed */
void								SampleWindowResetTitlebar(SampleWindowRec* Window)
	{
		char*							DocumentName;

		CheckPtrExistence(Window);
		DocumentName = GetCopyOfDocumentName(Window->MainWindow);
		if (DocumentName != NIL)
			{
				SampleWindowGlobalNameChange(Window,DocumentName);
				ReleasePtr(DocumentName);
			}
	}


/* get an 'actual' sample object that contains the same data as the window.  the */
/* caller must delete the object. */
struct SampleStorageActualRec*	SampleWindowGetTheSampleActual(SampleWindowRec* Window)
	{
		SampleStorageActualRec*		TheStuff;
		NumChannelsType						NumChannels;
		long											Limit;
		long											Scan;

		NumChannels = SampleWindowGetNumChannels(Window);
		Limit = GetSampleViewNumFrames(Window->SampleView);
		TheStuff = NewSampleStorageActual(SampleWindowGetNumBits(Window),
			NumChannels,Limit);
		if (TheStuff != NIL)
			{
				switch (NumChannels)
					{
						default:
							EXECUTE(PRERR(ForceAbort,"SampleWindowGetTheSampleActual:  bad num bits"));
							break;
						case eSampleMono:
							for (Scan = 0; Scan < Limit; Scan += 1)
								{
									SetSampleStorageActualValue(TheStuff,Scan,eMonoChannel,
										GetSampleViewValue(Window->SampleView,Scan,eMonoChannel));
								}
							break;
						case eSampleStereo:
							for (Scan = 0; Scan < Limit; Scan += 1)
								{
									SetSampleStorageActualValue(TheStuff,Scan,eLeftChannel,
										GetSampleViewValue(Window->SampleView,Scan,eLeftChannel));
									SetSampleStorageActualValue(TheStuff,Scan,eRightChannel,
										GetSampleViewValue(Window->SampleView,Scan,eRightChannel));
								}
							break;
					}
			}
		return TheStuff;
	}


/* force ALL modified data to be written back to the object.  this includes */
/* calling SampleWindowForceUpdateSampleObjectData() */
MyBoolean						SampleWindowWritebackModifiedData(SampleWindowRec* Window)
	{
		MyBoolean					SuccessFlag = True;

		CheckPtrExistence(Window);

		/* if an edit is being edited, then finalize it */
		SampleWindowFinalizeCurrentEdit(Window);

		if (TextEditDoesItNeedToBeSaved(Window->NameEdit))
			{
				char*							TempString;

				TempString = SampleWindowGetNameCopy(Window);
				if (TempString != NIL)
					{
						SampleObjectNewName(Window->SampleObject,TempString);
						TextEditHasBeenSaved(Window->NameEdit);
					}
				 else
					{
						SuccessFlag = False;
					}
			}

		if (TextEditDoesItNeedToBeSaved(Window->OriginEdit))
			{
				SampleObjectPutOrigin(Window->SampleObject,SampleWindowGetOrigin(Window));
				TextEditHasBeenSaved(Window->OriginEdit);
			}

		if (TextEditDoesItNeedToBeSaved(Window->LoopStartEdit))
			{
				switch (Window->EditingWhichLoop)
					{
						default:
							EXECUTE(PRERR(ForceAbort,
								"DisposeSampleWindow:  bad value in EditingWhichLoop"));
							break;
						case eSampleLoop1:
							SampleObjectPutLoopStart1(Window->SampleObject,
								SampleWindowGetLoopStart(Window));
							break;
						case eSampleLoop2:
							SampleObjectPutLoopStart2(Window->SampleObject,
								SampleWindowGetLoopStart(Window));
							break;
						case eSampleLoop3:
							SampleObjectPutLoopStart3(Window->SampleObject,
								SampleWindowGetLoopStart(Window));
							break;
					}
				TextEditHasBeenSaved(Window->LoopStartEdit);
			}

		if (TextEditDoesItNeedToBeSaved(Window->LoopEndEdit))
			{
				switch (Window->EditingWhichLoop)
					{
						default:
							EXECUTE(PRERR(ForceAbort,
								"DisposeSampleWindow:  bad value in EditingWhichLoop"));
							break;
						case eSampleLoop1:
							SampleObjectPutLoopEnd1(Window->SampleObject,
								SampleWindowGetLoopEnd(Window));
							break;
						case eSampleLoop2:
							SampleObjectPutLoopEnd2(Window->SampleObject,
								SampleWindowGetLoopEnd(Window));
							break;
						case eSampleLoop3:
							SampleObjectPutLoopEnd3(Window->SampleObject,
								SampleWindowGetLoopEnd(Window));
							break;
					}
				TextEditHasBeenSaved(Window->LoopEndEdit);
			}

		if (TextEditDoesItNeedToBeSaved(Window->SamplingRateEdit))
			{
				SampleObjectPutSamplingRate(Window->SampleObject,
					SampleWindowGetSamplingRate(Window));
				TextEditHasBeenSaved(Window->SamplingRateEdit);
			}

		if (TextEditDoesItNeedToBeSaved(Window->NaturalFrequencyEdit))
			{
				SampleObjectPutNaturalFrequency(Window->SampleObject,
					SampleWindowGetNaturalFrequency(Window));
				TextEditHasBeenSaved(Window->NaturalFrequencyEdit);
			}

		if (TextEditDoesItNeedToBeSaved(Window->SampleExpressionEdit))
			{
				char*						TextTemp;

				TextTemp = SampleWindowGetFormulaCopy(Window);
				if (TextTemp != NIL)
					{
						SampleObjectNewFormula(Window->SampleObject,TextTemp);
						TextEditHasBeenSaved(Window->SampleExpressionEdit);
					}
				 else
					{
						SuccessFlag = False;
					}
			}

		if (!SampleWindowForceUpdateSampleObjectData(Window))
			{
				SuccessFlag = False;
			}

		return SuccessFlag;
	}


/* this routine updates the loop points when some number of sample frames are */
/* inserted or removed from the specified point.  (for removal, NumAddedFrames < 0) */
/* it does NOT do any redrawing of the points. */
void								SampleWindowShiftPoints(SampleWindowRec* Window, long Position,
											long NumAddedFrames)
	{
		long							Temp;

		CheckPtrExistence(Window);
		SampleWindowFinalizeCurrentEdit(Window);

		Temp = SampleObjectGetOrigin(Window->SampleObject);
		if (Temp >= Position)
			{
				Temp += NumAddedFrames;
				if (Temp < Position)
					{
						Temp = Position;
					}
				SampleObjectPutOrigin(Window->SampleObject,Temp);
				SampleWindowPutOrigin(Window,Temp);
			}

		Temp = SampleObjectGetLoopStart1(Window->SampleObject);
		if (Temp >= Position)
			{
				Temp += NumAddedFrames;
				if (Temp < Position)
					{
						Temp = Position;
					}
				SampleObjectPutLoopStart1(Window->SampleObject,Temp);
				if (Window->EditingWhichLoop == eSampleLoop1)
					{
						SampleWindowPutLoopStart(Window,Temp);
					}
			}

		Temp = SampleObjectGetLoopStart2(Window->SampleObject);
		if (Temp >= Position)
			{
				Temp += NumAddedFrames;
				if (Temp < Position)
					{
						Temp = Position;
					}
				SampleObjectPutLoopStart2(Window->SampleObject,Temp);
				if (Window->EditingWhichLoop == eSampleLoop2)
					{
						SampleWindowPutLoopStart(Window,Temp);
					}
			}

		Temp = SampleObjectGetLoopStart3(Window->SampleObject);
		if (Temp >= Position)
			{
				Temp += NumAddedFrames;
				if (Temp < Position)
					{
						Temp = Position;
					}
				SampleObjectPutLoopStart3(Window->SampleObject,Temp);
				if (Window->EditingWhichLoop == eSampleLoop3)
					{
						SampleWindowPutLoopStart(Window,Temp);
					}
			}

		Temp = SampleObjectGetLoopEnd1(Window->SampleObject);
		if (Temp >= Position)
			{
				Temp += NumAddedFrames;
				if (Temp < Position)
					{
						Temp = Position;
					}
				SampleObjectPutLoopEnd1(Window->SampleObject,Temp);
				if (Window->EditingWhichLoop == eSampleLoop1)
					{
						SampleWindowPutLoopEnd(Window,Temp);
					}
			}

		Temp = SampleObjectGetLoopEnd2(Window->SampleObject);
		if (Temp >= Position)
			{
				Temp += NumAddedFrames;
				if (Temp < Position)
					{
						Temp = Position;
					}
				SampleObjectPutLoopEnd2(Window->SampleObject,Temp);
				if (Window->EditingWhichLoop == eSampleLoop2)
					{
						SampleWindowPutLoopEnd(Window,Temp);
					}
			}

		Temp = SampleObjectGetLoopEnd3(Window->SampleObject);
		if (Temp >= Position)
			{
				Temp += NumAddedFrames;
				if (Temp < Position)
					{
						Temp = Position;
					}
				SampleObjectPutLoopEnd3(Window->SampleObject,Temp);
				if (Window->EditingWhichLoop == eSampleLoop3)
					{
						SampleWindowPutLoopEnd(Window,Temp);
					}
			}
	}
