/*
          Cwin - Size the CLI window.

          Original effort by Fabio Rossetti.

          (c) 1989 by Fabio Rossetti

	  To compile under Lattice C v5.0x use:

		lc -O -cus -v cwin.c
		blink from lib:cres.o cwin.o to cwin lib lib:a.lib lib:lc.lib sd nd

*/

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

#include <devices/console.h>
#include <devices/conunit.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <libraries/arpbase.h>

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

#include <arpfunctions.h>
#include <proto/exec.h>
#include <proto/intuition.h>

struct MsgPort iorp = {
    {0, 0, NT_MSGPORT, 0, 0}, 0,
    -1,				/* initialize signal to -1 */
    0,
				/* start with empty list */
    {&iorp.mp_MsgList.lh_Tail, 0, &iorp.mp_MsgList.lh_Head, 0, 0}
};

struct IOStdReq ior = {
    {{0, 0, 0, 0, 0}, &iorp, 0},
    0				/* device is zero */
};

struct Window *W;
struct ArpBase *ArpBase;
struct IntuitionBase *IntuitionBase;

VOID Cleanup(code)
{
    if (ior.io_Device != 0) {
	if (iorp.mp_SigBit != -1) {
	    FreeSignal(iorp.mp_SigBit);
	}
	CloseDevice(&ior);
    }
	CloseLibrary((struct Library*)ArpBase);  
    exit(code);
}

/* bulletproofly obtain a pointer to the CLI window sending a ACTION_DISK_INFO
   packet to the console process and looking into InfoData */
struct Window *GetWin()

{
	struct MsgPort *con;
	struct StandardPacket *packet=NULL;
	struct InfoData *id=NULL;

	/* open the console device */
	if ((OpenDevice("console.device", -1, &ior, 0)) != 0) {
	Cleanup(RETURN_FAIL);
	}

	/* set up the message port in the I/O request */
	if ((iorp.mp_SigBit = AllocSignal(-1)) < 0) {
	Cleanup(RETURN_FAIL);
	}
	iorp.mp_SigTask = (struct Task*)FindTask(NULL);

	/* try to find console associated with calling process */
	/* if started from CLI, than is  */
	if ((iorp.mp_SigTask->tc_Node.ln_Type == NT_PROCESS)) {
	con = (struct MsgPort *) 
		((struct Process *) iorp.mp_SigTask) -> pr_ConsoleTask;
	if (con != 0) {
		if ((packet = (struct StandardPacket *)
			ArpAlloc(sizeof(*packet)))) {
		if ((id = (struct id *) ArpAlloc(sizeof(*id)))) {
			/* this is the console handlers packet port */
			packet->sp_Msg.mn_Node.ln_Name = &(packet->sp_Pkt);
			packet->sp_Pkt.dp_Link = &(packet->sp_Msg);
			packet->sp_Pkt.dp_Port = &iorp;
			packet->sp_Pkt.dp_Type = ACTION_DISK_INFO;
			packet->sp_Pkt.dp_Arg1 = ((ULONG) id) >> 2;
			PutMsg(con, packet);
		 	WaitPort(&iorp);
			/* Pointer to console window, all we need..*/
			return( (struct Window*)(id->id_VolumeNode));
		}
	}
	}
	/* error */
	return((struct Window *)-1);
}
}

VOID MemCleanup()
{
}

VOID _main(Line)

STRPTR Line;

{
	

	
	LONG argc,val;
	STRPTR argv[7];
	WORD sdx=0,sdy=0,mdx=0,mdy=0;

	if(!(ArpBase = (struct ArpBase*)OpenLibrary(ArpName,ArpVersion))) exit(20);
	
	IntuitionBase = ArpBase->IntuiBase;

	/* parse command line */
	for (argc=0;argc < 7;++argc)
		argv[argc] = (STRPTR) NULL;

	while(*Line > ' ')
		++Line;

	argc = GADS(++Line,
			strlen(Line),
"\nUsage: Cwin BIG=B | SMALL=S | INFO=I\n       Cwin LeftEdge|# TopEdge|# Width|MAX|# Height|MAX|#\n",
			argv,
"BIG=B/S,SMALL=S/S,INFO=I/S,LEFTEDGE,TOPEDGE,WIDTH,HEIGHT");

	if ((W = GetWin()) == (struct Window *)-1) Cleanup(RETURN_FAIL);

		if (argv[2]) {
		/* There will be a 16384^2 Amiga :) ?
		   Cwin will be there anyway...*/
		Printf("%05ld %05ld %05ld %05ld %s\n",
			W->LeftEdge,
			W->TopEdge,
			W->Width,
			W->Height,
			W->Title);
		Cleanup(RETURN_OK);
			}

	
		/* expand window */
		if (argv[0]) {
		MoveWindow(W,(-W->LeftEdge),(-W->TopEdge));
		Delay(7);
		SizeWindow(W,(((W->WScreen)->Width)-(W->Width)),
			(((W->WScreen)->Height)-(W->Height)));

		WindowToFront(W);
		Cleanup(RETURN_OK);

		}

		/* iconify window */
		if (argv[1])

		{

		SizeWindow(W,((W->MinWidth)-(W->Width)),
			((W->MinHeight)-(W->Height)));
	Cleanup(RETURN_OK);
		    	
		}

	/* size window */
	if (argc > 3) {
	
		/* leftedge */
		val = Atol(argv[3]);	
		if (!(Errno==ERRBADINT) && (val >= 0) && 
			(val+W->Width <= W->WScreen->Width)) 
			mdx = val-W->LeftEdge;
			Errno = NULL;

		val = Atol(argv[4]);	
		if (!(Errno==ERRBADINT) && (val >= 0) && 
			(val+W->Height <= W->WScreen->Height)) 
			mdy = val-W->TopEdge;
			Errno = NULL;
	
		if (Strcmp(argv[5],"MAX")) {
		val = Atol(argv[5]);	
		if (!(Errno==ERRBADINT) && (val >= W->MinWidth) && 
			(val+W->LeftEdge <= W->WScreen->Width))
			sdx = val-W->Width;
		Errno = NULL;
			}
		else sdx = (((W->WScreen)->Width)-(W->Width));
	
	if (Strcmp(argv[6],"MAX")) {
		val = Atol(argv[6]);	
	if (!(Errno==ERRBADINT) && (val >= W->MinHeight) && 
			(val+W->TopEdge <= W->WScreen->Height))
			sdy = val-W->Height;
		Errno = NULL;
			}
	else sdy = (((W->WScreen)->Height)-(W->Height));
		MoveWindow(W,mdx,mdy);
		Delay(7);
		SizeWindow(W,sdx,sdy);
	
		 }   
		else Puts("Error: Too few arguments");			    		    
		
	Cleanup(RETURN_OK);
}

