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

#include <exec/types.h>
#include <exec/memory.h>
#include <exec/ports.h>

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

#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
#include <libraries/reqtools.h>

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

#include <stdlib.h>

#include "Blanker.h"
#include "Blanker_rev.h"
#include "defs.h"

STATIC const UBYTE VersTag[] = VERSTAG;

#include "protos/cxhand.h"
#include "protos/prefs.h"
#include "protos/winhand.h"
#include "protos/messaging.h"
#include "protos/timer.h"

__far   extern  ULONG   RangeSeed;
        LONG            blankSig, unblankSig, rc;
        ULONG           tags[] = { RT_Window, 0L, RT_LockWindow, TRUE, TAG_END, 0L, TAG_END };
struct  IntuitionBase   *IntuitionBase = 0L;
struct  GfxBase         *GfxBase = 0L;
struct  ReqToolsBase    *ReqToolsBase = 0L;
struct  Library         *CxBase = 0L, *IconBase = 0L, *GadToolsBase = 0L, *UtilityBase = 0L, *WorkbenchBase = 0L,
                        *IFFParseBase = 0L;
struct  Task            *Task = 0L;
struct  MsgPort         *blankerPort = 0L, *modulePort = 0L, *appWinPort = 0L;
struct  AppWindow       *blankerAppWin = 0L;
struct  RandomPrefsList *rPL = 0L;
struct  BlankerPrefs    *bPrefs;

VOID closeMainWindow( VOID )
{
        while( blankerAppWin ) if( RemoveAppWindow( blankerAppWin )) blankerAppWin = 0L;
        CloseBlankerWindow();
        tags[1] = 0L;
}

LONG openMainWindow( VOID )
{
        ULONG   lock, scr = 0;

        if( !BlankerWnd ) {
                if( SetupScreen()) return( 1 );
                OpenBlankerWindow();
                tags[1] = ( ULONG )BlankerWnd;
                CloseDownScreen();
                blankerAppWin = AddAppWindow( 1L, 0L, BlankerWnd, appWinPort, 0L );
        } else {
                ActivateWindow( BlankerWnd );
                if( BlankerWnd->WScreen->FirstWindow != BlankerWnd ) WindowToFront( BlankerWnd );
        }
        if( !BlankerWnd ) return( QUIT );
        else {
                lock = LockIBase( 0 );
                scr = ( IntuitionBase->FirstScreen != BlankerWnd->WScreen );
                UnlockIBase( lock );
                if( scr ) ScreenToFront( BlankerWnd->WScreen );
        }
        setPrefs( bPrefs, Blanker_CNT );
        return( OK );
}

VOID exitBlanker( LONG exitValue )
{
        struct Message *cleanMsg;

        if( modulePort ) sendModMsg( BM_DOQUIT, modulePort );

        closeMainWindow();

        if( bPrefs ) FreeVec( bPrefs );

        if( rPL ) {
                FreeRPList( rPL );
                FreeVec( rPL );
        }

        if( appWinPort ) {
                while( cleanMsg = GetMsg( appWinPort )) ReplyMsg( cleanMsg );
                DeletePort( appWinPort );
        }

        if( blankerPort ) DeletePort( blankerPort );

        ShutdownCX();

        FreeSignal( blankSig );

        if( IFFParseBase ) CloseLibrary( IFFParseBase );
        if( UtilityBase ) CloseLibrary( UtilityBase );
        if( WorkbenchBase ) CloseLibrary( WorkbenchBase );
        if( ReqToolsBase ) CloseLibrary(( struct Library * )ReqToolsBase );
        if( IconBase ) CloseLibrary( IconBase );
        if( CxBase ) CloseLibrary( CxBase );
        if( GfxBase ) CloseLibrary(( struct Library * )GfxBase );
        if( GadToolsBase ) CloseLibrary( GadToolsBase );
        if( IntuitionBase ) CloseLibrary(( struct Library * )IntuitionBase );

        exit( exitValue );
}
                
#ifdef DICE
VOID Kludge( VOID ) { _waitwbmsg(); }

VOID main( int argc, char *argv[] )
{
extern  struct WBStartup        *_WBMsg;
        struct WBStartup        *WBSMsg = _WBMsg;
#else
VOID main( int argc, char *argv[] )
{
        struct WBStartup        *WBSMsg = 0L;
#endif
	struct Task		*tTask = 0L;
	struct MsgPort		*tmpPort = 0L;
        struct AppMessage       *AppMsg;
        ULONG                   sigs;
        LONG                    retval = 1;

        if(!( IntuitionBase = ( struct IntuitionBase * )OpenLibrary( "intuition.library", 37L ))) exitBlanker( 1L );
        if(!( GfxBase = ( struct GfxBase * )OpenLibrary( "graphics.library", 37L ))) exitBlanker( 1L );
        if(!( GadToolsBase = OpenLibrary( "gadtools.library", 37L ))) exitBlanker( 1L );
        if(!( CxBase = OpenLibrary( "commodities.library", 37L ))) exitBlanker( 1L );
        if(!( IconBase = OpenLibrary( "icon.library", 36L ))) exitBlanker( 1L );
        if(!( ReqToolsBase = ( struct ReqToolsBase * )OpenLibrary( REQTOOLSNAME, REQTOOLSVERSION ))) exitBlanker( 1L );
        if(!( WorkbenchBase = OpenLibrary( WORKBENCH_NAME, 37L ))) exitBlanker( 1L );
        if(!( UtilityBase = OpenLibrary( "utility.library", 37L ))) exitBlanker( 1L );
        if(!( IFFParseBase = OpenLibrary( "iffparse.library", 37L ))) exitBlanker( 1L );

        if(!( bPrefs = AllocVec( sizeof( struct BlankerPrefs ), MEMF_CLEAR ))) exitBlanker( 2L );
        if(!( rPL = AllocVec( sizeof( struct RandomPrefsList ), MEMF_CLEAR ))) exitBlanker( 2L );

        RangeSeed = (ULONG)( Task = FindTask( 0L ));

        if(( blankSig = ( ULONG )AllocSignal( -1L )) == -1 ) exitBlanker( 3L );
        cxBlankFlag = 1L << blankSig;

        if( CheckCX() == QUIT ) exitBlanker( 3L );

        if(!( blankerPort = CreatePort( "BlankerCC", 0 ))) exitBlanker( 4L );
        if(!( appWinPort = CreatePort( 0L, 0 ))) exitBlanker( 4L );

        rc = loadPrefsFromENVARC( bPrefs );
#ifdef DICE
        if( WBSMsg &&( WBSMsg->sm_NumArgs > 1 ))
#else
	if(( !argc )&&( WBSMsg = ( struct WBStartup * )argv )&&( WBSMsg->sm_NumArgs > 1 ))
#endif
		rc = loadPrefsFromWBArgList( &( WBSMsg->sm_ArgList[1] ), WBSMsg->sm_NumArgs-1, bPrefs );
	if( rc ) prefError( rc );

	if( SetupCX() == QUIT ) exitBlanker( 5L );

        if( bPrefs->bp_PopUp ) retval = openMainWindow();

	while( retval ) {
		sigs = Wait( cxBlankFlag | cxSigFlag | SIG_WIN | SIG_BREAK | SIG_APP );

                if( sigs & cxBlankFlag ) {
			if(( bPrefs->bp_RandTimeout )&&( tTask = bTask )&&( tmpPort = modulePort )) {
				bTask = 0L;
				modulePort = 0L;
			}
                        if( bPrefs->bp_Flags & BS_RANDOM ) loadRandPrefs( rPL, bPrefs );
                        sendModMsg( BM_DOBLANK, modulePort );
			if( tTask ) {
				Delay( 60 );
				Signal( tTask, SIGBREAKF_CTRL_C );
				sendModMsg( BM_DOQUIT, tmpPort );
				tTask = 0L;
			}
                }
                if( sigs & cxSigFlag ) retval = handleCxMess();
                if( sigs & SIG_WIN ) retval = HandleBlankerIDCMP();
                if( sigs & SIG_BREAK ) retval = 0L;
                if( sigs & SIG_APP ) {
                        if( AppMsg = ( struct AppMessage * )GetMsg( appWinPort )) {
                                loadPrefsFromWBArgList( AppMsg->am_ArgList, AppMsg->am_NumArgs, bPrefs );
                                ReplyMsg(( struct Message * )AppMsg );
                        }
                }
                if( retval == CLOSEWIN ) closeMainWindow();
        }

        exitBlanker( 0L );
}
