/* SynthProgressWindow.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 "SynthProgressWindow.h"
#include "Memory.h"
#include "Screen.h"
#include "Numbers.h"
#include "DataMunging.h"
#include "EventLoop.h"


#define WINDOWWIDTH (300)
#define WINDOWHEIGHT (3 + 3 + 4 * GetFontHeight(GetScreenFont(),9))


struct SynthWinRec
	{
		WinType*						ScreenID;
		double							LastTimerValue;
		OrdType							FontHeight;
		FontType						ScreenFont;
		long								CallCountdown;
		long								CallCountReset;
		MyBoolean						ShowClippedSamples;
	};


static void					WindowUpdateRoutine(SynthWinRec* Window)
	{
		CheckPtrExistence(Window);
	}


/* create a new synth window record */
SynthWinRec*				NewSynthWindow(long MinCallCount, MyBoolean ShowClippedSamples)
	{
		SynthWinRec*			Window;

		Window = (SynthWinRec*)AllocPtrCanFail(sizeof(SynthWinRec),"SynthWinRec");
		if (Window == NIL)
			{
			 FailurePoint1:
				return NIL;
			}

		Window->ScreenID = MakeNewWindow(eModelessDialogWindow,eWindowNotClosable,
			eWindowNotZoomable,eWindowNotResizable,DialogLeftEdge(WINDOWWIDTH),
			DialogTopEdge(WINDOWHEIGHT),WINDOWWIDTH,WINDOWHEIGHT,
			(void (*)(void*))&WindowUpdateRoutine,Window);
		if (Window->ScreenID == NIL)
			{
			 FailurePoint2:
				ReleasePtr((char*)Window);
				goto FailurePoint1;
			}
		SetWindowName(Window->ScreenID,"Progress");

		Window->FontHeight = GetFontHeight(GetScreenFont(),9);
		Window->ScreenFont = GetScreenFont();
		Window->LastTimerValue = ReadTimer();
		Window->CallCountdown = 0;
		Window->CallCountReset = MinCallCount;
		Window->ShowClippedSamples = ShowClippedSamples;

		PerformDeferredUpdates(); /* update our windows before we start */
		RelinquishCPUCheckCancel(); /* let other programs update too */

		SetWatchCursor();
		DrawTextLine(Window->ScreenID,Window->ScreenFont,9,"Preparing...",12,3,3,ePlain);
		DrawTextLine(Window->ScreenID,Window->ScreenFont,9,"Press Escape To Abort",
			21,3,3 + 3 * Window->FontHeight,eBold);

		return Window;
	}


/* dispose of a synth window record */
void								DisposeSynthWindow(SynthWinRec* Window)
	{
		CheckPtrExistence(Window);
		KillWindow(Window->ScreenID);
		ReleasePtr((char*)Window);
	}


/* update the information in the synth window */
void								UpdateSynthWindow(SynthWinRec* Window, long SamplingRate,
											long TotalSamples, long TotalClippedSamples, MyBoolean ForceRedraw)
	{
		char*							StringTemp;
		double						TimerValue;

		CheckPtrExistence(Window);

		/* delay so we don't call ReadTimer() all the time */
		Window->CallCountdown -= 1;
		if (!ForceRedraw && (Window->CallCountdown >= 0))
			{
				return;
			}
		Window->CallCountdown = Window->CallCountReset;

		/* make sure we were called at least 1 real seconds ago. */
		TimerValue = ReadTimer();
		if (!ForceRedraw && (ReadTimer() - Window->LastTimerValue < 1))
			{
				return;
			}
		Window->LastTimerValue = TimerValue;

		/* we can do this since none of the data is in an inconsistent state (or even */
		/* altered) during playback. */
		PerformDeferredUpdates();

		StringTemp = StringToBlockCopy("Elapsed Song Time (Seconds):  ");
		if (StringTemp != NIL)
			{
				char*							TimeStr;

				TimeStr = LongDoubleToString((long double)TotalSamples / SamplingRate,5,.01,1e8);
				if (TimeStr != NIL)
					{
						char*							Combined;

						Combined = ConcatBlockCopy(StringTemp,TimeStr);
						if (Combined != NIL)
							{
								DrawTextLine(Window->ScreenID,Window->ScreenFont,9,Combined,
									PtrSize(Combined),3,3,ePlain);
								DrawBoxErase(Window->ScreenID,3 + LengthOfText(Window->ScreenFont,9,
									Combined,PtrSize(Combined),ePlain),3,WINDOWWIDTH,Window->FontHeight);
								ReleasePtr(Combined);
							}
						ReleasePtr(TimeStr);
					}
				ReleasePtr(StringTemp);
			}

		StringTemp = StringToBlockCopy("Total Generated Frames:  ");
		if (StringTemp != NIL)
			{
				char*							SamplesStr;

				SamplesStr = IntegerToString(TotalSamples);
				if (SamplesStr != NIL)
					{
						char*							Combined;

						Combined = ConcatBlockCopy(StringTemp,SamplesStr);
						if (Combined != NIL)
							{
								DrawTextLine(Window->ScreenID,Window->ScreenFont,9,Combined,
									PtrSize(Combined),3,3 + Window->FontHeight,ePlain);
								DrawBoxErase(Window->ScreenID,3 + LengthOfText(Window->ScreenFont,9,
									Combined,PtrSize(Combined),ePlain),3 + Window->FontHeight,
									WINDOWWIDTH,Window->FontHeight);
								ReleasePtr(Combined);
							}
						ReleasePtr(SamplesStr);
					}
				ReleasePtr(StringTemp);
			}

		if (Window->ShowClippedSamples)
			{
				StringTemp = StringToBlockCopy("Total Clipped Sample Points:  ");
				if (StringTemp != NIL)
					{
						char*							SamplesStr;

						SamplesStr = IntegerToString(TotalClippedSamples);
						if (SamplesStr != NIL)
							{
								char*							Combined;

								Combined = ConcatBlockCopy(StringTemp,SamplesStr);
								if (Combined != NIL)
									{
										DrawTextLine(Window->ScreenID,Window->ScreenFont,9,Combined,
											PtrSize(Combined),3,3 + 2 * Window->FontHeight,ePlain);
										DrawBoxErase(Window->ScreenID,3 + LengthOfText(Window->ScreenFont,9,
											Combined,PtrSize(Combined),ePlain),3 + 2 * Window->FontHeight,
											WINDOWWIDTH,Window->FontHeight);
										ReleasePtr(Combined);
									}
								ReleasePtr(SamplesStr);
							}
						ReleasePtr(StringTemp);
					}
			}

		DrawTextLine(Window->ScreenID,Window->ScreenFont,9,"Press Escape To Abort",
			21,3,3 + 3 * Window->FontHeight,eBold);

		SetWatchCursor();
	}
