/*
 * Copyright (c) 1993 Michael D. Bayne.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that
 * the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
 *    following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
 *    following disclaimer in the documentation and/or other materials provided with the distribution.
 *
 * 3. All advertising materials mentioning features or use of this software must display the following
 *    acknowledgement:
 *
 *       This product includes software developed by Michael D. Bayne.
 *
 * 4. My name may not be used to endorse or promote products derived from this software without specific prior
 *    written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY MICHAEL D. BAYNE ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL MICHAEL D. BAYNE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <exec/execbase.h>
#include <exec/memory.h>

#include <intuition/intuitionbase.h>
#include <intuition/screens.h>

#include <libraries/gadtools.h>
#include <libraries/reqtools.h>

#include <ctype.h>

#include "TaskE.h"
#include "defs.h"

#include "TaskE_rev.h"

static	UBYTE	*VersTag = VERSTAG;

extern	struct	ExecBase	*SysBase;
	struct	ReqToolsBase	*ReqToolsBase;
	struct	IntuitionBase	*IBase;
	struct	List		*taskList, *scrList;
	ULONG	Tags[] = { RTEZ_ReqTitle, (ULONG)VERS, RT_Window, 0L, RT_LockWindow, TRUE, RT_Underscore, '_', TAG_END },
		killMode = NONE, CXFlag;

void getScreens( struct List *scrList )
{
	struct	Screen	*Scr;
		ULONG	lock;
	struct	Node	*scrNode;
static		UBYTE	*noName = "Untitled Screen";

	GT_SetGadgetAttrs( TaskEGadgets[GD_SCREENL], TaskEWnd, 0l, 
		GTLV_Labels, 0l, TAG_DONE );

	while ( scrList->lh_TailPred != ( struct Node *)scrList ) {
		scrNode = RemHead( scrList );
		FreeMem( scrNode->ln_Name, 30 );
		FreeMem( scrNode, sizeof( struct Node ));
	}

	lock = LockIBase( 0 );

	for( Scr = IBase->FirstScreen; Scr; Scr = Scr->NextScreen ) {
		if( scrNode = AllocMem( sizeof( struct Node ), MEMF_CLEAR )) {
			if( Scr->DefaultTitle ) {
				if( scrNode->ln_Name = AllocMem( 30, MEMF_CLEAR )) {
					CopyMem( Scr->DefaultTitle, scrNode->ln_Name, 30 );
					AddTail( scrList, scrNode );
				} else break;
			} else scrNode->ln_Name = noName;
		} else break;
	}

	UnlockIBase( lock );

	GT_SetGadgetAttrs( TaskEGadgets[GD_SCREENL], TaskEWnd, 0l, 
		GTLV_Labels, scrList, TAG_DONE );
}

void getTasks( struct List *taskList )
{
	struct Node *execNode;
	struct TaskNode *taskNode;

	GT_SetGadgetAttrs( TaskEGadgets[GD_TASKL], TaskEWnd, 0l, GTLV_Labels, 0L, TAG_DONE );
	while ( taskList->lh_TailPred != ( struct Node *)taskList ) {
		taskNode = ( struct TaskNode * )RemHead( taskList );
		FreeMem( taskNode, sizeof( struct TaskNode ));
	}

        Disable();
	    
	for( execNode = (SysBase->TaskWait).lh_Head; execNode; execNode = execNode->ln_Succ ) {
		if(( execNode->ln_Name )&&( isgraph( execNode->ln_Name[0] ))) {
			if( taskNode = AllocMem( sizeof( struct TaskNode ), MEMF_CLEAR )) {
				CopyMem( execNode->ln_Name, taskNode->tn_Name, 31 );
				taskNode->tn_Name[31] = '\0';
				taskNode->tn_Node.ln_Pri = execNode->ln_Pri;
				taskNode->tn_TaskAddress = (ULONG)execNode;
				taskNode->tn_SigAlloc = (( struct Task * )execNode )->tc_SigAlloc;
				taskNode->tn_SigWait = (( struct Task * )execNode )->tc_SigWait;
				taskNode->tn_Node.ln_Name = taskNode->tn_Name;
				AddTail( taskList, ( struct Node * )taskNode );
			} else break;
		}
	}
	for( execNode = (SysBase->TaskReady).lh_Head; execNode; execNode = execNode->ln_Succ ) {
		if(( execNode->ln_Name )&&( isgraph( execNode->ln_Name[0] ))) {
			if( taskNode = AllocMem( sizeof( struct TaskNode ), MEMF_CLEAR )) {
				CopyMem( execNode->ln_Name, taskNode->tn_Name, 31 );
				taskNode->tn_Name[31] = '\0';
				taskNode->tn_Node.ln_Pri = execNode->ln_Pri;
				taskNode->tn_TaskAddress = (ULONG)execNode;
				taskNode->tn_SigAlloc = (( struct Task * )execNode )->tc_SigAlloc;
				taskNode->tn_SigWait = (( struct Task * )execNode )->tc_SigWait;
				taskNode->tn_Node.ln_Name = taskNode->tn_Name;
				AddTail( taskList, ( struct Node * )taskNode );
			} else break;
		}
	}

	Enable();
	GT_SetGadgetAttrs( TaskEGadgets[GD_TASKL], TaskEWnd, 0l, GTLV_Labels, taskList, TAG_DONE );
}

void taskExit( int retval )
{
	struct Node *Node;

	CloseTaskEWindow();
	CloseDownScreen();

	ShutdownCX();

	if( ReqToolsBase ) CloseLibrary(( struct Library * )ReqToolsBase );
	if( IBase ) CloseLibrary(( struct Library * )IBase );
	if( scrList ) {
		while ( scrList->lh_TailPred != ( struct Node *)scrList ) {
			Node = RemHead( scrList );
			FreeMem( Node->ln_Name, 30 );
			FreeMem( Node, sizeof( struct Node ));
		}
		FreeMem( scrList, sizeof( struct List ));
	}
	if( taskList ) {
		while ( taskList->lh_TailPred != ( struct Node *)taskList ) {
			Node = RemHead( taskList );
			FreeMem( Node, sizeof( struct TaskNode ));
		}
		FreeMem( taskList, sizeof( struct List ));
	}
	exit( retval );
}

void main( void )
{
	ULONG			retval = 1, sigs;

	if(!( ReqToolsBase = ( struct ReqToolsBase * )OpenLibrary( REQTOOLSNAME, REQTOOLSVERSION ))) taskExit( 3 );
	if(!( IBase = ( struct IntuitionBase * )OpenLibrary( "intuition.library", 37L ))) taskExit( 3 );

	if(!( taskList = AllocMem( sizeof( struct List ), MEMF_CLEAR ))) taskExit( 1 );
	if(!( scrList = AllocMem( sizeof( struct List ), MEMF_CLEAR ))) taskExit( 1 );
	NewList( taskList );
	NewList( scrList );

	if( SetupScreen()) taskExit( 4 );
	if( OpenTaskEWindow()) taskExit( 4 );

	Tags[3] = (ULONG)TaskEWnd;

	getScreens( scrList );
	getTasks( taskList );

	if(!( CXFlag = SetupCX())) taskExit( 5 );

	ScreenToFront( TaskEWnd->WScreen );

	while( retval ) {
		sigs = Wait( SIG_BREAK | SIG_WINDOW | CXFlag );
		if( sigs & SIG_WINDOW ) retval = HandleTaskEIDCMP();
		if( sigs & SIG_BREAK ) retval = 0;
		if( sigs & CXFlag ) retval = handleCxMess();
	}

	taskExit( 0 );
}
