/*·······························
 ·
 ·	XTWindows.c
 ·
 ·	
 ·
 ······························*/

#include <datatypes/datatypesclass.h>
#include <exec/memory.h>
#include <exec/execbase.h>
#include <intuition/gadgetclass.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <proto/input.h>
#include <proto/scalos.h>
#include <Scalos/Scalos.h>
#include <string.h>
#include <stdio.h>
#include "SCCMacros.h"
#include "AutoMsg.h"

__saveds __asm int						__UserLibInit( register __a6 struct Library *base );
__saveds __asm void						__UserLibCleanup( register __a6 struct Library *base );
__saveds __asm struct ScaClassInfo *LIBGetClassInfo( register __a6 struct Library *base );
SCC_DECLARE( XTWindows )


//#define DEBUG

ULONG						oldSegList;

struct ExecBase		*SysBase = NULL;
struct DosLibrary		*DOSBase = NULL;
struct IntuitionBase	*IntuitionBase = NULL;
struct Library			*ScalosBase = NULL;
struct Library			*InputBase = NULL;

struct AutoReplyPort	replyPort;


extern char __far _LibName[];

struct XTWindowsData {//FrexxStartFold1.2.0.
	struct ScaWindowTask	*windowTask;
};
//FrexxEndFold1.
struct ScaClassInfo	ci = {//FrexxStartFold1.2.0.
	0,0,0,0,0,
	0,
	0,
	39,
	0,
	"IconWindow.sca",
	"IconWindow.sca",
	"XTWindows class",
	"This class extends the windows functions",
	"David Rydh"
};
//FrexxEndFold1.


#ifdef DEBUG
BPTR	debugHandle = NULL;

void DPrintf( char *formatStr, ... ) {//FrexxStartFold1.2.0.
	char	str[256];

	vsprintf( str, formatStr, &formatStr + 1L );
	Write( debugHandle, str, strlen(str) );
}
#endif//FrexxEndFold1.

//·············································································
//  LibInit / LibCleanup
//·············································································

int __saveds __asm __UserLibInit( register __a6 struct Library *base ) {//FrexxStartFold1.2.0.
	SysBase = *(struct ExecBase **)4L;

	oldSegList = *(ULONG *)(base+1);
	*(ULONG *)(base+1) = *(ULONG *)"PLUG";

	if( !(DOSBase = (struct DosLibrary *)OpenLibrary( "dos.library", 37 )) ) {
		__UserLibCleanup( base );
		return 1;
	}

	if( !(IntuitionBase = (struct IntuitionBase *)OpenLibrary( "intuition.library", 37 )) ) {
		__UserLibCleanup( base );
		return 1;
	}

	if( !(ScalosBase = OpenLibrary( "scalos.library", 39 )) ) {
		__UserLibCleanup( base );
		return 1;
	}

	Disable();
	InputBase = (struct Library *)FindName(&SysBase->DeviceList, "input.device");
	Enable();

	if( !InputBase ) {
		__UserLibCleanup( base );
		return 1;
	}

	InitAutoReplyPort( &replyPort, ScalosBase );

#ifdef DEBUG
	debugHandle = Open( "CON:0/0/640/100/XTWindows output/AUTO/WAIT", MODE_NEWFILE );
#endif

	return 0;
}
//FrexxEndFold1.
void __saveds __asm __UserLibCleanup( register __a6 struct Library *base ) {//FrexxStartFold1.2.0.
	*(ULONG *)(base+1) = oldSegList;

#ifdef DEBUG
	if( debugHandle )
		Close( debugHandle );
#endif

	FreeAutoReplyPort( &replyPort );

	if( ScalosBase )
		CloseLibrary( (struct Library *)ScalosBase );
	if( IntuitionBase )
		CloseLibrary( (struct Library *)IntuitionBase );
	if( DOSBase )
		CloseLibrary( (struct Library *)DOSBase );
}
//FrexxEndFold1.

//·············································································
//  Main entry point
//·············································································

__saveds __asm struct ScaClassInfo *LIBGetClassInfo( register __a6 struct Library *base ) {//FrexxStartFold1.2.0.
	SCC_INIT( &ci, XTWindows, base )

	return &ci;
}
//FrexxEndFold1.

SCC( XTWindows ) {//FrexxStartFold1.2.0.

SCC_Method( OM_NEW ) {//FrexxStartFold2.2.0.
	obj = (Object *)DoSuperMethodA( cl,obj,msg );

	if( obj ) {
		SCC_InitData

		data->windowTask = ((struct ScaRootList *)obj)->rl_WindowTask;
	}

	return (ULONG)obj;
} SCC_Method_End
//FrexxEndFold2.
SCC_SCAMethod( Message ) {//FrexxStartFold2.2.0.
	if( methodMsg->IntuiMsg->Class == IDCMP_CLOSEWINDOW ) {
		if( PeekQualifier() & (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT) ) {
			BPTR	lock, windowLock;
			char	*name;

			// ······················· Open parentdrawer ··························
			data->windowTask = ((struct ScaRootList *)obj)->rl_WindowTask;
			lock = data->windowTask->mt_WindowStruct->ws_Lock;
			windowLock = ParentDir( lock );
			if( windowLock ) {
				name = AllocVec( 1000, 0 );
				if( name ) {
					if( NameFromLock( windowLock, name, 1000 ) ) {
						struct TagItem	tags[2] = { SCA_Path, 0, TAG_END };

						tags[0].ti_Data = (ULONG)name;
						SCA_OpenIconWindow( tags );
					}
					FreeVec( name );
				}
				UnLock( windowLock );
			}
		}
	}
	SCC_Method_SuperReturn

} SCC_SCAMethod_End
//FrexxEndFold2.

SCC_SCAMethodX( IconWin_Open ) {//FrexxStartFold2.2.0.
	if( !DoSuperMethodA( cl,obj,msg ) )
		return FALSE;

	if( PeekQualifier() & (IEQUALIFIER_LALT | IEQUALIFIER_RALT) ) {
		// ······················· Close window ··························
		struct SM_CloseWindow	*message;

		data->windowTask = ((struct ScaRootList *)obj)->rl_WindowTask;

		if( data->windowTask ) {
			message = (struct SM_CloseWindow *)SCA_AllocMessage( MTYP_CloseWindow, 0 );
			if( message ) {
				PutAutoMsg( data->windowTask->mt_WindowStruct->ws_MessagePort,
								&message->ScalosMessage.sm_Message, &replyPort );
			}
		}
	}


	return TRUE;
} SCC_SCAMethod_End
//FrexxEndFold2.
SCC_Method_SuperDefault

} SCC_End
//FrexxEndFold1.

