/*
 *  Copyright (c) 1994 Michael D. Bayne.
 *  All rights reserved.
 *
 *  Please see the documentation accompanying the distribution for distribution
 *  and disclaimer information.
 */

#include <exec/memory.h>
#include <utility/date.h>
#include <hardware/custom.h>

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

#include "/Garshnelib/Garshnelib_protos.h"
#include "/Garshnelib/Garshnelib_pragmas.h"

#include <string.h>

#include "Clock.h"
#include "//defs.h"
#include "/main.h"

extern __far struct Custom custom;

struct ModulePrefs
{
	LONG Mode;
	LONG Delay;
	LONG Cycle;
	LONG Secs;
	LONG Military;
	struct TextAttr Font;
	BYTE fName[64];
};

extern struct ModulePrefs nP;
LONG Hour[] = {12,1,2,3,4,5,6,7,8,9,10,11,12,1,2,3,4,5,6,7,8,9,10,11};

LONG getTime( BYTE *time, struct ModulePrefs *nP )
{
	struct DateStamp Stamp;
	struct ClockData Data;
	LONG pos = 0, hour;
	
	DateStamp( &Stamp );
	Amiga2Date((( Stamp.ds_Days * 1440 ) + Stamp.ds_Minute ) * 60 +
			   Stamp.ds_Tick/TICKS_PER_SECOND, &Data );
	
	if( !nP->Military )
		hour = Hour[Data.hour];
	else
		hour = Data.hour;

	if( hour > 9 )
		time[pos++] = ( BYTE )( hour / 10 ) + '0';
	time[pos++] = ( BYTE )( hour % 10 ) + '0';

	time[pos++] = ':';

	time[pos++] = ( BYTE )( Data.min / 10 ) + '0';
	time[pos++] = ( BYTE )( Data.min % 10 ) + '0';

	if( nP->Secs )
	{
		time[pos++] = ':';
		time[pos++] = ( BYTE )( Data.sec / 10 ) + '0';
		time[pos++] = ( BYTE )( Data.sec % 10 ) + '0';
	}

	if( !nP->Military )
	{
		if( Data.hour > 11 )
			time[pos++] = 'p';
		else
			time[pos++] = 'a';
		time[pos++] = 'm';
	}

	time[pos] = '\0';
	
	return ( LONG )strlen( time );
}

LONG Diff( BYTE *One, BYTE *Two )
{
	while( *One && *Two )
		if( *One++ != *Two++ )
			return TRUE;

	return *One != *Two;
}

LONG Blank( VOID *Prefs )
{
	struct TextFont *font;
	struct ModulePrefs *bP;
	struct Screen *Scr;
	struct Window *Wnd;
	struct RastPort *RP;
	struct ViewPort *VP;
	LONG vals[] = {
		1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 14, 13, 12, 11, 10,
		9, 8, 7, 6, 5, 4, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
	BYTE scrClock[32], oldClock[32];
	LONG ScrToFrontCnt=0, c1 = 0, c2 = 14, c3 = 28, delay, fonty, RetVal = OK;
	LONG x, y, Wid, Hei, len, nlen, numc, base, count = 0, dx = -1, dy = -1;
	
	if( ClockWnd )
		bP = &nP;
	else
		bP = ( struct ModulePrefs * )Prefs;
	
	delay = bP->Delay;
	
	bP->Font.ta_Name = bP->fName;
	font = OpenDiskFont(&( bP->Font ));
	if( !font )
	{
		strcpy( bP->fName, "topaz.font" );
		font = OpenDiskFont(&( bP->Font ));
	}
	base = font->tf_Baseline;
	fonty = bP->Font.ta_YSize;
	
	Scr = OpenScreenTags( 0l, SA_DisplayID, bP->Mode, SA_Depth, 1, SA_Quiet,
						 TRUE, SA_Behind, TRUE, SA_Overscan, OSCAN_STANDARD,
						 SA_Font, &( bP->Font ), TAG_DONE );
	if( Scr )
	{
		Wid = Scr->Width;
		Hei = Scr->Height;
		RP = &( Scr->RastPort );
		VP = &( Scr->ViewPort );
		
		SetRGB4( VP, 0, 0L, 0L, 0L );
		switch( bP->Cycle )
		{
		case 0:
			SetRGB4( VP, 1, vals[c1], vals[c2], vals[c3] );
			break;
		case 1:
			SetRGB4( VP, 1, ( ULONG )RangeRand( 15 ) + 1,
					( ULONG )RangeRand( 15 ) + 1,
					( ULONG )RangeRand( 15 ) + 1 );
			break;
		case 2:
			SetRGB4( VP, 1, 15, 15, 15 );
			break;
		case 3:
			setCopperList( Hei, 1, VP, &custom );
			break;
		}
		
		numc = getTime( scrClock, bP );
		while(( len = TextLength( RP, scrClock, numc )) >= Wid )
			numc--;
		
		x = ( Wid - len ) / 2;
		y = ( Hei - fonty ) / 2;
		
		SetAPen( RP, 1 );
		Move( RP, x, y + base );
		Text( RP, scrClock, numc );
		
		Wnd = BlankMousePointer( Scr );
		ScreenToFront( Scr );
		
		while( RetVal == OK )
		{
			WaitTOF();

			if(!( ScrToFrontCnt++ % ( 20 * bP->Secs ? 1 : 6 )))
			{
				numc = getTime( scrClock, bP );
				while(( nlen = TextLength( RP, scrClock, numc )) + x > Wid )
					numc--;
				if( Diff( oldClock, scrClock ))
				{
					Move( RP, x, y + base );
					Text( RP, scrClock, numc );
					
					if( nlen < len )
					{
						SetAPen( RP, 0 );
						RectFill( RP, x + nlen, y - 2, x + len + 2,
								 y + fonty + 2 );
						SetAPen( RP, 1 );
					}
					len = nlen;
					strcpy( oldClock, scrClock );
				}
			}
			
			if(!( ScrToFrontCnt % 60 ))
				ScreenToFront( Scr );

			if( !delay || !( ++count % delay ))
			{
				ScrollRaster( RP, dx, dy, x-2, y-2, x+len+2, y+fonty+2 );
				x -= dx;
				y -= dy;
				if( x < 3 )
					dx = -1;
				else
					if( x > Wid-len-3 )
						dx = 1;
				if( y < 3 )
					dy = -1;
				else
					if( y > Hei-fonty-3 )
						dy = 1;
			}

			if( !bP->Cycle )
			{
				if(!( count % 10 ))
				{
					c1 = ++c1 % 42;
					c2 = ++c2 % 42;
					c3 = ++c3 % 42;
					SetRGB4( VP, 1, vals[c1], vals[c2], vals[c3] );
				}
			}

			RetVal = ContinueBlanking();
		}
		if( bP->Cycle == 3 )
			clearCopperList( VP );
		UnblankMousePointer( Wnd );
		CloseScreen( Scr );
	}
	else
		RetVal = FAILED;
	
	if( font )
		CloseFont( font );
	
	return RetVal;
}
