#define NAME	 "Change"
#define VERSION  "2"
#define REVISION "29"

/* Possible define CLIONLY for Change.c and ChangeTexts.c to compile a CLI
   only version. Note: you must not link ChangeGUI.o to this version.
   The CLIONLY version of Change 2.29 is 5768 bytes, where normal version
   is 9356 bytes (3588 bytes shorter).

   This program is multi-reentrant and can be made resident.
*/

/* Programmheader

	Name:		Change
	Author:		SDI
	Distribution:	PD
	Description:	searches and changes characters in files
	Compileropts:	-
	Linkeropts:	-l amiga -gsi

 2.5   06.08.95 : fixed error in SDI_WriteBuf (now 1.4)
 2.6   15.10.95 : better return codes
 2.7   31.10.95 : fixed some bugs
 2.8   10.12.95 : fixed bug with PATTERN_BACK
 2.9   25.12.95 : better window flags, now also PubScreen useable
 2.10  31.12.95 : SDI_OpenBF function in includes new, a bit shorter,
 	SDI_FileReq instead of own ASL function, now English
 2.11  02.02.96 : fixed write error in texts
 2.12  04.02.96 : fixed bug with strings in GUI
 2.13  05.02.96 : reworked gadget handling, field of gadgets instead of
	search routine
 2.14  06.02.96 : fixed bug in includes, added TestOS
 2.15  10.02.96 : used own startup code --> TestOS removed again
 2.16  14.02.96 : bugfix - GUI was always started in last version
 2.17  31.03.96 : fixed error with POSITION option
 2.18  04.05.96 : fixed error with ReadArgs
 2.19  02.08.96 : on CTRL_C break and FROM == TO, source is saved
 2.20  05.11.96 : changed the end text, to print out a bit better info
 2.21  27.11.96 : OVERWRITE didn't work, removed bug with very short files
 2.22  18.03.97 : SDI includes changed a bit
 2.23  01.08.97 : some source changes, translated source to English
 2.24  24.12.97 : totally rewritten scan routines, lots of changes, shorter
 2.25  26.12.97 : bug fixes in scan routines
 2.26  29.12.97 : again bug-fixes, fixed errors with SAS compilation
 2.27  03.01.98 : startup code now internal, made SAS compilable (SMakeFile),
	removed GetFile gadget image
 2.28  04.01.98 : removed some obsolete stuff
 2.29  07.01.98 : hope I fixed bugs crashing the GUI, moved GUI to
	ChangeGUI.c completely
*/
 
#include <proto/dos.h>
#include <proto/exec.h>
#include "SDI_ASM_STD_protos.h"
#include "SDI_defines.h"
#include "Change.h"
#include "ChangeTexts.h"
#include "ChangeFunc.h"
#include "GetChar.h"

#ifndef CLIONLY
  #include "ChangeGUI.h"
#endif

struct DosLibrary *DOSBase = 0;

/* =============================== start =============================== */

LONG start(void)
{
  LONG ret = RETURN_FAIL;
  struct DosLibrary *dosbase;

  if((dosbase = (struct DosLibrary *) OpenLibrary("dos.library", 37)))
  {
    struct Process *task;

    DOSBase = dosbase;
    if(!(task = (struct Process *) FindTask(0))->pr_CLI)
    {
      struct Message *msg;
      WaitPort(&task->pr_MsgPort);
      msg = GetMsg(&task->pr_MsgPort);
#ifdef CLIONLY
      ret = RETURN_FAIL;
#else
      ret = DoGUI();
#endif
      Forbid();
      ReplyMsg(msg);
    }
#ifndef CLIONLY
    else if(task->pr_Arguments[1] == 0)
      ret = DoGUI();
#endif
    else
    {
      struct Args args = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
      struct RDArgs *rda;

      if((rda = (struct RDArgs *) AllocDosObject(DOS_RDARGS, 0)))
      {
        rda->RDA_ExtHelp = TEXT_CLI_HELP;
        if(ReadArgs(PARAM, (LONG *) &args, rda))
        {
          ULONG   l[2];				/* The string length */
          UWORD str[2][BACK_MAX];		/* The strings */

          if(!args.rstring) args.rstring = "";

          l[0] = args.hex ? GetCharHEX(args.sstring, str[0]) :
          GetCharSTRING(args.sstring, str[0]);

          if(!args.nochange)
          {
            l[1] = args.hex ? GetCharHEX(args.rstring, str[1]) :
            GetCharSTRING(args.rstring, str[1]);
          }

          if(!args.sstring || !*args.sstring || !l[0])
            SetIoErr(ERROR_REQUIRED_ARG_MISSING);
          else
          {
	    ULONG flags = 0, h, i;

            if(args.found)		flags |= CHANGEFLAG_FOUND;
            if(args.overwrite)		flags |= CHANGEFLAG_OVERWRITE;
	    if(args.length)		flags |= CHANGEFLAG_LENGTH;
	    if(args.nosize) 		flags |= CHANGEFLAG_NOSIZE;
	    if(args.path)		flags |= CHANGEFLAG_PATH;
	    if(args.position)		flags |= CHANGEFLAG_POSITION;

            for(h = 0; h < (args.nochange ? 1 : 2); ++h)
            {
              PutStr(h == 0 ? TEXT_SEARCH_STR : TEXT_REPLACE_STR);
              for(i = 0; i < l[h]; ++i)		/* printout strings */
              {
                if(str[h][i] == PATTERN_BACK)
                  PutStr("\033[7m" PATTERN_BACK_OUT "\033[27m");
                else if(SDI_isprint(str[h][i]))
                  FPutC(Output(), str[h][i]);
                else
                  PutStr("\033[7m.\033[27m");
              }
              PutStr("'\n");
            }

	    if(args.nochange)
	      ret = DoSearch(args.from, str[0], l[0], flags);
	    else
	      ret = DoChange(args.from, str[0], l[0], args.to, str[1], l[1],
	      flags, args.position ? SDI_strtoul(args.position, 0, 16) : 0);
          }
          FreeArgs(rda);
        } /* ReadArgs */
        FreeDosObject(DOS_RDARGS, rda);
      } /* AllocDosObject */

      if(ret)
        PrintFault(IoErr(), 0);
    } /* else */
    CloseLibrary((struct Library *) DOSBase);
  } /* OpenLibrary dos.library */

  return ret;
}
