/* ResetClient.c (c) 1997 Paweî Marciniak <pmarciniak@lodz.home.pl>*/
#include <stdio.h>
#include <string.h>
#include <exec/execbase.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <libraries/gadtools.h>
#include <graphics/text.h>
#include <graphics/gfxbase.h>
#include <graphics/scale.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/gadtools.h>
#include <proto/diskfont.h>
#include <proto/dos.h>
#include <stdlib.h>

#include "APP_globals.h"
#include "resetserver.h"

extern struct ExecBase *SysBase;

ULONG signal=0L;
ULONG sigwin=0L;
ULONG sigmsg=0L;
UBYTE TextBufor[256];

/* Rozmiar Okna */

	WORD Width=440;
	WORD Height=22;
	WORD MinWidth=50;
	WORD MinHeight=30;
	WORD MaxWidth=1600;
	WORD MaxHeight=1200;

/* Zmienne ResetDemo */

#define PROGNAME "ResetClientDemo...!"

struct MsgPort *msgport, *destport;
struct RWMessage sendmsg, sendmsg2, sendmsg3, *msg;

/* Tytaj zaczynajâ sië wszystkie poûyteczne funkcje */


/* Funkcja otwiera okreôlony font */

int MakeGadget( void )
{
	if ( g = CreateContext( &APP_GList ))
	{
/* Warning */
		ng.ng_TopEdge		=	(ComputeY( 5 ) + OffY );
		ng.ng_LeftEdge	=	ComputeX( 10 ) + OffX;
		ng.ng_Width			=	ComputeX( 150 );
		ng.ng_Height		=	ComputeY( 12 );
		ng.ng_TextAttr		=	&ScreenFont;
		ng.ng_GadgetText=	"Welcom";
		ng.ng_GadgetID	=	GD_BUTTON;
		ng.ng_Flags		 	=	PLACETEXT_IN;
		ng.ng_VisualInfo	=	VisualInfo;
		ng.ng_UserData		=	NULL;
		if(!(gad_button = g = CreateGadget( BUTTON_KIND, g, &ng, GT_Underscore, '_', TAG_DONE )))
			return( FALSE );

/* Text komunikaty */
		ng.ng_TopEdge	  =	(ComputeY( 5 ) + OffY);
		ng.ng_LeftEdge	=	ComputeX( 170) + OffX;
		ng.ng_Width			=	ComputeX( 260 );
		ng.ng_Height		=	ComputeY( 12 );
		ng.ng_GadgetText=	"";
		ng.ng_GadgetID	=	GD_TEXT;
		if(!(gad_text = g = CreateGadget( TEXT_KIND, g, &ng, GTTX_Text, (ULONG)TextBufor,
																									 GTTX_Justification, GTJ_LEFT,
																									 GTTX_Border, TRUE,
																									 TAG_DONE )))
			return( FALSE );
		return( TRUE );
	}
return( FALSE );
}

int OpenFonts( void )
{
	if (!(APP_Font=OpenDiskFont( &ScreenFont )))
		return( FALSE );
	return( TRUE );
}


/* Funkcja zamyka otwarty font */

void CloseFonts( void )
{
	if ( APP_Font )	
	{
		CloseFont( APP_Font );
		APP_Font=NULL;
	}
}


UWORD ComputeX( UWORD value )
{
	return(( UWORD )((( FontX * value ) + 4 ) / 8 ));
}


UWORD ComputeY( UWORD value )
{
	return(( UWORD )((( FontY * value ) + 4 ) / 8 ));
}


void ComputeFont( void )
{
	Font = &ScreenFont;
	Font->ta_Name = (STRPTR)Screen->RastPort.Font->tf_Message.mn_Node.ln_Name;
	Font->ta_YSize = FontY = Screen->RastPort.Font->tf_YSize;
	FontX = Screen->RastPort.Font->tf_XSize;
	OffX = Screen->WBorLeft;
	OffY = Screen->RastPort.TxHeight + Screen->WBorTop + 1;
	return;
}


/* Funkcja otwiera okno */

int OpenAPP_Display( WORD Left, WORD Top )
{

	if(!(APP_Window=OpenWindowTags( 0,
		WA_Left,				Left,
		WA_Top,					Top,
		WA_Width,				ComputeX(Width) + OffX + Screen->WBorRight,
		WA_Height,			ComputeY(Height) + OffY + Screen->WBorBottom,
		WA_MinWidth,		ComputeX(MinWidth) + OffX + Screen->WBorRight,
		WA_MinHeight,		ComputeX(MinHeight) + OffY + Screen->WBorBottom,
		WA_MaxWidth,		ComputeX(MaxWidth) + OffX + Screen->WBorRight,
		WA_MaxHeight,		ComputeY(MaxHeight) + OffY + Screen->WBorBottom,
		WA_Title,				APP_TitleWindow,
		WA_Flags,				WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET | WFLG_SMART_REFRESH,
		WA_IDCMP,				IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW | IDCMP_GADGETUP,
		WA_Gadgets,			APP_GList,
		WA_AutoAdjust,	FALSE,
		WA_PubScreen,		(struct Screen *)Screen,
		TAG_DONE)))
			return( FALSE );
	GT_RefreshWindow( APP_Window, NULL );
	sigwin=( 1L << APP_Window->UserPort->mp_SigBit );
	return( TRUE );
}


/* Funkcja odczytuje komunikat Intuition */

LONG ReadIMsg( struct Window *iwnd )
{
	struct IntuiMessage *imsg;
	
	if ( imsg = GT_GetIMsg( iwnd->UserPort ))
	{
		IClass	  =	imsg->Class;
		Qualifier	=	imsg->Qualifier;
		Code			=	imsg->Code;
		IObject		=	imsg->IAddress;

		GT_ReplyIMsg( imsg );
		return( TRUE );
	}
	return( FALSE );
}


/* Funkcja zamyka otwarte okno */

void CloseAPP_Display(void)
{
	if(APP_Window) 
	{
		Forbid();
		while ( ReadIMsg( APP_Window ))
		;
		CloseWindow((struct Window *)APP_Window);
		APP_Window=NULL;
		Permit();
	}
}


/* Funkcja alokuje ekran */

int SetupScreen( void )
{
	if (!(Screen = LockPubScreen( PubScreenName )))
		return( FALSE );

	ComputeFont();

	if(!(OpenFonts()))
		return( FALSE );


	if (!( VisualInfo = GetVisualInfo( Screen, TAG_DONE )))
		return( FALSE );

	return( TRUE );
}


/* Funkcja dealokuje ekran */

void CloseDownScreen( void )
{
	if ( VisualInfo )
	{
		FreeVisualInfo( VisualInfo );
		VisualInfo = NULL;
	}

	CloseFonts();

	if ( Screen )
	{
		UnlockPubScreen( NULL, Screen );
		Screen = NULL;
	}
}


/* Funkcja otwiera wszystkie biblioteki */

LONG OpenLibraries( void )
{
	if ( !(DosBase = (struct DosLibrary *) OpenLibrary((UBYTE *) "dos.library", 37 )))
		return( FALSE );
	if ( !(IntuitionBase = (struct IntuitionBase *) OpenLibrary((UBYTE *) "intuition.library", 37 )))
		return( FALSE );
	if ( !(GadToolsBase = (struct Library *) OpenLibrary((UBYTE *) "gadtools.library", 37 )))
		return( FALSE );
	if ( !(GfxBase = (struct GfxBase *) OpenLibrary((UBYTE *) "graphics.library" , 37 )))
		return( FALSE );
	if ( !(DiskFontBase = (struct Library *) OpenLibrary((UBYTE *) "diskfont.library" , 37 )))
		return( FALSE );
	return( TRUE );
}


/* Funkcja zamyka wszystkie biblioteki */

void CloseLibraries( void )
{
	if (DiskFontBase)		CloseLibrary( (struct Library *) DiskFontBase );
	if (GfxBase)				CloseLibrary( (struct Library *) GfxBase );
	if (GadToolsBase)		CloseLibrary( (struct Library *) GadToolsBase );
	if (IntuitionBase)	CloseLibrary( (struct Library *) IntuitionBase );
	if (DosBase)				CloseLibrary( (struct Library *) DOSBase );
}


void ShutDown( void )
{
	CloseAPP_Display();
	FreeGadgets( APP_GList );
	APP_GList = NULL;
	CloseDownScreen();
	CloseLibraries();
}


/************************/
int CreatePorts( void )
{
	if (!(msgport=CreatePort(NULL, 0L)))
		return( FALSE );
	Forbid();
	if (!(destport=FindPort( RESETSERVERNAME )))
  {
		Permit();
		return( FALSE );
  }
  Permit();
	sigmsg = ( 1L << msgport->mp_SigBit  );
	return( TRUE );
}

void DeletePorts( void )
{
	if( msgport )
		DeletePort ( msgport );
}


/* Gîówna funkcja */

int main( int argc, char *argv[] )
{
BOOL running=TRUE;
BOOL done=FALSE;

	if(!(OpenLibraries()))
	{
		ShutDown();
		return( FALSE );
	}
	
	if(!(SetupScreen()))
	{
		ShutDown();
		return( FALSE );
	}

	if(!MakeGadget())
	{
		ShutDown();
		return( FALSE );
	}

	if(!(OpenAPP_Display( 20, 20 )))
	{
		ShutDown();
		return( FALSE );
	}

	if(!(CreatePorts()))
	{
		strcpy(TextBufor, "Createports failed");
		GT_SetGadgetAttrs( gad_text, APP_Window, 0, GTTX_Text, (ULONG)TextBufor, TAG_DONE);
	}

	SetFont( APP_Window->RPort, APP_Font );

	sendmsg.rwm_Message.mn_ReplyPort=msgport;
	sendmsg.rwm_MsgPort=msgport;
	sendmsg.rwm_MsgType=RWM_ADDPORT;
	sendmsg.rwm_ProgName=PROGNAME;
	if( destport )
	{
		strcpy(TextBufor, "Sending RWM_ADDPORT");
		GT_SetGadgetAttrs( gad_text, APP_Window, 0, GTTX_Text, (ULONG)TextBufor, TAG_DONE);
		PutMsg( destport, (struct Message *)&sendmsg );
	}

	do
	{
		signal=Wait( sigwin | sigmsg );


		while ( ReadIMsg( APP_Window ))
		{
			switch ( IClass )
			{
				case	IDCMP_REFRESHWINDOW:
					GT_BeginRefresh( APP_Window );
					GT_EndRefresh( APP_Window, TRUE );
				break;

				case	IDCMP_CLOSEWINDOW:
					sendmsg3.rwm_Message.mn_ReplyPort=msgport;
					sendmsg3.rwm_MsgPort=msgport;
					sendmsg3.rwm_MsgType=RWM_REMPORT;
					sendmsg3.rwm_ProgName=PROGNAME;
					if( destport )
					{
						strcpy(TextBufor, "Sending RWM_REMPORT");
						GT_SetGadgetAttrs( gad_text, APP_Window, 0, GTTX_Text, (ULONG)TextBufor, TAG_DONE);
						PutMsg( destport, (struct Message *)&sendmsg3 );
					}
					else
						running=FALSE;
				break;

				case	IDCMP_GADGETUP:
					switch ( IObject->GadgetID )
					{
						case	GD_BUTTON:
							strcpy(TextBufor, "Welcom to ResetClient");
							GT_SetGadgetAttrs( gad_text, APP_Window, 0, GTTX_Text, (ULONG)TextBufor, TAG_DONE);
						break;
					}
				break;

				default:
				break;
			}
		}

		while( msg=(struct RWMessage *)GetMsg( msgport ))
		{
			switch( msg->rwm_Message.mn_Node.ln_Type )
			{
				case	NT_MESSAGE:
					switch( msg->rwm_MsgType )
					{
						case	RWM_RESETWARNING:
							strcpy(TextBufor, "Message ResetWarning");
							GT_SetGadgetAttrs( gad_text, APP_Window, 0, GTTX_Text, (ULONG)TextBufor, TAG_DONE);
							done=TRUE;
							running=FALSE;
						break;

						default:
						break;
					}
				ReplyMsg((struct Message *)msg);
				break;

				case	NT_REPLYMSG:
					switch( msg->rwm_MsgType )
					{
						case	RWM_REMPORT:
							running = FALSE;
						break;
					}
				break;
			}
		}

	} while ( running );

	running=TRUE;

	if( done )
	{
							sendmsg2.rwm_Message.mn_ReplyPort=msgport;
							sendmsg2.rwm_MsgPort=msgport;
							sendmsg2.rwm_MsgType=RWM_DONE;
							sendmsg2.rwm_ProgName=PROGNAME;
							if( destport )
							{
								strcpy(TextBufor, "Sending RWM_DONE");
								GT_SetGadgetAttrs( gad_text, APP_Window, 0, GTTX_Text, (ULONG)TextBufor, TAG_DONE);
								PutMsg( destport, (struct Message *)&sendmsg2 );
								do
								{
								  Wait( sigmsg );
										while( msg=(struct RWMessage *)GetMsg( msgport ))
										{
											switch( msg->rwm_Message.mn_Node.ln_Type )
											{
												case	NT_REPLYMSG:
													switch( msg->rwm_MsgType )
													{
														case	RWM_DONE:
															running = FALSE;
														break;
													}
												break;
											}
										}
								} while ( running );
							}
	}

	DeletePorts();
	ShutDown();
	return( TRUE );
}
