/*
**	$Id: Monitor.c 1.1 1997/07/03 09:50:12 olsen Exp olsen $
**
**	:ts=4
*/

#include <intuition/intuition.h>

#include <graphics/gfxbase.h>
#include <graphics/gfxmacros.h>

#include <dos/dos.h>

#include <exec/memory.h>

#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <clib/exec_protos.h>
#include <clib/alib_protos.h>

#include <pragmas/intuition_pragmas.h>
#include <pragmas/graphics_pragmas.h>
#include <pragmas/exec_pragmas.h>

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

#include "clib/concierto_protos.h"
#include "pragmas/concierto_pragmas.h"
#include "libraries/concierto.h"

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

extern struct Library *	SysBase;

struct Library *		IntuitionBase;
struct Library *		GfxBase;

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

struct Library *		ConciertoBase;
struct AudioContext *	ac;

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

struct Window *			Window;
WORD *					Position;
WORD *					Position1;
WORD *					Position2;

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

VOID
PositionReset(VOID)
{
	LONG i;

	for(i = 0 ; i < Window->WScreen->Width ; i++)
		Position1[i] = Position2[i] = 32767;
}

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

VOID
CloseAll(VOID)
{
	if(ac != NULL)
		CTO_ReleaseAudioContext(ac);

	if(ConciertoBase != NULL)
		CloseLibrary(ConciertoBase);

	if(Window != NULL)
		CloseWindow(Window);

	if(Position != NULL)
		FreeVec(Position);

	if(GfxBase != NULL)
		CloseLibrary(GfxBase);

	if(IntuitionBase != NULL)
		CloseLibrary(IntuitionBase);
}

BOOL
OpenAll(VOID)
{
	IntuitionBase = OpenLibrary("intuition.library",37);
	if(IntuitionBase == NULL)
		return(FALSE);

	GfxBase = OpenLibrary("graphics.library",37);
	if(GfxBase == NULL)
		return(FALSE);

	ConciertoBase = OpenLibrary(CONCIERTONAME,0);
	if(ConciertoBase == NULL)
		return(FALSE);

	ac = CTO_ObtainAudioContext(0);
	if(ac == NULL)
		return(FALSE);

	Window = OpenWindowTags(NULL,
		WA_Title,			"Concierto sound monitor",
		WA_DragBar,			TRUE,
		WA_DepthGadget,		TRUE,
		WA_CloseGadget,		TRUE,
		WA_SizeGadget,		TRUE,
		WA_SimpleRefresh,	TRUE,
		WA_InnerWidth,		100,
		WA_InnerHeight,		40,
		WA_Activate,		TRUE,
		WA_RMBTrap,			TRUE,
		WA_IDCMP,			IDCMP_CLOSEWINDOW | IDCMP_NEWSIZE | IDCMP_SIZEVERIFY | IDCMP_REFRESHWINDOW,
	TAG_DONE);

	if(Window == NULL)
		return(FALSE);

	WindowLimits(Window,Window->BorderLeft + 60 + Window->BorderRight,
	                    Window->BorderTop  + 40 + Window->BorderBottom,
	                    Window->WScreen->Width,
	                    Window->WScreen->Height);

	Position = (WORD *)AllocVec(Window->WScreen->Width * sizeof(WORD) * 2,MEMF_ANY);
	if(Position == NULL)
		return(FALSE);

	Position1 = Position;
	Position2 = Position + Window->WScreen->Width;

	PositionReset();

	return(TRUE);
}

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

int
main(int argc,char **argv)
{
	if(OpenAll())
	{
		struct RastPort *RPort;
		struct IntuiMessage *Message;
		ULONG MsgClass;
		ULONG Mask;
		WORD Index,Left,Top,Width,Height,Value;
		UBYTE OriginalSource;
		BOOL Done;
		struct Task *ThisTask;
		LONG OldPriority;

		Mask = 1UL << Window->UserPort->mp_SigBit;

		Index	= 0;
		Left	= Window->BorderLeft;
		Top		= Window->BorderTop;
		Width	= Window->Width - (Window->BorderLeft + Window->BorderRight);
		Height	= Window->Height - (Window->BorderTop + Window->BorderBottom);

		RPort = Window->RPort;

		if(GfxBase->lib_Version >= 39)
			SetMaxPen(RPort,1);
		else
			SetWrMsk(RPort,1);

		SetAPen(RPort,0);
		SetDrMd(RPort,JAM1);
		RectFill(RPort,Left,Top,Left + Width - 1,Top + Height - 1);
		SetAPen(RPort,1);

		CTO_LockAudioContext(ac);
		OriginalSource = CTO_SetRecordingSource(ac,RECORDSRC_Mixer);

		ThisTask = FindTask(NULL);
		OldPriority = SetTaskPri(ThisTask,-1);

		do
		{
			Done = FALSE;

			Value = Top + (Height / 2) + ((Height / 2) * CTO_DirectReadSample8(ac)) / 128;

			if(Index == 0)
			{
				Position2[Index] = Value;

				SetAPen(RPort,0);
				RectFill(RPort,Left,Top,Left + 1,Top + Height - 1);
				SetAPen(RPort,1);
			}
			else
			{
				if(Index + 1 < Width && Position1[Index + 1 != 32767])
				{
					SetAPen(RPort,0);
					Move(RPort,Left + Index,Position1[Index + 1]);
					Draw(RPort,Left + Index + 1,Position2[Index + 1]);
					SetAPen(RPort,1);
				}

				Position1[Index] = Position2[Index - 1];

				Move(RPort,Left + Index - 1,Position1[Index]);
				Draw(RPort,Left + Index,Position2[Index] = Value);
			}

			if(++Index == Width)
				Index = 0;

			if(SetSignal(0,Mask) & Mask)
			{
				while((Message = (struct IntuiMessage *)GetMsg(Window->UserPort)) != NULL)
				{
					MsgClass = Message->Class;

					ReplyMsg((struct Message *)Message);

					switch(MsgClass)
					{
						case IDCMP_REFRESHWINDOW:

							BeginRefresh(Window);
							EndRefresh(Window,TRUE);

							/* FALLS THROUGH TO */

						case IDCMP_NEWSIZE:

							Width	= Window->Width - (Window->BorderLeft + Window->BorderRight);
							Height	= Window->Height - (Window->BorderTop + Window->BorderBottom);

							SetAPen(RPort,0);
							RectFill(RPort,Left,Top,Left + Width - 1,Top + Height - 1);
							SetAPen(RPort,1);

							PositionReset();

							Index = 0;

							break;

						case IDCMP_CLOSEWINDOW:

							Done = TRUE;
							break;
					}
				}
			}

			if(SetSignal(0,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
				Done = TRUE;
		}
		while(NOT Done);

		SetTaskPri(ThisTask,OldPriority);

		CTO_SetRecordingSource(ac,OriginalSource);
		CTO_UnlockAudioContext(ac);
	}

	CloseAll();

	return(0);
}
