 /*
    ***************************************************************************
    *
    * 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"
#include "protos.h"

static LIST DevList;

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

static WINDOW *FormatDiskWnd = NULL;
static GADGET *FormatDiskGList = NULL;
static GADGET *FormatDiskGadgets[10];
static UWORD FormatDiskLeft = 161;
static UWORD FormatDiskTop = 49;
static UWORD FormatDiskWidth = 297;
static UWORD FormatDiskHeight = 116;
static UBYTE FormatDiskWdt[100];	/*GMD */

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 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)
{
  NEWGADGET ng;
  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 (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, (TAGITEM *) & FormatDiskGTags[tc]);

      makelabelvisible (FormatDiskGadgets[lc]);

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

      tc++;

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

  strcpy (FormatDiskWdt, get_vers (" - Format Disk"));	/*GMD */

  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)
{
  DOSLIST *DosList;
  DEVICENODE *DevNode;
  char dev[PATHPARTWIDTH], str[MAXFULLNAME];

  DosList = LockDosList (LDF_DEVICES | LDF_READ);

  while (DosList = NextDosEntry (DosList, LDF_DEVICES | LDF_READ))
    {
      DevNode = (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;
}


 /*
  * startformat() führt den zusammengesetzten Format-Befehl mit
  * der System()-Routine aus
  */
static void
startformat (void)
{
  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)
{
  INTUIMESSAGE *message;
  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 (WIN_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 = (INTUIMESSAGE *)
		  GT_GetIMsg (FormatDiskWnd->UserPort)) != NULL)
	    {
	      object = message->IAddress;
	      class = message->Class;
	      code = message->Code;

	      GT_ReplyIMsg (message);

	      switch (class)
		{
		case IDCMP_GADGETUP:
		  ID = ((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 (WIN_UNLOCK);
    }

  return;
}
