/****************************************************************************
*
* VERSION
*	$VER: digital.c 1.60 (03.12.93)
*
* DESCRIPTION
*	The code for the digital clock...
*
* AUTHOR
*	Rune Johnsrud
*
* COPYRIGHT
*	(c) 1993 Amiga Freelancers
*
*****************************************************************************/

#define INTUI_V36_NAMES_ONLY

#include <exec/types.h>
#include <utility/date.h>

#include <proto/graphics.h>
#include <proto/intuition.h>
#include <proto/diskfont.h>
#include <proto/gadtools.h>

#include "global.h"

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

extern struct GlobalData *gd;
extern struct ClockInfo *ci;
extern struct Gadget ClockGadget;

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

UBYTE *Numbers[] =
{
	"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
};

UBYTE *Months[] =
{
	"Jan", "Feb", "Mar", "Apr", "May", "Jun",
	"Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
};

UWORD DateChars[] =
{
	11,		/* dd.mmm.yyyy	*/
	 9,		/* dd.mmm.yy	*/
	10,		/* dd.mm.yyyy	*/
	 8,		/* dd.mm.yy		*/
};

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

static VOID CalcWinDims(VOID);
WORD CreateDigitalClock(VOID);
VOID RefreshDigitalClock(VOID);
WORD DeleteDigitalClock(VOID);

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


static VOID CalcWinDims(VOID)
{
	UBYTE a;
	UWORD tx = 0, cw = 0, mw = 0, tsw = 0, dsw = 0;

	SetFont(&gd->FakeRP, gd->TextFont);

	ci->InnerHeight = gd->TextFont->tf_YSize + 2;

	for (a=0; a<10; a++)
	{
		tx = TextLength(&gd->FakeRP, Numbers[a], 1);
		if (tx > cw) cw = tx;
	}

	for (a=0; a<12; a++)
	{
		tx = TextLength(&gd->FakeRP, Months[a], 3);
		if (tx > mw) mw = tx;
	}

	tsw = TextLength(&gd->FakeRP, ci->TimeSep, 1);
	dsw = TextLength(&gd->FakeRP, ci->DateSep, 1);

	if (ci->ShowSec)
	{
		ci->InnerWidth = ((cw * 6) + (tsw * 2) + 6);
	}
	else
	{
		ci->InnerWidth = ((cw * 4) + tsw + 6);
	}

	ci->TimeWidth = ci->InnerWidth;

	if (ci->ShowDate)
	{
		ci->InnerWidth += ((dsw * 2) + (ci->DateSpc * cw));

		switch (ci->DateFormat)
		{
		case 0:
			tx = (mw + (cw * 6));
			break;
		case 1:
			tx = (mw + (cw * 4));
			break;
		case 2:
			tx = (cw * 8);
			break;
		case 3:
			tx = (cw * 6);
			break;
		}

		ci->InnerWidth += tx;
	}

	if (ci->InnerWidth > gd->VScreen->Width)
	{
		ci->InnerWidth = ci->TimeWidth;
		ci->ShowDate   = FALSE;

		Error("SClock", GEN_ERR_WINSIZE);
	}
}


WORD CreateDigitalClock(VOID)
{
	struct Gadget *g = &ClockGadget;
	struct RastPort *rp;

	if (gd->ClockWindow) CleanUpClock();

	gd->TextFont = OpenDiskFont(&gd->TextAttr);
	if (!gd->TextFont) return GEN_ERR_OPENFONT;

	gd->VScreen = LockPubScreen(ci->PubScreenName);
	if (!gd->VScreen) return GEN_ERR_LOCKSCREEN;

	gd->VisualInfo = GetVisualInfo(gd->VScreen, NULL);
	if (!gd->VisualInfo) return GEN_ERR_GETVISUALINFO;

	CalcWinDims();

	gd->ClockWindow = OpenWindowTags(NULL,
						WA_PubScreen,	gd->VScreen,
						WA_Top,			ci->Top,
						WA_Left,		ci->Left,
						WA_InnerWidth,	ci->InnerWidth,
						WA_InnerHeight,	ci->InnerHeight,
						WA_Activate,	TRUE,
						WA_Borderless,	TRUE,
						WA_Backdrop,	ci->BDClock,
						WA_DragBar,		FALSE,
						WA_NewLookMenus,TRUE,
						WA_IDCMP,		IDCMP_MENUPICK,
						TAG_DONE);

	if (!gd->ClockWindow) return GEN_ERR_OPENWINDOW;
	if (!InitMainMenus()) return GEN_ERR_MENUS;

	if (gd->VScreen)
	{
		UnlockPubScreen(NULL, gd->VScreen);
		gd->VScreen = NULL;
	}

	ci->InnerWidth--;
	ci->InnerHeight--;

	g->Width  		= ci->InnerWidth;
	g->Height 		= ci->InnerHeight;
	gd->ClockGadget = g;
	rp 				= gd->ClockWindow->RPort;

	gd->FillRP = *rp;
	SetAPen(&gd->FillRP, ci->BGPen);

	SetAPen(rp, ci->BGPen);
	RectFill(rp, 0, 0, ci->InnerWidth, ci->InnerHeight);

	if (ci->WinBevel)
	{
		SetAPen(rp, ci->ShinePen);
		Move(rp, 0, ci->InnerHeight);
		Draw(rp, 0, 0);
		Draw(rp, ci->InnerWidth, 0);

		SetAPen(rp, ci->ShadowPen);
		Move(rp, ci->InnerWidth, 1);
		Draw(rp, ci->InnerWidth, ci->InnerHeight);
		Draw(rp, 0, ci->InnerHeight);
	}

	SetABPenDrMd(rp, ci->TextPen, ci->BGPen, JAM2);
	SetFont(rp, gd->TextFont);

	gd->CData.year	= 0;
	gd->CData.month	= 0;
	gd->CData.mday	= 0;
	gd->CData.hour	= 99;
	gd->CData.min	= 99;
	gd->CData.sec	= 99;

	RefreshDigitalClock();

	AddGadget   (gd->ClockWindow, gd->ClockGadget, -1);
	RefreshGList(gd->ClockGadget, gd->ClockWindow, NULL, -1);

	return NOERROR;
}


VOID RefreshDigitalClock(VOID)
{
	struct RastPort *rp = gd->ClockWindow->RPort;
	UWORD x = 0;

	GetCurrSysTime();

	if (gd->NewTime)
	{
		if (ci->ShowSec) x = 8; else x = 5;

		Move(rp, 3, gd->TextFont->tf_Baseline + 1);
		Text(rp, gd->TimeStr, x);

		if (rp->cp_x <= (ci->TimeWidth - 1))
		{
			RectFill(&gd->FillRP, rp->cp_x, 1, ci->TimeWidth - 2, ci->InnerHeight - 1);
		}

		gd->NewTime = FALSE;
	}
	
	if ((ci->ShowDate) && (gd->NewDate))
	{
		RectFill(&gd->FillRP, rp->cp_x, 1, ci->InnerWidth - 1, ci->InnerHeight - 1);

		x = TextLength(rp, gd->DateStr, DateChars[ci->DateFormat]);

		Move(rp, (ci->InnerWidth - x - 2), gd->TextFont->tf_Baseline + 1);
		Text(rp, gd->DateStr, DateChars[ci->DateFormat]);

		gd->NewDate = FALSE;
	}
}


WORD DeleteDigitalClock(VOID)
{
	ci->Top  = gd->ClockWindow->TopEdge;
	ci->Left = gd->ClockWindow->LeftEdge;

	if (gd->VScreen)	 UnlockPubScreen(NULL, gd->VScreen);
	if (gd->ClockGadget) RemoveGadget(gd->ClockWindow, gd->ClockGadget);
	if (gd->TextFont)    CloseFont(gd->TextFont);
	if (gd->ClockWindow) ClearMenuStrip(gd->ClockWindow);
	if (gd->MainMenu)	 FreeMenus(gd->MainMenu);
	if (gd->VisualInfo)	 FreeVisualInfo(gd->VisualInfo);
	if (gd->ClockWindow) CloseWindow(gd->ClockWindow);

	gd->VScreen     = NULL;
	gd->ClockGadget = NULL;
	gd->VisualInfo  = NULL;
	gd->MainMenu    = NULL;
	gd->TextFont    = NULL;
	gd->ClockWindow = NULL;

	ci->ShowDate	= gd->TmpFlags;

	return NOERROR;
}

/* End Of File */
