/*
***************************************************************************
*
* Datei:
*    RSysFormatDisk.c
*
* Inhalt:
*
*      --- Globale Routinen ---
*
*    void FormatDisk ( void );
*
*      --- Lokale  Routinen ---
*
*    static int OpenFormatDiskWindow ( void );
*    static void FindDevices ( void );
*    static void SelFormatProgram ( void );
*    static void startformat ( void );
*    static void update ( void );
*
* Bemerkungen:
*    Enthält die Schnittstelle zum AmigaOS-Format-Befehl.
*
* Erstellungsdatum:
*    19-Jul-93    Rolf Böhme
*
* Änderungen:
*    19-Jul-93    Rolf Böhme    Erstellung
*
***************************************************************************
*/

#include "RSys.h"

static struct List DevList;
extern struct Remember *DevKey;

static UBYTE fmtcmd[MAXWRITESIZE],
		parts[7][MAXSTRLEN] =
{
	"SYS:System/Format", "DF0:", "Empty", "OFS", "NOINTL", "NOICONS", ""
};

static struct Window *FormatDiskWnd = NULL;
static struct Gadget *FormatDiskGList = NULL;
static struct Gadget *FormatDiskGadgets[10];
static UWORD FormatDiskLeft = 161;
static UWORD FormatDiskTop = 49;
static UWORD FormatDiskWidth = 297;
static UWORD FormatDiskHeight = 116;
static UBYTE *FormatDiskWdt = (UBYTE *) NAME " " VERSION " - Format Disk";

static UBYTE *IconsGad0Labels[]=
{
	(UBYTE *) "Icons",
	(UBYTE *) "No Icons",
	NULL};

static UBYTE *FSCYGad0Labels[]=
{
	(UBYTE *) "OFS",
	(UBYTE *) "FFS",
	NULL};

static UBYTE *InterCYGad0Labels[]=
{
	(UBYTE *) "No international",
	(UBYTE *) "International",
	NULL};

static UWORD FormatDiskGTypes[] = {
	STRING_KIND,
	BUTTON_KIND,
	LISTVIEW_KIND,
	STRING_KIND,
	CYCLE_KIND,
	CYCLE_KIND,
	CYCLE_KIND,
	STRING_KIND,
	BUTTON_KIND,
	BUTTON_KIND
};

static struct NewGadget FormatDiskNGad[] = {
	68, 3, 145, 13, (UBYTE *)"Format", NULL, GD_FormatStrGad, PLACETEXT_LEFT, NULL, NULL,
	216, 3, 73, 13, (UBYTE *)"Select", NULL, GD_SelFormatGad, PLACETEXT_IN, NULL, NULL,
	8, 32, 73, 48, (UBYTE *)"Devices", NULL, GD_DevLV, PLACETEXT_ABOVE|NG_HIGHLABEL, NULL, NULL,
	92, 32, 197, 13, (UBYTE *)"Disk label", NULL, GD_NameGad, PLACETEXT_ABOVE|NG_HIGHLABEL, NULL, NULL,
	92, 50, 97, 13, NULL, NULL, GD_IconsGad, 0, NULL, NULL,
	192, 50, 97, 13, NULL, NULL, GD_FSCYGad, 0, NULL, NULL,
	92, 67, 197, 13, NULL, NULL, GD_InterCYGad, 0, NULL, NULL,
	8, 85, 281, 13, NULL, NULL, GD_FmtStrGad, 0, NULL, NULL,
	8, 100, 137, 13, (UBYTE *)"Format", NULL, GD_FormatGad, PLACETEXT_IN, NULL, NULL,
	152, 100, 137, 13, (UBYTE *)"Quick", NULL, GD_QuickGad, PLACETEXT_IN, NULL, NULL
};

static ULONG *FormatDiskGTags[] = {
	(ULONG *)(GTST_String), (ULONG *)parts[0], (ULONG *)(GTST_MaxChars), (ULONG *)256, (ULONG *)(TAG_DONE),
	(ULONG *)(TAG_DONE),
	(ULONG *)(GTLV_ShowSelected), (ULONG *)NULL, (ULONG *)GTLV_Labels, (ULONG *)&DevList, (ULONG *)GTLV_Selected, (ULONG *)0, (ULONG *)GTLV_Top, (ULONG *)0, (ULONG *)(TAG_DONE),
	(ULONG *)(GTST_String), (ULONG *)parts[2], (ULONG *)(GTST_MaxChars), (ULONG *)256, (ULONG *)(TAG_DONE),
	(ULONG * )(GTCY_Labels), (ULONG *)&IconsGad0Labels[ 0 ], (ULONG *)(TAG_DONE),
	(ULONG * )(GTCY_Labels), (ULONG *)&FSCYGad0Labels[ 0 ], (ULONG *)(TAG_DONE),
	(ULONG * )(GTCY_Labels), (ULONG *)&InterCYGad0Labels[ 0 ], (ULONG *)(TAG_DONE),
	(ULONG *)(GTST_MaxChars), (ULONG *)256, (ULONG *)GTST_String, (ULONG *)fmtcmd, (ULONG *)(TAG_DONE),
	(ULONG *)(TAG_DONE),
	(ULONG *)(TAG_DONE)
};

	/*
	 * OpenFormatDiskWindow() öffnet ein Window mit
	 * Kontrollelementen zu Aufruf des FORMAT-Befehls
	 */
static int
OpenFormatDiskWindow( void )
{
	struct NewGadget	ng;
	struct Gadget	*g;
	UWORD		lc, tc;
	UWORD		wleft = FormatDiskLeft, wtop = FormatDiskTop, ww, wh;
	int gl[] = {GD_FormatStrGad - GD_FormatStrGad,
               GD_DevLV - GD_FormatStrGad,
               GD_NameGad - GD_FormatStrGad,
               GD_FmtStrGad - GD_FormatStrGad};

	DPOS;

   AdjustWindowDimensions(Scr, FormatDiskLeft, FormatDiskTop, FormatDiskWidth, FormatDiskHeight,
                               &wleft, &wtop, &ww, &wh);

	if ( ! ( g = CreateContext( &FormatDiskGList ))) return( 1L );

	for( lc = 0, tc = 0; lc < FormatDisk_CNT; lc++ ) 
   {
		CopyMem((char * )&FormatDiskNGad[ lc ], (char * )&ng, (long)sizeof( struct NewGadget ));

		ng.ng_VisualInfo = VisualInfo;
		ng.ng_TextAttr	 = Font;
		ng.ng_LeftEdge	 = OffX + ComputeX( ng.ng_LeftEdge );
		ng.ng_TopEdge	 = OffY + ComputeY( ng.ng_TopEdge );
		ng.ng_Width		 = ComputeX( ng.ng_Width );
		ng.ng_Height 	 = ComputeY( ng.ng_Height);

		FormatDiskGadgets[ lc ] = g = CreateGadgetA((ULONG)FormatDiskGTypes[ lc ], g, &ng, ( struct TagItem * )&FormatDiskGTags[ tc ] );

		makelabelvisible(FormatDiskGadgets[lc]);

		while( FormatDiskGTags[ tc ] ) tc += 2;

		tc++;

		if ( NOT g ) return( 2L );
	}

	if ( ! ( FormatDiskWnd = OpenWindowTags( NULL,
				WA_Left,	wleft,
				WA_Top,		wtop,
				WA_Width,	ww,
				WA_Height,	wh,
				WA_IDCMP,	STRINGIDCMP|
								BUTTONIDCMP|
								LISTVIEWIDCMP|
								CYCLEIDCMP|
								IDCMP_CLOSEWINDOW|
								IDCMP_REFRESHWINDOW|
								IDCMP_VANILLAKEY,
				WA_Flags,	WFLG_DRAGBAR|
								WFLG_DEPTHGADGET|
								WFLG_CLOSEGADGET|
								WFLG_SMART_REFRESH|
								WFLG_ACTIVATE|
								WFLG_RMBTRAP,
				WA_Title,	FormatDiskWdt,
				WA_PubScreenFallBack,TRUE,
				WA_PubScreen, Scr,
				TAG_DONE )))
		return( 4L );

	RefreshRastPort(FormatDiskWnd,FormatDiskGadgets,gl, 4, FALSE, FormatDiskGList);

	return 0L;
}

	/*
	 * FindDevices() sucht nach formatierbaren Devices im System
	 * und baut eine Liste mit deren Namen auf
	 */
static void
FindDevices(void)
{
	struct DosList *DosList;
	struct DeviceNode *DevNode;
	char	dev[PATHPARTWIDTH],
			str[MAXFULLNAME];

	DosList = LockDosList(LDF_DEVICES | LDF_READ);

	while (DosList = NextDosEntry(DosList, LDF_DEVICES | LDF_READ))
	{
		DevNode = (struct DeviceNode *) DosList;
		if ((DevNode->dn_Startup > 1000) && 
          (DevNode->dn_Task || DevNode->dn_Handler || DevNode->dn_SegList))
		{
			strncpy(str, B2CStr(dev, DevNode->dn_Name),MAXFULLNAME-1);
			strcat(str, ":");

			MakeDevEntry(&DevList, str);
		}
	}

	UnLockDosList(LDF_DEVICES | LDF_READ);

	return;
}

	/*
	 * update() aktualisiert den Aufruf des Formatbefehls nach den
	 * Einstellungen des Kontrollfensters
	 */
static void
update(void)
{
	sprintf((char *)fmtcmd, CMDFMT, parts[0], parts[1], parts[2], parts[3],
			  parts[4], parts[5], parts[6]);

	GT_SetGadgetAttrs(FormatDiskGadgets[GD_FmtStrGad - GD_FormatStrGad], FormatDiskWnd,
							NULL,
							GTST_String, fmtcmd,
							TAG_DONE);

	return;
}

	/*
	 * SelFormatProgram() bietet einen Filerequester an, mit dem
	 * ein alternativer Format-Befehl ausgeführt werden kann
	 */
static void
SelFormatProgram(void)
{
	if (GetFile(FormatDiskWnd,"SYS:System/","Format","#?", "Select Format program","Select"))
		if (exist((char *)_fullpath))
		{
			strncpy((char *)parts[0], (char *)_fullpath, MAXSTRLEN);
			update();
		}
		else ErrorHandle((char *)_fullpath, FILE_ERR, EXIST_FAIL, NO_KILL);

	return;
}

extern UBYTE autocon[];

	/*
	 * startformat() führt den zusammengesetzten Format-Befehl mit
	 * der System()-Routine aus
	 */
static void
startformat(void)
{
	struct TagItem stags[5];
	BPTR	fileptr;

	if (fileptr = Open(autocon, MODE_OLDFILE))
	{
		stags[0].ti_Tag = SYS_Input;
		stags[0].ti_Data = fileptr;
		stags[1].ti_Tag = SYS_Output;
		stags[1].ti_Data = NULL;
		stags[2].ti_Tag = SYS_Asynch;
		stags[2].ti_Data = FALSE;
		stags[3].ti_Tag = SYS_UserShell;
		stags[3].ti_Data = TRUE;
		stags[4].ti_Tag = TAG_DONE;

		if (Question(FormatDiskWnd, (char *)fmtcmd, YES))
			if (System(fmtcmd, stags) == -1L)
			{
				Close(fileptr);
				ErrorHandle((char *)fmtcmd, TASK_ERR, CREATE_FAIL, NO_KILL);
			}
	}

	return;
}

	/*
	 * FormatDisk() bietet eine kleine Benutzeroberfläche an und
	 * verarbeitet die Eingaben, mit denen der Aufruf des
	 * Format-Befehls konfiguriert werden kann
	 */
void
FormatDisk(void)
{
	register struct IntuiMessage *message;
	struct Node *clicknode;
	ULONG class,
			code;
	APTR	object;
	char *buff;
   int ID;

	DPOS;

   HandleHelp(MN_FormatDisk);

	Flags.quit_fd = 0;

	NewList(&DevList);

	FindDevices();

	if (OpenASysWindow(OpenFormatDiskWindow,NO_KILL))
	{
      LockMainWindow(LOCK);

		update();

		GT_SetGadgetAttrs(FormatDiskGadgets[GD_DevLV - GD_FormatStrGad], FormatDiskWnd,
								NULL,
								GTLV_Labels, &DevList,
								TAG_DONE);
		do
		{
			Wait(1L << FormatDiskWnd->UserPort->mp_SigBit);

			while ((message = (struct IntuiMessage *)
					  GT_GetIMsg(FormatDiskWnd->UserPort)) != NULL)
			{
				object = message->IAddress;
				class = message->Class;
				code = message->Code;

				GT_ReplyIMsg(message);

				switch (class)
				{
					case IDCMP_GADGETUP:
                  ID = ((struct Gadget *) object)->GadgetID;

                  HandleHelp((enum RSysNumbers)ID);

						switch (ID)
						{
							case GD_FormatStrGad:
								buff = gadgetbuff(FormatDiskGadgets[GD_FormatStrGad - GD_FormatStrGad]);
								if (exist(buff))
								{
									strncpy((char *)parts[0], buff, MAXSTRLEN);
									update();
								}
								else ErrorHandle(buff, FILE_ERR, EXIST_FAIL, NO_KILL);
								break;

							case GD_SelFormatGad:
								SelFormatProgram();
								break;

							case GD_DevLV:
								clicknode = GetNode(&DevList, code);
								strncpy((char *)parts[1], clicknode->ln_Name,MAXSTRLEN);
								update();
								break;

							case GD_NameGad:
								strncpy((char *)parts[2],gadgetbuff(FormatDiskGadgets[GD_NameGad - GD_FormatStrGad]),
										  MAXSTRLEN);
								update();
								break;

							case GD_IconsGad:
								if (code == 0) parts[5][0] = STRINGEND;
								else
									strcpy((char *)parts[5], "NOICONS");
								update();
								break;

							case GD_FSCYGad:
								strncpy((char *)parts[3], (char *)FSCYGad0Labels[code], MAXSTRLEN);
								update();
								break;

							case GD_InterCYGad:
								strcpy((char *)parts[4], (code == 0) ? "NOINTL" : "INTL");
								update();
								break;

							case GD_FmtStrGad:
								strncpy((char *)fmtcmd,
										 gadgetbuff(FormatDiskGadgets[GD_FmtStrGad - GD_FormatStrGad]),
										 MAXWRITESIZE);
								break;

							case GD_FormatGad:
								parts[6][0] = STRINGEND;
								update();
								startformat();
								break;

							case GD_QuickGad:
								strcpy((char *)parts[6], "QUICK");
								update();
								startformat();
								break;
						}

						break;

					case IDCMP_VANILLAKEY:
						if (code == '\33') Flags.quit_fd = 1;
						break;

					case IDCMP_REFRESHWINDOW:
						MakeWindowRefresh(FormatDiskWnd);
						break;

					case IDCMP_CLOSEWINDOW:
						Flags.quit_fd = 1;
						break;
				}
			}
		} while (NOT(Flags.quit_fd));

		FreeRemember(DEVKEY, TRUE);

		CloseASysWindow(&FormatDiskWnd, &FormatDiskGList, NULL);

      LockMainWindow(UNLOCK);
	}

	return;
}
