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

#include <exec/memory.h>

#include <dos/dos.h>
#include <dos/dostags.h>

#include <graphics/displayinfo.h>
#include <libraries/commodities.h>

#include <intuition/intuitionbase.h>

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

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

#include <strings.h>

#include "defs.h"

#include "protos/main.h"
#include "protos/cxhand.h"
#include "protos/prefs.h"
#include "protos/winhand.h"

struct Screen *ServerScr;

#define GETTOPSCREENMODE
#define BLANKMOUSE
#include "Blankers/utility.c"

VOID InternalBlank( VOID )
{
	if( !ServerScr )
	{
		ServerScr = OpenScreenTags( 0L, SA_DisplayID, getTopScreenMode(), SA_Depth, 1,
								   SA_Behind, 1, TAG_END );
		if( ServerScr )
		{
			BlankMousePointer( ServerScr );
			SetRGB4(&( ServerScr->ViewPort ), 0, 0, 0, 0 );
			ScreenToFront( ServerScr );
			Blanking = TRUE;
		}
	}
}

VOID MessageModule( LONG Type )
{
	struct MsgPort *ClientPort;
	BlankMsg *ClientMsg;
	
	if( ClientPort = FindPort( "GarshneClient" ))
	{
		if( Type == BM_DOBLANK )
		{
			TimeOutIO->tr_node.io_Command = TR_ADDREQUEST;
			TimeOutIO->tr_time.tv_secs = 2;
			TimeOutIO->tr_time.tv_micro = 0;
			SendIO(( struct IORequest * )TimeOutIO );
		}
		
		if( ClientMsg = AllocVec( sizeof( BlankMsg ), MEMF_CLEAR|MEMF_PUBLIC ))
		{
			ClientMsg->bm_Mess.mn_ReplyPort = ServerPort;
			ClientMsg->bm_Mess.mn_Length = sizeof( BlankMsg );
			ClientMsg->bm_Type = Type;
			PutMsg( ClientPort, ( struct Message * )ClientMsg );
			return;
			}
	}
	else
		Prefs->bp_Flags &= ~BF_VALIDMOD;
	
	if( Type == BM_DOBLANK )
		InternalBlank();
}

VOID LoadModule( STRPTR Dir, STRPTR Module )
{
	BPTR in = Open( "NIL:", MODE_OLDFILE );
	BPTR out = Open( "NIL:", MODE_OLDFILE );
	BYTE Path[256];
	
	if( !Stricmp( Module, "Random" ))
		Module = RandomModule();
	strcpy( Path, Dir );
	AddPart( Path, Module, 256 );
	
	if( in && out )
		if( SystemTags( Path, NP_Priority, -5, SYS_Asynch, TRUE, SYS_Input, in, SYS_Output, out,
					   TAG_END ) != -1 )
			return;
	
	if( in )
		Close( in );
	if( out )
		Close( out );
	
	Prefs->bp_Flags &= ~BF_VALIDMOD;
}

BlankerEntry *NewBlankerEntry( STRPTR Path, STRPTR Name )
{
	BlankerEntry *New = AllocVec( sizeof( BlankerEntry ), MEMF_CLEAR );

	if( New )
	{
		strcpy( New->be_Path, Path );
		AddPart( New->be_Path, Name, 128 );
		New->be_Name = FilePart( New->be_Path );
		New->be_Node.ln_Name = New->be_Name;
	}

	return New;
}

LONG FileIsModule( STRPTR Path, STRPTR Name )
{
	LONG Length = strlen( Name );
	
	if(!( Stricmp(&( Name[Length-5] ), ".info" )))
		return FALSE;
	
	if(!( Stricmp(&( Name[Length-6] ), ".prefs" )))
		return FALSE;
	
	if(!( Stricmp(&( Name[Length-4] ), ".txt" )))
		return FALSE;
	
	return TRUE;
}

VOID FreeBlankerEntries( struct List *Entries )
{
	BlankerEntry *FreeMe;

	if( !Entries )
		return;

	while( FreeMe = ( BlankerEntry * )RemHead( Entries ))
		FreeVec( FreeMe );

	FreeVec( Entries );
}

struct List *LoadBlankerEntries( STRPTR Path )
{
	struct FileInfoBlock *Blk;
	struct List *Entries;
	BPTR DirLock;

	if(!( Entries = AllocVec( sizeof( struct List ), MEMF_CLEAR )))
		return 0L;
	else
		NewList( Entries );

	if( DirLock = Lock( Path, ACCESS_READ ))
	{
		if(( Blk = AllocDosObject( DOS_FIB, 0L ))&&( Examine( DirLock, Blk )))
		{
			BlankerEntry *New;

			while( ExNext( DirLock, Blk ))
			{
				if(( Blk->fib_FileName )&&( FileIsModule( Path, Blk->fib_FileName )))
				{
					if( New = NewBlankerEntry( Path, Blk->fib_FileName ))
					{
						New->be_Node.ln_Pri = 128 -
							(( New->be_Name[0] == '(' ? New->be_Name[1] : New->be_Name[0] )
							 - 'a' );
						Enqueue( Entries, ( struct Node * )New );
					}
				}
			}
			FreeDosObject( DOS_FIB, Blk );

			if( New = NewBlankerEntry( ":", "Random" ))
				AddTail( Entries, ( struct Node * )New );
		}
		UnLock( DirLock );
	}
	
	return Entries;
}
