/*
 *  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 <dos/dostags.h>
/*#include <graphics/displayinfo.h>*/
#include <strings.h>

#include "includes.h"
#include "libraries.h"
#include "protos/protos.h"

struct Screen *ServerScr;
struct Window *Wnd;

VOID InternalBlank( VOID )
{
	if( !ServerScr )
	{
		ServerScr = OpenScreenTags( 0L, SA_DisplayID, getTopScreenMode(),
								   SA_Depth, 1, SA_Behind, 1, TAG_END );
		if( ServerScr )
		{
			Wnd = 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 );
			/* Stealthimania */
			ClientMsg->bm_Mess.mn_Node.ln_Name = ( UBYTE * )( &Blanking );
			ClientMsg->bm_Type = Type;
			PutMsg( ClientPort, ( struct Message * )ClientMsg );
			return;
		}
	}
	
	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 );
}

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;
}
