/* Routinesheader

	Name:		ChangeGUI.c
	Main:		Change
	Versionstring:	$VER: ChangeGUI.c 1.6 (07.01.1998)
	Author:		SDI
	Distribution:	PD
	Description:	GUI routines und structures

 1.4   17.03.97 : added header
 1.5   04.01.98 : made global vars static
 1.6   07.01.98 : moved all in all GUI-stuff from Change.c
*/

#include <proto/asl.h>
#include <proto/exec.h>
#include <proto/gadtools.h>
#include <proto/intuition.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <exec/memory.h>
#include <intuition/gadgetclass.h>
#include <dos/dosasl.h>
#include "SDI_ASM_STD_protos.h"
#include "Change.h"
#include "ChangeTexts.h"
#include "ChangeFunc.h"
#include "ChangeGUI.h"

struct IntuitionBase *	IntuitionBase	= 0;
struct Library *	GadToolsBase	= 0;
struct Library *	AslBase 	= 0;

static struct TextAttr topaz8 = {"topaz.font", TOPAZ_EIGHTY};

static UWORD ChangeGTypes[Change_CNT] = {
  BUTTON_KIND,
  BUTTON_KIND,
  CHECKBOX_KIND,
  CHECKBOX_KIND,
  CHECKBOX_KIND,
  CHECKBOX_KIND,
  CHECKBOX_KIND,
  CHECKBOX_KIND,
  CHECKBOX_KIND,
  CHECKBOX_KIND,
  TEXT_KIND,
  BUTTON_KIND,
  STRING_KIND,
  STRING_KIND,
  STRING_KIND,
  STRING_KIND,
  STRING_KIND,
};

static struct NewGadget ChangeNGad[Change_CNT] = {
  314,  15,  20, 14, 0, 0, GD_Load_File_GetFile, 0, 0, 0,
  314,  34,  20, 14, 0, 0, GD_Save_File_GetFile, 0, 0, 0,
   20,  58,  26, 11, (UBYTE *) "FOUND",		 0, GD_FOUND_CheckBox,	   PLACETEXT_RIGHT, 0, 0,
   20,  70,  26, 11, (UBYTE *) "HEX",		 0, GD_HEX_CheckBox,       PLACETEXT_RIGHT, 0, 0,
   20,  82,  26, 11, (UBYTE *) "LENGTH",	 0, GD_LENGTH_CheckBox,    PLACETEXT_RIGHT, 0, 0,
   20,  94,  26, 11, (UBYTE *) "NOCHANGE",	 0, GD_NOCHANGE_CheckBox,  PLACETEXT_RIGHT, 0, 0,
   20, 106,  26, 11, (UBYTE *) "NOSIZE",	 0, GD_NOSIZE_CheckBox,    PLACETEXT_RIGHT, 0, 0,
   20, 118,  26, 11, (UBYTE *) "OVERWRITE",	 0, GD_OVERWRITE_CheckBox, PLACETEXT_RIGHT, 0, 0,
   20, 130,  26, 11, (UBYTE *) "PATH",		 0, GD_PATH_CheckBox,      PLACETEXT_RIGHT, 0, 0,
   20, 142,  26, 11, (UBYTE *) "POSITION",	 0, GD_POSITION_CheckBox,  PLACETEXT_RIGHT, 0, 0,
  166, 139, 276, 14, (UBYTE *) "Error", 	 0, GD_Error_Text,	   PLACETEXT_ABOVE, 0, 0,
  137,  58,  69, 15, (UBYTE *) "START", 	 0, GD_START_Button,	   PLACETEXT_IN,    0, 0,
  346,  34,  96, 14, 0, 0, GD_Position_String, 0, 0, 0,
  101,  15, 212, 14, (UBYTE *) "Load-File",	 0, GD_Load_File_String,   PLACETEXT_LEFT,  0, 0,
  101,  34, 212, 14, (UBYTE *) "Save-File",	 0, GD_Save_File_String,   PLACETEXT_LEFT,  0, 0,
  166,  83, 276, 14, (UBYTE *) "Search-String",  0, GD_Search_String,	   PLACETEXT_ABOVE, 0, 0,
  166, 111, 276, 14, (UBYTE *) "Replace-String", 0, GD_Replace_String,	   PLACETEXT_ABOVE, 0, 0,
};

static ULONG ChangeGTags[] = {
  TAG_DONE,
  TAG_DONE,
  TAG_DONE,
  TAG_DONE,
  TAG_DONE,
  TAG_DONE,
  TAG_DONE,
  TAG_DONE,
  TAG_DONE,
  TAG_DONE,
  GTTX_Border, TRUE, TAG_DONE,
  TAG_DONE,
  GA_TabCycle, FALSE, GTST_String, (ULONG) "0", GTST_MaxChars, 10, STRINGA_Justification, GACT_STRINGCENTER, GA_Disabled, TRUE, TAG_DONE,
  GTST_String, (ULONG) "RAM:A", GTST_MaxChars, 100, STRINGA_Justification, GACT_STRINGCENTER, TAG_DONE,
  GTST_String, (ULONG) "RAM:B", GTST_MaxChars, 100, STRINGA_Justification, GACT_STRINGCENTER, TAG_DONE,
  GTST_MaxChars, 255, STRINGA_Justification, GACT_STRINGCENTER, TAG_DONE,
  GTST_MaxChars, 255, STRINGA_Justification, GACT_STRINGCENTER, TAG_DONE,
};

static struct Window *InitStuff(struct GuiData *gd)
{
  if((gd->IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 37)))
  {
    IntuitionBase = gd->IntuitionBase;
    if((gd->GadToolsBase = OpenLibrary("gadtools.library", 37)))
    {
      GadToolsBase = gd->GadToolsBase;
      if((gd->Scr = LockPubScreen(0)))
      {
        if((gd->VisualInfo = GetVisualInfoA(gd->Scr, 0)))
        {
          struct Gadget *g;

          if((g = CreateContext(&gd->GadgList)))
          {
            UWORD lc, tc;

            for(lc = tc = 0; lc < Change_CNT; lc++)
            {
              struct NewGadget ng;

              CopyMem(&ChangeNGad[lc], &ng, sizeof(struct NewGadget));
              ng.ng_VisualInfo = gd->VisualInfo;
              ng.ng_TextAttr = &topaz8;
              ng.ng_LeftEdge += gd->Scr->WBorLeft;
              ng.ng_TopEdge += gd->Scr->WBorTop + gd->Scr->RastPort.TxHeight + 1;
              if(!(gd->Gadg[lc] = g = CreateGadgetA(ChangeGTypes[lc], g,
              &ng, (struct TagItem *) &ChangeGTags[tc])))
                return 0;

	      if(ng.ng_GadgetID == GD_Search_String ||
              ng.ng_GadgetID == GD_Replace_String)
                g->Activation |= GACT_IMMEDIATE;

              while(ChangeGTags[tc++])
                ++tc;
            } /* gadget creation loop */

            if((gd->Window = OpenWindowTags(0, WA_Left, 55, WA_Top, 53,
	    WA_InnerWidth, 475, WA_InnerHeight, 166,
	    WA_IDCMP, IDCMP_GADGETUP|IDCMP_GADGETDOWN|IDCMP_CLOSEWINDOW,
	    WA_Flags, WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_CLOSEGADGET|
            WFLG_SMART_REFRESH, WA_Gadgets, gd->GadgList, WA_Title,
            version + 6, WA_ScreenTitle, version + 6, WA_AutoAdjust, TRUE,
            WA_Activate, TRUE, WA_PubScreen, gd->Scr, TAG_DONE)))
              GT_RefreshWindow(gd->Window, 0);
          } /* create ContextGadget */
        } /* get visualinfo */
      } /* lock screen */
    } /* open gadtools */
  } /* open intuition */

  return gd->Window;
}

/* =========================== ToogleGadgStat ========================== */

static void ToogleGadgStat(struct GuiData *gd, ULONG id, ULONG real)
{
  GT_SetGadgetAttrs(GetGadg(id), gd->Window, NULL, GA_Disabled, real,
  TAG_DONE);
}

/* ============================== FileReq ============================== */

static void FileReq(STRPTR dir, ULONG size)
{
  struct Library *aslbase;
  struct FileRequester *r;
  UBYTE str[50];
  STRPTR ptr = FilePart(dir);

  if(ptr)
    CopyMem(ptr, &str, SDI_strlen(ptr)+1);
  else
    str[0] = 0;

  if(!(aslbase = OpenLibrary("asl.library", 37)))
    return;
  AslBase = aslbase;
  if((r = (struct FileRequester *) AllocAslRequest(ASL_FileRequest, 0)))
  {
    *ptr = '\0';
    if(AslRequestTags(r, ASLFR_TitleText, TEXT_CHOOSE_A_FILE,
    ASLFR_InitialFile, str, ASLFR_InitialDrawer, dir, TAG_DONE))
    {
      CopyMem(r->fr_Drawer, dir, SDI_strlen(r->fr_Drawer)+1);
      AddPart(dir, r->fr_File, size);
    }
    else
      *ptr = str[0];
    FreeAslRequest(r);
  }
  CloseLibrary(aslbase);
}

/* ============================== FreeStuff ============================ */

static void FreeStuff(struct GuiData *gd)
{
  if(gd->Window) 	CloseWindow(gd->Window);
  if(gd->GadgList)	FreeGadgets(gd->GadgList);
  if(gd->VisualInfo)	FreeVisualInfo(gd->VisualInfo);
  if(gd->Scr)		UnlockPubScreen(0, gd->Scr);
  if(gd->GadToolsBase)	CloseLibrary(gd->GadToolsBase);
  if(gd->IntuitionBase)	CloseLibrary((struct Library *) gd->IntuitionBase);
  FreeMem(gd, sizeof(struct GuiData));
}

/* =============================== DoGUI =============================== */

LONG DoGUI(void)
{
  STRPTR in_str[2];	/* original strings */
  ULONG l[2] = {0, 0};
  ULONG	_Class = IDCMP_CLOSEWINDOW;
  struct GuiData *gd;
  ULONG flags = 0, hex = 0, nochange = 0;

  if(!(gd = (struct GuiData *) AllocMem(sizeof(struct GuiData), MEMF_CLEAR)))
    return 0;

  if(!InitStuff(gd))
  {
    FreeStuff(gd);
    return RETURN_FAIL;
  }

  in_str[0] = GetGadgBuf(GetGadg(GD_Search_String));
  in_str[1] = GetGadgBuf(GetGadg(GD_Replace_String));

  do
  {
    struct IntuiMessage *msg;

    Wait(1<<gd->Window->UserPort->mp_SigBit);
    while((msg = GT_GetIMsg(gd->Window->UserPort)))
    {
      ULONG i, j;
      struct Gadget *gadg;

      _Class = msg->Class;
      gadg = (struct Gadget *) msg->IAddress;

      switch(_Class)
      {
      case IDCMP_GADGETUP:
        switch(gadg->GadgetID)
        {
        case GD_PATH_CheckBox:
          flags &= ~CHANGEFLAG_OVERWRITE;
          flags ^= CHANGEFLAG_PATH;
          GetGadg(GD_OVERWRITE_CheckBox)->Flags &= ~GFLG_SELECTED;
          RefreshGList(GetGadg(GD_OVERWRITE_CheckBox), gd->Window, 0, 1);
          break;
        case GD_OVERWRITE_CheckBox:
          flags &= ~CHANGEFLAG_PATH;
          flags ^= CHANGEFLAG_OVERWRITE;
          GetGadg(GD_PATH_CheckBox)->Flags &= ~GFLG_SELECTED;
          RefreshGList(GetGadg(GD_PATH_CheckBox), gd->Window, 0, 1);
          break;
        case GD_LENGTH_CheckBox: flags ^= CHANGEFLAG_LENGTH; break;
        case GD_FOUND_CheckBox: flags ^= CHANGEFLAG_FOUND; break;
        case GD_HEX_CheckBox: hex = gadg->Flags & GFLG_SELECTED; break;
        case GD_NOCHANGE_CheckBox:
	  nochange = gadg->Flags & GFLG_SELECTED;
          ToogleGadgStat(gd, GD_LENGTH_CheckBox, nochange);
          ToogleGadgStat(gd, GD_OVERWRITE_CheckBox, nochange);
          ToogleGadgStat(gd, GD_PATH_CheckBox, nochange);
          ToogleGadgStat(gd, GD_POSITION_CheckBox, nochange);
          ToogleGadgStat(gd, GD_Position_String, (nochange ||
            !(flags & CHANGEFLAG_POSITION)));
          ToogleGadgStat(gd, GD_Save_File_String, nochange);
          ToogleGadgStat(gd, GD_Save_File_GetFile, nochange);
          ToogleGadgStat(gd, GD_Replace_String, nochange);
          break;
        case GD_NOSIZE_CheckBox: flags ^= CHANGEFLAG_NOSIZE; break;
        case GD_POSITION_CheckBox: flags ^= CHANGEFLAG_POSITION;
          ToogleGadgStat(gd, GD_Position_String, !(gadg->Flags & GFLG_SELECTED));
          break;
        case GD_Search_String: case GD_Replace_String:
          j = gadg->GadgetID == GD_Search_String ? 0 : 1;
          l[j] = (hex ? GetCharHEX(in_str[j], gd->str[j]) :
          GetCharSTRING(in_str[j], gd->str[j]));
          for(i = 0; i < l[j]; ++i)
          {
            if(!(gd->out_str[j][i] = gd->str[j][i]))
	      gd->out_str[j][i] = 1; /* prevents no string display */
          }
          gd->out_str[j][i] = '\0';
          GetGadgBuf(gadg) = gd->out_str[j];
          GetSpecInfo(gadg)->BufferPos = 0;
          RefreshGList(gadg, gd->Window, 0, 1);
          break;
        case GD_Load_File_String:
        case GD_Save_File_String:
	  GetSpecInfo(gadg)->BufferPos = 0;
          RefreshGList(gadg, gd->Window, 0, 1);
	  break;
        case GD_Load_File_GetFile: case GD_Save_File_GetFile:
          gadg = GetGadg(gadg->GadgetID == GD_Load_File_GetFile ?
          GD_Load_File_String : GD_Save_File_String);

	  FileReq(GetGadgBuf(gadg), GetSpecInfo(gadg)->MaxChars);
          RefreshGList(gadg, gd->Window, 0, 1);
          break;
        case GD_START_Button:
          if(!l[0])
            GT_SetGadgetAttrs(GetGadg(GD_Error_Text), gd->Window, NULL,
            GTTX_Text, TEXT_NO_SEARCH_STRING, TAG_DONE);
          else
          {
            ULONG fh;

            if(!(fh = Open("CON:0/11/640/190/Change Report/WAIT/CLOSE",
            MODE_NEWFILE)))
            {
              GT_SetGadgetAttrs(GetGadg(GD_Error_Text), gd->Window, NULL,
              GTTX_Text, TEXT_CANT_OPEN_REPORT_WINDOW, TAG_DONE);
              fh = Open("NIL:", MODE_NEWFILE);
            }
            fh = SelectOutput(fh);

            if(nochange)
              i = DoSearch(GetGadgBuf(GetGadg(GD_Load_File_String)),
              gd->str[0], l[0], flags);
            else
              i = DoChange(GetGadgBuf(GetGadg(GD_Load_File_String)),
              gd->str[0], l[0], GetGadgBuf(GetGadg(GD_Save_File_String)),
              gd->str[1], l[1], flags, 
              SDI_strtoul(GetGadgBuf(GetGadg(GD_Position_String)), 0, 16));

            if(i)
            {
              Fault(IoErr(), 0, gd->faulttext, TEXT_FAULT_SIZE);
              GT_SetGadgetAttrs(GetGadg(GD_Error_Text), gd->Window, NULL,
              GTTX_Text, gd->faulttext, TAG_DONE);
            }

            Close(SelectOutput(fh));
          }
          break;
        } /* End of switch(...) */
        break;
      case IDCMP_GADGETDOWN:
        switch(gadg->GadgetID)
        {
        case GD_Search_String: case GD_Replace_String:
          GetGadgBuf(gadg) = in_str[gadg->GadgetID == GD_Search_String ? 0 : 1];
          RefreshGList(gadg, gd->Window, 0, 1);
          break;
        }
        break;
      } /* switch(_Class) */
      GT_ReplyIMsg(msg);
      if(_Class == IDCMP_CLOSEWINDOW)
        break;
    } /* while */
  } while(_Class != IDCMP_CLOSEWINDOW);

  FreeStuff(gd);
  return RETURN_OK;
}

