/*
 *  moreHTML
 *  © Dirk Holtwick, 1997
 *  ---------------------
///
    I publish this source, but that doesn't mean that it is  free.  It
    still remains copyrighted by me, Dirk Holtwick, and if you want to
    change the source or add some functions, you first have to get  in
    contact with me and get my permission.

    I regret that the comments and the stile of  the  source  are  not
    very  clear,  but  I  will try to make it more readable and better
    structured. For the compilation I used SAS/C 6.57.

    I need some help reguarding ARexx and Internet Access. Please  get
    in contact with me if you can help me. Thanks.

///                                                Yours Dirk Holtwick
 */

#define VERS      "1.5"
#define NAME      "moreHTML"
#define TMPREXX   "T:moreHTML_temp_command.rexx"
#define TMPINFO   "T:moreHTML_temp_info.rexx"

// Choose wether you want debuging infos or not:
// #define DEBUG

/// DEBUG
#ifdef DEBUG
   extern void KPrintF(...);
   #define DB KPrintF
#else
   #define DB ; / ## /
#endif
///
/// Includes
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include <rexx/storage.h>
#include <rexx/rxslib.h>

#include <exec/memory.h>
#include <prefs/prefhdr.h>
#include <datatypes/pictureclass.h>
#include <workbench/workbench.h>
#include <libraries/locale.h>
#include <libraries/asl.h>
#include <libraries/gadtools.h>
#include <libraries/mui.h>

#include <proto/rexxsyslib.h>

#include <clib/exec_protos.h>
#include <clib/graphics_protos.h>
#include <clib/intuition_protos.h>
#include <clib/utility_protos.h>
#include <clib/dos_protos.h>
#include <clib/locale_protos.h>
#include <clib/muimaster_protos.h>
#include <clib/icon_protos.h>
#include <clib/alib_protos.h>

#include <pragmas/exec_pragmas.h>
#include <pragmas/graphics_pragmas.h>
#include <pragmas/intuition_pragmas.h>
#include <pragmas/utility_pragmas.h>
#include <pragmas/dos_pragmas.h>
#include <pragmas/locale_pragmas.h>
#include <pragmas/muimaster_pragmas.h>
#include <pragmas/icon_pragmas.h>

#include <dos.h>

#include <mui/htmltext_mcc.h>

#include "dtpic.h"
#include "cb.h"
#include "mylist.h"
#include "mystring.h"
///
/// Compiler Stuff
#ifdef _DCC
#define REG(x) __ ## x
#define ASM
#define SAVEDS __geta4
#else
#define REG(x) register __ ## x
#define ASM    __asm
#define SAVEDS __saveds
#endif
///
/// Definitions
#define MUIM_MainWindow_Finish        0x90a41070
#define MUIM_MainWindow_About         0x90a41071
#define MUIM_MainWindow_Open          0x90a41072
#define MUIM_MainWindow_Iconify       0x90a41073
#define MUIM_MainWindow_Save          0x90a41074
#define MUIM_MainWindow_AddURL        0x90a41075
#define MUIM_MainWindow_ShowURL       0x90a41076
#define MUIM_MainWindow_ReloadURL     0x90a41077
#define MUIM_MainWindow_Config        0x90a41078
#define MUIM_MainWindow_Action        0x90a41079
#define MUIM_MainWindow_Find          0x90a4107a
#define MUIM_MainWindow_Rexx          0x90a4107b

#define REQ(text,but)                 MUI_Request(app,obj,0,NULL,but,(char *)text,0)
///
/// Global Vars
char  openurlstr[80];

LONG __stack = 2*8192;

struct Library *MUIMasterBase;
struct Library *GfxBase      ;
struct Library *IntuitionBase;
struct Library *LocaleBase   ;
struct Library *AslBase      ;
struct Library *UtilityBase  ;
struct Library *DataTypesBase;

Object *win;

extern struct Library *DOSBase;

struct MUI_CustomClass *CL_MainWindow  ;
struct MUI_CustomClass *CL_Dtpic       ;
///
/// Menu
#define RB CHECKIT
#define TG CHECKIT|MENUTOGGLE

enum
{
   MEN_OPEN=1,
   MEN_SAVE,
   MEN_ABOUT,
   MEN_AMUI,
   MEN_PRINT,
   MEN_PRSRC,
   MEN_EDIT,
   MEN_VIEW,
   MEN_HIDE,
   MEN_QUIT,
   MEN_CPBLOCK,
   MEN_CPTEXT,
   MEN_PATEXT,
   MEN_BACK,
   MEN_FORWARD,
   MEN_RELOAD,
   MEN_CONF,
   MEN_MUI,
   MEN_FIND,
   MEN_NEXT,
};

struct NewMenu MainMenu[] =
{
   { NM_TITLE, (STRPTR)"Project"                 , 0 ,0,0,(APTR)0             },
   { NM_ITEM , (STRPTR)"Open"                    ,"O",0,0,(APTR)MEN_OPEN      },
   { NM_ITEM , (STRPTR)"Save as"                 ,"S",0,0,(APTR)MEN_SAVE      },
   { NM_ITEM , (STRPTR)NM_BARLABEL               , 0 ,0,0,(APTR)0             },
   { NM_ITEM , (STRPTR)"Print"                   ,"P",0,0,(APTR)MEN_PRINT     },
   { NM_ITEM , (STRPTR)NM_BARLABEL               , 0 ,0,0,(APTR)0             },
   { NM_ITEM , (STRPTR)"About"                   ,"?",0,0,(APTR)MEN_ABOUT     },
   { NM_ITEM , (STRPTR)"About MUI"               , 0 ,0,0,(APTR)MEN_AMUI      },
   { NM_ITEM , (STRPTR)NM_BARLABEL               , 0 ,0,0,(APTR)0             },
   { NM_ITEM , (STRPTR)"Hide"                    ,"H",0,0,(APTR)MEN_HIDE      },
   { NM_ITEM , (STRPTR)"Quit"                    ,"Q",0,0,(APTR)MEN_QUIT      },

   { NM_TITLE, (STRPTR)"Edit"                    , 0 ,0,0,(APTR)0             },
   { NM_ITEM , (STRPTR)"Find"                    ,"F",0,0,(APTR)MEN_FIND      },
   { NM_ITEM , (STRPTR)"Find next"               ,"N",0,0,(APTR)MEN_NEXT      },
   { NM_ITEM , (STRPTR)NM_BARLABEL               , 0 ,0,0,(APTR)0             },
   { NM_ITEM , (STRPTR)"Copy block"              ,"C",0,0,(APTR)MEN_CPBLOCK   },

   { NM_TITLE, (STRPTR)"Navigation"              , 0 ,0,0,(APTR)0             },
   { NM_ITEM , (STRPTR)"Back"                    ,"B",0,0,(APTR)MEN_BACK      },
   { NM_ITEM , (STRPTR)"Forward"                 ,"F",0,0,(APTR)MEN_FORWARD   },
   { NM_ITEM , (STRPTR)NM_BARLABEL               , 0 ,0,0,(APTR)0             },
   { NM_ITEM , (STRPTR)"Reload"                  ,"R",0,0,(APTR)MEN_RELOAD    },

   { NM_TITLE, (STRPTR)"Source"                  , 0 ,0,0,(APTR)0             },
   { NM_ITEM , (STRPTR)"View"                    ,"V",0,0,(APTR)MEN_VIEW      },
   { NM_ITEM , (STRPTR)"Edit"                    ,"E",0,0,(APTR)MEN_EDIT      },
   { NM_ITEM , (STRPTR)"Copy"                    , 0 ,0,0,(APTR)MEN_CPTEXT    },
   { NM_ITEM , (STRPTR)"Print"                   , 0 ,0,0,(APTR)MEN_PRSRC     },

   { NM_TITLE, (STRPTR)"Settings"                , 0 ,0,0,(APTR)0             },
   { NM_ITEM , (STRPTR)"moreHTML"                , 0 ,0,0,(APTR)MEN_CONF      },
   { NM_ITEM , (STRPTR)"MUI"                     , 0 ,0,0,(APTR)MEN_MUI       },

   { NM_END,NULL,0,0,0,(APTR)0 },
};
///
/// Misc Help Functions
LONG xget(Object *obj,ULONG attribute)
{
   LONG x;
   get(obj,attribute,&x);
   return(x);
}

ULONG __stdargs DoSuperNew(struct IClass *cl,Object *obj,ULONG tag1,...)
{
   return(DoSuperMethod(cl,obj,OM_NEW,&tag1,NULL));
}
///
/// Clipboard
int WriteClip(char *string)
{
   struct IOClipReq *ior;

   if (string == NULL)
   {
      puts("No string argument given");
      return(0);
   }
   if (ior = CBOpen(0L))
   {
      if (!(CBWriteFTXT(ior,string)))
        printf("Error writing to clipboard: io_Error = %ld\n",ior->io_Error);
      CBClose(ior);
   }
   else
      puts("Error opening clipboard.device");
   return(0);
}
///

// Structures

/// struct Config_Data
struct Config_Data
{
   char  viewsource[80];
   char  printtext[80];
   char  editsource[80];
   char  openurl[80];
};
///
/// struct Tool_Data
struct Tool_Data
{
   struct   Tool_Data
            *next;
   char     *command;
   char     *help;
};
///
/// struct MainWindow_Data
struct MainWindow_Data
{
   Object   *win;
   Object   *file;
   Object   *html;
   Object   *scroll;
   Object   *infoline;
   Object   *list;
   Object   *toolbar;
   Object   *tool[4];

   char     searchstr[256];
   ULONG    searchpos;

   char     path[256];

   struct   Config_Data
            cfg;

   // Toolbar
   struct   MyList
            *tools;
};
///

// Toolbar

/// CreateToolbar
void CreateToolbar(struct MainWindow_Data *data)
{
   FILE     *f;
   static   char
            inbuf[1024],
            buf[1024];
//          *str;
   struct   RDArgs
            rda;
   BOOL     error = TRUE,
            textmode = FALSE,
            virgin = TRUE,
            horiz = TRUE;

   struct
   {
      char     *pos;
      ULONG    mode;
      ULONG    space;
      char     *text;
      char     *command;
      ULONG    script;
      char     *key;
      char     *image;
      char     *help;
   } arr;

   if(!DataTypesBase) textmode = TRUE;

   data->toolbar = data->tool[0];

   if(data->tools = MyCreateList(sizeof(struct Tool_Data), 12))
   if(f = fopen("PROGDIR:config/moreHTML.toolbar.config","r"))
   {
      while(!feof(f))
      {
         fgets(inbuf, sizeof(inbuf), f);
         buf[strlen(inbuf)-1] = 0;

         if((*stpblk(inbuf) != '#') && (*stpblk(inbuf) != NULL))
         {
            error = FALSE;

            memset(&rda, 0, sizeof(struct RDArgs));
            memset(&arr, 0, sizeof(arr));

            rda.RDA_Source.CS_Buffer = inbuf;
            rda.RDA_Source.CS_Length = strlen(inbuf);

            ReadArgs("POS=POSITION/K,TEXTMODE/S,SPACE/S,TEXT/K,COMMAND/K,SCRIPT/S,KEY/K,IMAGE/K,HELP/K",(LONG *)&arr,&rda);

            // Some definitions that have to come before the button definitions
            if(virgin)
            {
               if(arr.pos)
               {
                  if(!stricmp(arr.pos,"left"))
                  {
                     data->toolbar = data->tool[2];
                     horiz = FALSE;
                  }
                  else if(!stricmp(arr.pos,"right"))
                  {
                     data->toolbar = data->tool[3];
                     horiz = FALSE;
                  }
                  else if(!stricmp(arr.pos,"bottom"))
                     data->toolbar = data->tool[1];
               }
               if(arr.mode) textmode=TRUE;
            }

            // Kill old contents
            if((arr.space || arr.text) && virgin)
            {
               struct   List
                        *childlist;
               Object   *cstate;
               Object   *child;

               if(childlist = (void *)xget(data->toolbar, MUIA_Group_ChildList))
               {
                  cstate = (Object *)childlist->lh_Head;
                  while (child = NextObject(&cstate))
                     DoMethod(data->toolbar, OM_REMMEMBER, child);
               }
               virgin = FALSE;
            }

            // Create space
            if(arr.space)
            {
               if(horiz)
                  DoMethod (data->toolbar, OM_ADDMEMBER, HSpace(0));
               else
                  DoMethod (data->toolbar, OM_ADDMEMBER, VSpace(0));
            }

            // Create button
            else if(arr.text)
            {
               Object *obj;
               struct Tool_Data *t;

               // Buffer the important strings
               // Uses private functions
               t = MyAddItem(data->tools);
               t->command = MyAllocString(arr.command);
               t->help    = MyAllocString(arr.help);

               if(textmode)
               {
                  DoMethod (data->toolbar, OM_ADDMEMBER,
                     obj = TextObject,
                        ButtonFrame,
                        MUIA_Text_Contents, arr.text,
                        MUIA_Text_PreParse, "\33c",
                        MUIA_Text_HiChar  , *arr.key,
                        MUIA_ControlChar  , *arr.key,
                        MUIA_InputMode    , MUIV_InputMode_RelVerify,
                        MUIA_Background   , MUII_ButtonBack,
                        MUIA_CycleChain   , TRUE,
                        MUIA_ShortHelp    , t->help,
                        End
                  );
               }
               else
               {
                  DoMethod (data->toolbar, OM_ADDMEMBER,
                     obj = DtpicObject,
                        ImageButtonFrame,
                        MUIA_CycleChain           , 1,
                        MUIA_InputMode            , MUIV_InputMode_RelVerify,
                        MUIA_Dtpic_Name           , arr.image,
                        MUIA_ShortHelp            , t->help,
                        MUIA_ControlChar          , *arr.key,
                        End
                  );
               }

               DoMethod(obj, MUIM_Notify, MUIA_Pressed, FALSE,
                  data->win,3,MUIM_MainWindow_Rexx,t->command,arr.script);
            }

            FreeArgs(&rda);
         }
      }
      fclose(f);
   }
/*
   else
   {
      puts("Couldn't open toolbar config file.");
   }
*/

   if(error)
      DoMethod (data->toolbar, OM_ADDMEMBER,
         HSpace(0)
      );
}
///
/// DisposeToolbar
void DisposeToolbar(struct MainWindow_Data *data)
{
   struct Tool_Data *t;

   t = (void *)data->tools->first;
   while(t)
   {
      MyFreeString(t->command);
      MyFreeString(t->help);
      t=t->next;
   }

   MyDisposeList(data->tools);
}
///

// MainWindow

/// OpenURLHook
__saveds ULONG __asm OpenURL(register __a0 struct Hook *h, register __a2 Object *obj, register __a1 struct{ char *URL; char *TmpFilename; } *msg)
{
// struct MainWindow_Data *data = INST_DATA(OCLASS(obj), obj);
   return(TRUE);
}
///
/// Popobj & List
SAVEDS ASM VOID ObjStrFunc(REG(a2) Object *list,REG(a1) Object *str)
{
   char *x;
   DoMethod(list,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,&x);
   set(str,MUIA_String_Contents,x);
   set(str,MUIA_String_Acknowledge,TRUE);
}
///
/// AppMsgFunc
SAVEDS ASM LONG AppMsgFunc(REG(a2) APTR obj, REG(a1) struct AppMessage **x)
{
   struct WBArg *ap;
   struct AppMessage *amsg = *x;
   static char buf[256];

   if(amsg->am_NumArgs)
   {
      ap=amsg->am_ArgList;
      NameFromLock(ap->wa_Lock,buf,sizeof(buf));
      AddPart(buf,ap->wa_Name,sizeof(buf));
      DoMethod(obj,MUIM_MainWindow_Open,buf);
   }

   return(0);
}
///

/// SaveHTML
void SaveHTML(struct MainWindow_Data *data, char *name)
{
   if(name)
   {
      char  *text;
      FILE  *f;

      get(data->html, MUIA_HTMLtext_Contents, &text);
      if(f=fopen(name,"w"))
      {
         fwrite(text,strlen(text),1,f);
         fclose(f);
      }
   }
}
///
/// MainWindow_Rexx
ULONG MainWindow_Rexx(struct IClass *cl,Object *obj,struct {ULONG MethodID; char *command; ULONG script;} *msg)
{
//   struct MainWindow_Data *data = INST_DATA(cl,obj);

   DB("Command: %s, Script: %ld\n",msg->command,!msg->script);

   {
      char     *name, cmd[256];
      FILE     *f;
      Object   *app = (Object *)xget(obj,MUIA_ApplicationObject);

      name = TMPREXX;
      if(f = fopen(name,"w"))
      {
         fprintf(f,
            "/* Tmpfile */\n"
            "address %s %s",
            ((char *)xget(app,MUIA_Application_Base)),
            msg->command
         );
         fclose(f);

         sprintf(cmd,"run <>nil: sys:rexxc/rx %s",name);
         system(cmd);
      }
   }

   return(0);
}
///
/// MainWindow_Config
ULONG MainWindow_Config(struct IClass *cl,Object *obj,struct {ULONG MethodID; ULONG justget;} *msg)
{
   struct   MainWindow_Data *data = INST_DATA(cl,obj);
   Object   *app = (Object *)xget(obj,MUIA_ApplicationObject);
   char     *h;
   ULONG    d;

   Object
      *win,
      *showtoolbar,
      *showinfoline,
      *showimg,
      *viewsource,
      *editsource,
      *printtext;
//    *openurl;

   enum
   {
      OBJ_showtoolbar = 1,
      OBJ_showinfoline,
      OBJ_viewsource,
      OBJ_editsource,
      OBJ_printtext,
      OBJ_openurl,
      OBJ_showimg,
   };

   static const char *titles[] =
   {
      "Misc",
      "Commands",
      NULL
   };

   set(app,MUIA_Application_Sleep,TRUE);  // disable other windows

   win =
      WindowObject,
         MUIA_Window_Title, "Settings",
         MUIA_Window_ID   , MAKE_ID('C','O','N','F'),

         WindowContents, VGroup,

            Child, RegisterObject,
               MUIA_Register_Titles, titles,

               // DISPLAY
               Child, ColGroup(2),
                  Child, LLabel("Show _tool bar"),
                  Child, showtoolbar = KeyCheckMark(TRUE,'t'),
                  Child, LLabel("Show info _line"),
                  Child, showinfoline = KeyCheckMark(TRUE,'l'),
                  Child, LLabel("Show _images"),
                  Child, showimg = KeyCheckMark(TRUE,'i'),
                  End,

               // FUNCTIONS
               Child, ColGroup(2),
                  Child, VSpace(0),
                  Child, VSpace(0),
/*
                  Child, LLabel("Open URL"),
                  Child, openurl = StringObject,
                     StringFrame,
                     MUIA_CycleChain, 1,
                     MUIA_ObjectID, OBJ_openurl,
                     MUIA_String_Contents, "geturl %s %s",
                     MUIA_ShortHelp,
                        "Command to be used to load page and data\n"
                        "of an to HTMLtext unknown protocol.\n"
                        "First '%s' stands for the URL and the\n"
                        "second '%s' for the file where to write\n"
                        "data to.",
                     End,
                  Child, VSpace(0),
                  Child, VSpace(0),
*/
                  Child, LLabel("Print text"),
                  Child, printtext = StringObject,
                     StringFrame,
                     MUIA_CycleChain, 1,
                     MUIA_ObjectID, OBJ_printtext,
                     MUIA_String_Contents, "httx %s prt: ansi",
                     MUIA_ShortHelp,
                        "Command to be used to print the\n"
                        "contents of the current HTML file.\n"
                        "One '%s' has to be used!",
                     End,
                  Child, LLabel("View source"),
                  Child, viewsource = StringObject,
                     StringFrame,
                     MUIA_CycleChain, 1,
                     MUIA_ObjectID, OBJ_viewsource,
                     MUIA_String_Contents, "more %s",
                     MUIA_ShortHelp,
                        "Command to be used to display the\n"
                        "source of the current HTML file.\n"
                        "One '%s' has to be used!",
                     End,
                  Child, LLabel("Edit source"),
                  Child, editsource = StringObject,
                     StringFrame,
                     MUIA_CycleChain, 1,
                     MUIA_ObjectID, OBJ_editsource,
                     MUIA_String_Contents, "ed %s",
                     MUIA_ShortHelp,
                        "Command to be used to edit the\n"
                        "source of the current HTML file.\n"
                        "One '%s' has to be used!",
                     End,
/*
                  Child, printtext = LLabel("On Double-Click"),
                  Child, StringObject,
                     StringFrame,
                     MUIA_CycleChain, 1,
                     MUIA_ObjectID, OBJ_printtext,
                     MUIA_String_Contents, "rx findword.rexx",
                     MUIA_ShortHelp,
                        "Command to be used to print the\n"
                        "contents of the current HTML file.\n"
                        "One '\%s' has to be used!",
                     End,
*/
                  Child, VSpace(0),
                  Child, VSpace(0),
                  End,

               End,
            End,
         End;

   if (win)                               // ok ?
   {
      DoMethod(app,OM_ADDMEMBER,win);    // add window...
      DoMethod(win,MUIM_Notify,MUIA_Window_CloseRequest,TRUE ,
         app,2,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);

      set(showtoolbar,   MUIA_ObjectID, OBJ_showtoolbar);
      set(showtoolbar,   MUIA_CycleChain, 1);
      set(showinfoline,  MUIA_ObjectID, OBJ_showinfoline);
      set(showinfoline,  MUIA_CycleChain, 1);
      set(showimg,       MUIA_ObjectID, OBJ_showimg);
      set(showimg,       MUIA_CycleChain, 1);

      DoMethod(app,MUIM_Application_Load, MUIV_Application_Load_ENVARC);

      // Just get the config datas
      if(!msg->justget)
      {

         set(win,MUIA_Window_Open,TRUE);    // and open it

         {
            ULONG sigs = 0;

            while (DoMethod(app,MUIM_Application_NewInput,&sigs) != MUIV_Application_ReturnID_Quit)
            {
               if (sigs)
               {
                  sigs = Wait(sigs | SIGBREAKF_CTRL_C);
                  if (sigs & SIGBREAKF_CTRL_C) break;
               }
            }
         }

         set(win,MUIA_Window_Open,FALSE);   // Close window

         DoMethod(app,MUIM_Application_Save, MUIV_Application_Save_ENVARC);
      }

      // Read out the config datas
      get(showtoolbar, MUIA_Selected, &d);
      set(data->toolbar, MUIA_ShowMe, d);

      get(showinfoline, MUIA_Selected, &d);
      set(data->infoline, MUIA_ShowMe, d);

      get(showimg, MUIA_Selected, &d);
      set(data->html, MUIA_HTMLtext_LoadImages, d);

      get(viewsource, MUIA_String_Contents, &h);
      strcpy(data->cfg.viewsource, h);

      get(editsource, MUIA_String_Contents, &h);
      strcpy(data->cfg.editsource, h);

      get(printtext, MUIA_String_Contents, &h);
      strcpy(data->cfg.printtext, h);

/*
      get(openurl, MUIA_String_Contents, &h);
      strcpy(data->cfg.openurl, h);
      strcpy(openurlstr, h);
*/
      // Remove window
      DoMethod(app,OM_REMMEMBER,win);    // remove

      MUI_DisposeObject(win);            // and kill it
   }
   else puts("Couldn't open config window.");

   set(app,MUIA_Application_Sleep,FALSE); // wake up the application
   return(0);
}
///
/// MainWindow_Iconify
ULONG MainWindow_Iconify(struct IClass *cl,Object *obj,struct Msg *msg)
{
// struct MainWindow_Data *data = INST_DATA(cl,obj);

   set((Object *)xget(obj,MUIA_ApplicationObject),MUIA_Application_Iconified,TRUE);

   return(0);
}
///
/// MainWindow_Finish
ULONG MainWindow_Finish(struct IClass *cl,Object *obj,struct Msg *msg)
{
//   struct MainWindow_Data *data = INST_DATA(cl,obj);
   DoMethod((Object *)xget(obj,MUIA_ApplicationObject),MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);
   return(0);
}
///
/// MainWindow_About
ULONG MainWindow_About(struct IClass *cl,Object *obj,Msg msg)
{
   Object   *app = (Object *)xget(obj,MUIA_ApplicationObject);
   struct   MainWindow_Data
            *data = INST_DATA(cl,obj);
   FILE     *f;

   static const char AboutText[] =
      "<HTML>\n"
      "<HEAD><TITLE>"NAME"</TITLE></HEAD>\n"
      "<BODY>\n"
      "<CENTER>\n"
      "<H1>"NAME"</H1><HR>\n"
      "Version %s<BR>\n"
      "%s<BR>\n"
      "Description: %s"
      "<P>\n"
      "<PRE>\n"
      "This program is free software; you can redistribute it  and/or  modify\n"
      "it  under  the terms of the GNU General Public License as published by\n"
      "the Free Software Foundation; either version 2 of the License, or  (at\n"
      "your option) any later version.\n"
      "\n"
      "This program is distributed in the hope that it will  be  useful,  but\n"
      "WITHOUT   ANY   WARRANTY;   without   even  the  implied  warranty  of\n"
      "MERCHANTABILITY or FITNESS FOR  A  PARTICULAR  PURPOSE.  See  the  GNU\n"
      "General Public License for more details.\n"
      "</PRE>\n"
      "</P>\n"
      "ARexx-Port: %s\n"
      "</BODY>\n"
      "</HTML>\n";


   if(f = fopen(TMPINFO,"w"))
   {
      fprintf(f,
         (char *)AboutText,
         ((char *)xget(app,MUIA_Application_Version))+7+strlen(NAME),
         ((char *)xget(app,MUIA_Application_Copyright)),
         ((char *)xget(app,MUIA_Application_Description)),
         ((char *)xget(app,MUIA_Application_Base)));
      fclose(f);

      set(data->html, MUIA_HTMLtext_URL, TMPINFO);
   }

   return(0);
}
///
/// MainWindow_AddURL
ULONG MainWindow_AddURL(struct IClass *cl,Object *obj,struct {ULONG MethodID; ULONG fstr;} *msg)
{
   struct MainWindow_Data *data = INST_DATA(cl,obj);
   char   *url;
   ULONG  x;

   // from string
   if(msg->fstr)
   {
      set(data->html, MUIA_HTMLtext_URL, xget(data->file, MUIA_String_Contents));
   }

   url = (char *)xget(data->html, MUIA_HTMLtext_URL);
   set(data->file, MUIA_String_Contents, url);

   // history
   if(url && *url)
   {
      set(data->list, MUIA_List_Quiet, TRUE);
      if((x = xget(data->list, MUIA_List_Active))!=MUIV_List_Active_Off)
      {
         while(x)
         {
            DoMethod(data->list, MUIM_List_Remove, MUIV_List_Remove_First);
            --x;
         }
      }

      DoMethod(data->list,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,&x);

      if(stricmp((char *)x,url))
         DoMethod(data->list, MUIM_List_InsertSingle, url, MUIV_List_Insert_Top);

      set(data->list, MUIA_List_Active, MUIV_List_Active_Top);
      set(data->list, MUIA_List_Quiet, FALSE);
   }

   return(0);
}
///
/// MainWindow_ShowURL
enum
{
   SHOW_back,
   SHOW_forward,
   SHOW_active
};

ULONG MainWindow_ShowURL(struct IClass *cl,Object *obj,struct {ULONG MethodID; ULONG mode;} *msg)
{
   struct MainWindow_Data *data = INST_DATA(cl,obj);
   ULONG  x;

   switch(msg->mode)
   {
      case SHOW_back:
         set(data->list, MUIA_List_Active, MUIV_List_Active_Down);
         break;
      case SHOW_forward:
         set(data->list, MUIA_List_Active, MUIV_List_Active_Up);
         break;
   }

   DoMethod(data->list,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,&x);
   set(data->html,MUIA_HTMLtext_URL,x);
   set(data->file,MUIA_String_Contents,x);
   return(0);
}
///
/// MainWindow_ReloadURL
ULONG MainWindow_ReloadURL(struct IClass *cl,Object *obj,Msg msg)
{
   struct MainWindow_Data *data = INST_DATA(cl,obj);

   DoMethod(data->html, MUIM_HTMLtext_Reload);
   return(0);
}
///
/// IntuiMsgFunc
SAVEDS ASM VOID IntuiMsgFunc(REG(a1) struct IntuiMessage *imsg,REG(a2) struct FileRequester *req)
{
   if (imsg->Class==IDCMP_REFRESHWINDOW)
      DoMethod(req->fr_UserData,MUIM_Application_CheckRefresh);
}
///
/// getfilename
char *getfilename(char *title,BOOL save, char *path)
{
   static char buf[512];
   struct FileRequester *req;
   struct Window *w;
   static LONG left=-1,top=-1,width=-1,height=-1;
   Object *app = (Object *)xget(win,MUIA_ApplicationObject);
   char *res = NULL;
   static const struct Hook IntuiMsgHook = { { 0,0 },(VOID *)IntuiMsgFunc,NULL,NULL };

   get(win,MUIA_Window_Window,&w);
   if (left==-1)
   {
      left   = w->LeftEdge+w->BorderLeft+2;
      top    = w->TopEdge+w->BorderTop+2;
      width  = w->Width-w->BorderLeft-w->BorderRight-4;
      height = w->Height-w->BorderTop-w->BorderBottom-4;
   }

   if (req=MUI_AllocAslRequestTags(ASL_FileRequest,
      ASLFR_Window, w,
      ASLFR_TitleText, title,
      ASLFR_InitialLeftEdge, left,
      ASLFR_InitialTopEdge , top,
      ASLFR_InitialWidth   , width,
      ASLFR_InitialHeight  , height,
      ASLFR_InitialDrawer  , path,
      ASLFR_InitialPattern , "#?.(html|htm)",
      ASLFR_DoSaveMode     , save,
      ASLFR_DoPatterns     , TRUE,
      ASLFR_RejectIcons    , TRUE,
      ASLFR_UserData       , app,
      ASLFR_IntuiMsgFunc   , &IntuiMsgHook,
      TAG_DONE))
   {
      set(app,MUIA_Application_Sleep,TRUE);
      if (MUI_AslRequestTags(req,TAG_DONE))
      {
         if (*req->fr_File)
         {
            res = buf;
            stccpy(path,req->fr_Drawer,255);
            stccpy(buf,req->fr_Drawer,sizeof(buf));
            AddPart(buf,req->fr_File,sizeof(buf));
         }
         left   = req->fr_LeftEdge;
         top    = req->fr_TopEdge;
         width  = req->fr_Width;
         height = req->fr_Height;
      }
      MUI_FreeAslRequest(req);
      set(app,MUIA_Application_Sleep,FALSE);
   }
   return(res);
}
///
/// MainWindow_Action
enum
{
   ACTION_clipblock,
   ACTION_clipsrc,
   ACTION_print,
   ACTION_viewsrc,
   ACTION_editsrc,
   ACTION_geturl,
   ACTION_printsrc,
};

ULONG MainWindow_Action(struct IClass *cl,Object *obj,struct {ULONG MethodID; ULONG mode;} *msg)
{
   struct   MainWindow_Data *data = INST_DATA(cl,obj);
   char     buf[120], *text, tmpname[60];

   switch(msg->mode)
   {
      // Clip block
      case ACTION_clipblock:
         get(data->html, MUIA_HTMLtext_Block, &text);
         WriteClip(text);
         break;

      // Clip source
      case ACTION_clipsrc:
         get(data->html, MUIA_HTMLtext_Contents, &text);
         WriteClip(text);
         break;

      // Print text
      case ACTION_print:
         tmpnam(tmpname);
         SaveHTML(data, tmpname);
         sprintf(buf, data->cfg.printtext, tmpname);
         if(buf[0]) system(buf);
         remove(tmpname);
         break;

      // Print source
      case ACTION_printsrc:
         SaveHTML(data, "prt:");
         break;

      // View source
      case ACTION_viewsrc:
         tmpnam(tmpname);
         SaveHTML(data, tmpname);
         sprintf(buf, data->cfg.viewsource, tmpname);
         if(buf[0]) system(buf);
         remove(tmpname);
         break;

      // Edit source
      case ACTION_editsrc:
         {
            char  *url;

            get(data->html, MUIA_HTMLtext_URL, &url);
            if(url)
            {
               sprintf(buf, data->cfg.editsource, url);
               if(buf[0]) system(buf);
               DoMethod(obj, MUIM_MainWindow_ReloadURL, 0);
            }
         }
         break;

      // Get URL
      case ACTION_geturl:
         {
            ULONG url;

            get(data->html, MUIA_HTMLtext_URL, &url);
            return(url);
         }
         break;
   }
   return(0);
}
///
/// MainWindow_Find
enum
{
   FIND_new = 1,
   FIND_word,
   FIND_next,
   FIND_first
};

ULONG Search(struct MainWindow_Data *data, STRPTR searchstr, ULONG pos, ULONG flags)
{
   struct MUIS_HTMLtext_Element *el; //, *ell;
// Object *app = (Object *)xget(data->html,MUIA_ApplicationObject);
// char  *str;

   if(searchstr && *searchstr)
   {
//    set(app, MUIA_Application_Sleep, TRUE);
      get(data->html, MUIA_HTMLtext_ElementList, &el);
      while(el)
      {
         if(!strnicmp(MACRO_HTMLtext_GetText(el), searchstr, strlen(searchstr)))
         {
            if(pos)
               pos--;
            else
            {
               DoMethod(data->html, MUIM_HTMLtext_Mark, el, el);
               DoMethod(data->html, MUIM_HTMLtext_Jump, el);
               return(TRUE);
            }
         }
         el = el->next;
      }
//    set(app, MUIA_Application_Sleep, FALSE);
   }

   return(FALSE);
}

ULONG MainWindow_Find(struct IClass *cl,Object *obj,struct {ULONG MethodID; ULONG mode; char *str;} *msg)
{
   Object *app = (Object *)xget(obj,MUIA_ApplicationObject);
   struct MainWindow_Data *data = INST_DATA(cl,obj);

   switch(msg->mode)
   {
      case FIND_new:
         // Open window and ask
         {
            Object   *win, *searchstr, *start;
            char     *str;

            set(app,MUIA_Application_Sleep,TRUE);  // disable other windows

            win =
               WindowObject,
                  MUIA_Window_Title, "Find",
                  MUIA_Window_ID   , MAKE_ID('F','I','N','D'),

                  WindowContents, VGroup,
                     Child, LLabel("Find this string:"),
                     Child, searchstr = StringObject,
                        StringFrame,
                        MUIA_CycleChain, 1,
                        MUIA_String_AdvanceOnCR, TRUE,
                        MUIA_String_Contents, data->searchstr,
                        MUIA_ShortHelp, "Will find all words in the text\nbeginning with this string",
                        End,
                     Child, start = SimpleButton("_Start"),
                     End,
                  End;

            if (win)                               // ok ?
            {
               DoMethod(app,OM_ADDMEMBER,win);    // add window...
               DoMethod(win,MUIM_Notify,MUIA_Window_CloseRequest,TRUE ,
                  app,2,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);
               DoMethod(start, MUIM_Notify, MUIA_Pressed, FALSE,
                  app,2,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);

               set(start,MUIA_CycleChain, 1);
               set(win,MUIA_Window_Open,TRUE);    // and open it
               set(win,MUIA_Window_ActiveObject, searchstr);

               {
                  ULONG sigs = 0;

                  while (DoMethod(app,MUIM_Application_NewInput,&sigs) != MUIV_Application_ReturnID_Quit)
                  {
                     if (sigs)
                     {
                        sigs = Wait(sigs | SIGBREAKF_CTRL_C);
                        if (sigs & SIGBREAKF_CTRL_C) break;
                     }
                  }
               }

               set(win,MUIA_Window_Open,FALSE);   // Close window

               get(searchstr, MUIA_String_Contents, &str);
               stccpy(data->searchstr, str, sizeof(data->searchstr));

               // Remove window
               DoMethod(app,OM_REMMEMBER,win);    // remove

               MUI_DisposeObject(win);            // and kill it
            }
            else puts("Couldn't open search window.");

            set(app,MUIA_Application_Sleep,FALSE); // wake up the application
         }

      case FIND_first:
         data->searchpos = 0;
         break;

      case FIND_word:
         // Take word from string (AREXX)
         stccpy(data->searchstr, msg->str, sizeof(data->searchstr));
         data->searchpos = 0;
         break;

   }

   // Suchen und erhöhen
   if(!Search(data, data->searchstr, data->searchpos++, 0))
   {
      // Am Ende angelang wieder das erste zeigen
      if(data->searchpos)
      {
         data->searchpos = 0;
         Search(data, data->searchstr, data->searchpos++, 0);
      }
      else REQ("String can't be found!","*_OK");
   }

   return(0);
}
///
/// MainWindow_Open
ULONG MainWindow_Open(struct IClass *cl,Object *obj,struct {ULONG MethodID; char *name;} *msg)
{
   struct MainWindow_Data *data = INST_DATA(cl,obj);
   char *name;

   if(msg->name)
   {
      // name comes as argument
      name = msg->name;
   }
   else
   {
      // filerequester
      name = getfilename("Select local file",FALSE,data->path);
   }

   if(name)
   {
      set(data->file, MUIA_String_Contents, name);
      DoMethod(obj, MUIM_MainWindow_AddURL, 1);
   }

   return(0);
}
///
/// MainWindow_Save
ULONG MainWindow_Save(struct IClass *cl,Object *obj,struct {ULONG MethodID; char *name;} *msg)
{
   struct MainWindow_Data *data = INST_DATA(cl,obj);
   char *name;

   if(msg->name)
   {
      name = msg->name;
   }
   else
   {
      name = getfilename("Select local file",TRUE,data->path);
   }

   SaveHTML(data, name);
   return(0);
}
///
/// MainWindow_Dispose
ULONG MainWindow_Dispose(struct IClass *cl,Object *obj,Msg msg)
{
   struct MainWindow_Data *data = INST_DATA(cl,obj);

   DB("Dispose\n");

   // remove toolbar
   DisposeToolbar(data);

   DB("End Dispose\n");

   return(DoSuperMethodA(cl,obj,msg));
}
///
/// MainWindow_New
ULONG MainWindow_New(struct IClass *cl,Object *obj,struct opSet *msg)
{
   Object *strip;
   struct MainWindow_Data tmp = {0};
/*
   static const struct Hook OpenURLHook
      = { { NULL,NULL },(VOID *)OpenURL ,NULL,NULL };
*/
   static const struct Hook AppMsgHook
      = { { NULL,NULL },(VOID *)AppMsgFunc,NULL,NULL };

   if (obj = (Object *)DoSuperNew(cl,obj,
         MUIA_Window_Title, "MoreHTML © Dirk Holtwick, 1997",
         MUIA_Window_ID   , MAKE_ID('H','T','M','L'),
         MUIA_Window_UseRightBorderScroller, TRUE,
         MUIA_Window_UseBottomBorderScroller, TRUE,
         MUIA_Window_Menustrip, strip = MUI_MakeObject(MUIO_MenustripNM,MainMenu,0),
         MUIA_Window_AppWindow, TRUE,

         WindowContents, HGroup,
            Child, tmp.tool[2] = VGroup,
               MUIA_VertWeight, 1,
               Child, VSpace(0),
               End,
            Child, VGroup,
               Child, tmp.tool[0] = HGroup,
                  Child, HSpace(0),
                  End,

               // Infoline
               Child, tmp.infoline = PopobjectObject,
                  MUIA_Popstring_String, tmp.file = StringObject,
                     StringFrame,
                     MUIA_CycleChain, 1,
                     MUIA_String_MaxLen, 1024,
                     End,
                  MUIA_Popstring_Button, PopButton(MUII_PopUp),
                  MUIA_Popobject_Object, ListviewObject,
                     MUIA_Listview_List, tmp.list = ListObject,
                        InputListFrame,
                        MUIA_List_ConstructHook, MUIV_List_ConstructHook_String,
                        MUIA_List_DestructHook, MUIV_List_DestructHook_String,
                        End,
                     End,
                  End,

               // HTML object with ScrollGroup
               Child, tmp.scroll = ScrollgroupObject,
                  MUIA_CycleChain, 1,
                  MUIA_Scrollgroup_UseWinBorder, TRUE,
                  MUIA_Scrollgroup_Contents, tmp.html = HTMLtextObject,
                     TextFrame,
//                   MUIA_HTMLtext_OpenURLHook, &OpenURLHook,
                     End,
                  End,

               Child, tmp.tool[1] = HGroup,
                  Child, HSpace(0),
                  End,
               End,
            Child, tmp.tool[3] = VGroup,
               MUIA_VertWeight, 1,
               Child, VSpace(0),
               End,
            End,

         TAG_MORE,msg->ops_AttrList))
   {
      struct MainWindow_Data *data = INST_DATA(cl,obj);

      *data = tmp;

      data->win = obj;

      // Add toolbar
      CreateToolbar(data);

      // Methods
      DoMethod(obj,MUIM_Notify,MUIA_Window_CloseRequest,TRUE ,
         obj,2,MUIM_MainWindow_Finish, 0);

      DoMethod((Object *)DoMethod(strip,MUIM_FindUData,MEN_ABOUT    ),MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,
         obj,1,MUIM_MainWindow_About);
      DoMethod((Object *)DoMethod(strip,MUIM_FindUData,MEN_OPEN     ),MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,
         obj,2,MUIM_MainWindow_Open,0);
      DoMethod((Object *)DoMethod(strip,MUIM_FindUData,MEN_SAVE     ),MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,
         obj,2,MUIM_MainWindow_Save,0);
      DoMethod((Object *)DoMethod(strip,MUIM_FindUData,MEN_HIDE     ),MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,
         obj,1,MUIM_MainWindow_Iconify);
      DoMethod((Object *)DoMethod(strip,MUIM_FindUData,MEN_QUIT     ),MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,
         obj,2,MUIM_MainWindow_Finish,0);
      DoMethod((Object *)DoMethod(strip,MUIM_FindUData,MEN_FIND     ),MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,
         obj,3,MUIM_MainWindow_Find,FIND_new,0);
      DoMethod((Object *)DoMethod(strip,MUIM_FindUData,MEN_NEXT     ),MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,
         obj,3,MUIM_MainWindow_Find,FIND_next,0);
      DoMethod((Object *)DoMethod(strip,MUIM_FindUData,MEN_CPTEXT   ),MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,
         obj,2,MUIM_MainWindow_Action,ACTION_clipsrc);
      DoMethod((Object *)DoMethod(strip,MUIM_FindUData,MEN_CPBLOCK  ),MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,
         obj,2,MUIM_MainWindow_Action,ACTION_clipblock);
      DoMethod((Object *)DoMethod(strip,MUIM_FindUData,MEN_PRINT    ),MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,
         obj,2,MUIM_MainWindow_Action,ACTION_print);
      DoMethod((Object *)DoMethod(strip,MUIM_FindUData,MEN_PRSRC    ),MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,
         obj,2,MUIM_MainWindow_Action,ACTION_printsrc);
      DoMethod((Object *)DoMethod(strip,MUIM_FindUData,MEN_VIEW     ),MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,
         obj,2,MUIM_MainWindow_Action,ACTION_viewsrc);
      DoMethod((Object *)DoMethod(strip,MUIM_FindUData,MEN_EDIT     ),MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,
         obj,2,MUIM_MainWindow_Action,ACTION_editsrc);
      DoMethod((Object *)DoMethod(strip,MUIM_FindUData,MEN_BACK     ),MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,
         obj,2,MUIM_MainWindow_ShowURL, SHOW_back);
      DoMethod((Object *)DoMethod(strip,MUIM_FindUData,MEN_FORWARD  ),MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,
         obj,2,MUIM_MainWindow_ShowURL, SHOW_forward);
      DoMethod((Object *)DoMethod(strip,MUIM_FindUData,MEN_RELOAD   ),MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,
         obj,1,MUIM_MainWindow_ReloadURL);
      DoMethod((Object *)DoMethod(strip,MUIM_FindUData,MEN_CONF     ),MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,
         obj,1,MUIM_MainWindow_Config, FALSE);
      DoMethod((Object *)DoMethod(strip,MUIM_FindUData,MEN_AMUI     ),MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,
         MUIV_Notify_Application,2,MUIM_Application_AboutMUI,obj);
      DoMethod((Object *)DoMethod(strip,MUIM_FindUData,MEN_MUI      ),MUIM_Notify,MUIA_Menuitem_Trigger,MUIV_EveryTime,
         MUIV_Notify_Application,2,MUIM_Application_OpenConfigWindow,0);

      // Popobj
      DoMethod(data->list,MUIM_Notify,MUIA_Listview_DoubleClick,TRUE,
         data->infoline,2,MUIM_Popstring_Close,TRUE);

      // Clicked
      DoMethod(data->html,MUIM_Notify,MUIA_HTMLtext_Clicked,TRUE,
         obj,2,MUIM_MainWindow_AddURL,0);

      // Title
      DoMethod(data->html,MUIM_Notify,MUIA_HTMLtext_Title,MUIV_EveryTime,
         obj,3,MUIM_Set,MUIA_Window_Title,MUIV_TriggerValue);

      // String
      DoMethod(data->file, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime,
         obj,2,MUIM_MainWindow_AddURL,1);

      // History
      DoMethod(data->list, MUIM_Notify, MUIA_Listview_DoubleClick, MUIV_EveryTime,
         obj,2,MUIM_MainWindow_ShowURL,SHOW_active);

      // App Msg
      DoMethod(obj,MUIM_Notify,MUIA_AppMessage,MUIV_EveryTime,
         obj,3,MUIM_CallHook,&AppMsgHook,MUIV_TriggerValue);

      set(obj,MUIA_Window_ActiveObject,data->scroll);
      set(obj,MUIA_Window_DefaultObject,data->scroll);

      return((ULONG)obj);
   }
   return(0);
}
///
/// MainWindow_Dispatcher
SAVEDS ASM ULONG MainWindow_Dispatcher(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) Msg msg)
{
   switch (msg->MethodID)
   {
      case OM_NEW                   : return(MainWindow_New       (cl,obj,(APTR)msg));
      case OM_DISPOSE               : return(MainWindow_Dispose   (cl,obj,(APTR)msg));
      case MUIM_MainWindow_Finish   : return(MainWindow_Finish    (cl,obj,(APTR)msg));
      case MUIM_MainWindow_Iconify  : return(MainWindow_Iconify   (cl,obj,(APTR)msg));
      case MUIM_MainWindow_About    : return(MainWindow_About     (cl,obj,(APTR)msg));
      case MUIM_MainWindow_AddURL   : return(MainWindow_AddURL    (cl,obj,(APTR)msg));
      case MUIM_MainWindow_ShowURL  : return(MainWindow_ShowURL   (cl,obj,(APTR)msg));
      case MUIM_MainWindow_ReloadURL: return(MainWindow_ReloadURL (cl,obj,(APTR)msg));
      case MUIM_MainWindow_Open     : return(MainWindow_Open      (cl,obj,(APTR)msg));
      case MUIM_MainWindow_Save     : return(MainWindow_Save      (cl,obj,(APTR)msg));
      case MUIM_MainWindow_Config   : return(MainWindow_Config    (cl,obj,(APTR)msg));
      case MUIM_MainWindow_Action   : return(MainWindow_Action    (cl,obj,(APTR)msg));
      case MUIM_MainWindow_Find     : return(MainWindow_Find      (cl,obj,(APTR)msg));
      case MUIM_MainWindow_Rexx     : return(MainWindow_Rexx      (cl,obj,(APTR)msg));
   }
   return(DoSuperMethodA(cl,obj,msg));
}

///

// ARexx

/// Rexx_URL
SAVEDS ASM LONG Rexx_URL (REG(a2) Object *app)
{
   set(app, MUIA_Application_RexxString,
      DoMethod(win, MUIM_MainWindow_Action, ACTION_geturl));
   return(0);
}
///
/// Rexx_Save
SAVEDS ASM LONG Rexx_Save (REG(a1) struct {char *name;} *msg)
{
   if(msg->name)
      DoMethod(win, MUIM_MainWindow_Save, msg->name);
   else
      DoMethod(win, MUIM_MainWindow_Save, 0);

   return(0);
}
///
/// Rexx_Open
SAVEDS ASM LONG Rexx_Open(REG(a1) struct {char *name;} *msg)
{
   if(msg->name)
      DoMethod(win, MUIM_MainWindow_Open, msg->name);
   else
      DoMethod(win, MUIM_MainWindow_Open, 0);

   return(0);
}
///
/// Rexx_Find
SAVEDS ASM LONG Rexx_Find (REG(a1) struct {char *str; LONG first; LONG next;} *msg)
{
   if(msg->str)
      DoMethod(win, MUIM_MainWindow_Find, FIND_word, msg->str);
   else if(msg->first)
      DoMethod(win, MUIM_MainWindow_Find, FIND_first, 0);
   else if(msg->next)
      DoMethod(win, MUIM_MainWindow_Find, FIND_next, 0);
   else
      DoMethod(win, MUIM_MainWindow_Find, FIND_new, 0);
   return(0);
}
///
/// Rexx_Print
SAVEDS ASM LONG Rexx_Print(REG(a1) Msg msg)
{
   DoMethod(win, MUIM_MainWindow_Action, ACTION_print);
   return(0);
}
///
/// Rexx_View
SAVEDS ASM LONG Rexx_View(REG(a1) Msg msg)
{
   DoMethod(win, MUIM_MainWindow_Action, ACTION_viewsrc);
   return(0);
}
///
/// Rexx_Reload
SAVEDS ASM LONG Rexx_Reload(REG(a1) Msg msg)
{
   DoMethod(win, MUIM_MainWindow_ReloadURL);
   return(0);
}
///
/// Rexx_Back
SAVEDS ASM LONG Rexx_Back(REG(a1) Msg msg)
{
   DoMethod(win, MUIM_MainWindow_ShowURL, SHOW_back);
   return(0);
}
///
/// Rexx_Forward
SAVEDS ASM LONG Rexx_Forward(REG(a1) Msg msg)
{
   DoMethod(win, MUIM_MainWindow_ShowURL, SHOW_forward);
   return(0);
}
///
/// Rexx_Edit
SAVEDS ASM LONG Rexx_Edit(REG(a1) Msg msg)
{
   DoMethod(win, MUIM_MainWindow_Action, ACTION_editsrc);
   return(0);
}
///

// Init

/// ExitLibs
VOID ExitLibs(VOID)
{
   if (IntuitionBase) CloseLibrary(IntuitionBase);
   if (GfxBase      ) CloseLibrary(GfxBase      );
   if (AslBase      ) CloseLibrary(AslBase      );
   if (UtilityBase  ) CloseLibrary(UtilityBase  );
   if (MUIMasterBase) CloseLibrary(MUIMasterBase);
   if (DataTypesBase) CloseLibrary(DataTypesBase);
}
///
/// InitLibs
BOOL InitLibs(VOID)
{
   MUIMasterBase = OpenLibrary("muimaster.library",11);
   UtilityBase   = OpenLibrary("utility.library"  ,36);
   AslBase       = OpenLibrary("asl.library"      ,36);
   GfxBase       = OpenLibrary("graphics.library" ,36);
   IntuitionBase = OpenLibrary("intuition.library",36);
   DataTypesBase = OpenLibrary("datatypes.library",0);

   if (MUIMasterBase && UtilityBase && AslBase && GfxBase && IntuitionBase)
      return(TRUE);

   ExitLibs();
   return(FALSE);
}
///
/// ExitClasses
VOID ExitClasses(VOID)
{
   if (CL_Dtpic       )    MUI_DeleteCustomClass(CL_Dtpic       );
   if (CL_MainWindow  )    MUI_DeleteCustomClass(CL_MainWindow  );
}
///
/// InitClasses
BOOL InitClasses(VOID)
{
   CL_MainWindow   = MUI_CreateCustomClass(NULL,MUIC_Window    ,NULL,sizeof(struct MainWindow_Data  )    ,MainWindow_Dispatcher  );
   CL_Dtpic        = MUI_CreateCustomClass(NULL,MUIC_Area      ,NULL,sizeof(struct DtpicData  )          ,DtpicDispatcher  );

   if (CL_MainWindow && CL_Dtpic)
      return(TRUE);

   ExitClasses();
   return(FALSE);
}
///
/// HandleArgs
const char CLITemplate[] = "URL";

const char CLIHelp[] =
   "\n"
   "\033[1mmoreHTML " VERS "\033[0m\n"
   "(C)opyright by Dirk Holtwick, 1997\n"
   "\n"
   "Usage: moreHTML <url>\n"
   " <url>   : filename or URL of the file to be displayed\n";

LONG HandleArgs(char *filename)
{
   struct RDArgs *rda,*rdas;
   LONG msg = 0;

   struct CLIArgs
   {
      char *url;
   } argarray = { 0 };

   if (rdas = AllocDosObject(DOS_RDARGS,NULL))
   {
      rdas->RDA_ExtHelp = (char *)CLIHelp;

      if (rda = ReadArgs((char *)CLITemplate,(LONG *)&argarray,rdas))
      {
         if (argarray.url)
         {
            strcpy(filename, argarray.url);
         }
         FreeArgs(rda);
      }
      FreeDosObject(DOS_RDARGS,rdas);
   }
   return(msg);
}
///

// Main

/// Main Program

int main(int argc,char *argv[])
{
   struct   WBStartup *wbmsg;
   ULONG    sigs=0, id;
   Object   *app;
   int      res;
   int      msg=0;
   char     filename[256];

   static const struct Hook Rexx_URLHook       = { { NULL,NULL },(VOID *)Rexx_URL     ,NULL,NULL };
   static const struct Hook Rexx_SaveHook      = { { NULL,NULL },(VOID *)Rexx_Save    ,NULL,NULL };
   static const struct Hook Rexx_OpenHook      = { { NULL,NULL },(VOID *)Rexx_Open    ,NULL,NULL };
   static const struct Hook Rexx_PrintHook     = { { NULL,NULL },(void *)Rexx_Print   ,NULL,NULL };
   static const struct Hook Rexx_BackHook      = { { NULL,NULL },(void *)Rexx_Back    ,NULL,NULL };
   static const struct Hook Rexx_ForwardHook   = { { NULL,NULL },(void *)Rexx_Forward ,NULL,NULL };
   static const struct Hook Rexx_ReloadHook    = { { NULL,NULL },(void *)Rexx_Reload  ,NULL,NULL };
   static const struct Hook Rexx_ViewHook      = { { NULL,NULL },(void *)Rexx_View    ,NULL,NULL };
   static const struct Hook Rexx_FindHook      = { { NULL,NULL },(void *)Rexx_Find    ,NULL,NULL };
   static const struct Hook Rexx_EditHook      = { { NULL,NULL },(void *)Rexx_Edit    ,NULL,NULL };

   // ARexx commands
   static struct MUI_Command commands[] =
   {
      { "url"       ,""                    , 0        , (void *)&Rexx_URLHook     },
      { "save"      ,"file/k"              , 1        , (void *)&Rexx_SaveHook    },
      { "open"      ,"url=file/k"          , 1        , (void *)&Rexx_OpenHook    },
      { "find"      ,"string=word/k,first=top/s,next/s"
                                           , 3        , (void *)&Rexx_FindHook    },
      { "print"     ,""                    , 0        , (void *)&Rexx_PrintHook   },
      { "back"      ,""                    , 0        , (void *)&Rexx_BackHook    },
      { "forward"   ,""                    , 0        , (void *)&Rexx_ForwardHook },
      { "reload"    ,""                    , 0        , (void *)&Rexx_ReloadHook  },
      { "view"      ,""                    , 0        , (void *)&Rexx_ViewHook    },
      { "edit"      ,""                    , 0        , (void *)&Rexx_EditHook    },
      { NULL        , NULL                 , NULL     , NULL                      }
   };

   DB("\n*** moreHTML ***\n");

   filename[0] = 0;

   // Starting from CLI
   if(argc!=0)
   {
      HandleArgs(filename);
   }
   // Starting from WB
   else
   {
      wbmsg = (struct WBStartup *)argv;

      if(wbmsg->sm_NumArgs>=2)
      {
         NameFromLock(wbmsg->sm_ArgList[1].wa_Lock,filename,255);
         AddPart(filename,wbmsg->sm_ArgList[1].wa_Name,255);
      }
   }

// InitLocale();

   if (InitLibs())
   {

      if (InitClasses())
      {

         app = ApplicationObject,
            MUIA_Application_Title      , NAME,
            MUIA_Application_Version    , "$VER: " NAME" " VERS " " __AMIGADATE__,
            MUIA_Application_Copyright  , "Copyright © Dirk Holtwick, 1997",
            MUIA_Application_Author     , "Dirk Holtwick",
            MUIA_Application_Description, "Simple Offline HTML Browser based on HTMLtext.mcc",
            MUIA_Application_Base       , "MOREHTML",
//          MUIA_Application_SingleTask , TRUE,
            MUIA_Application_Commands   , commands,
            MUIA_Application_Window     , win  = NewObject(CL_MainWindow->mcc_Class,NULL,TAG_DONE),
            End;

         if (app)
         {
            // Get configuration
            DoMethod(win, MUIM_MainWindow_Config, TRUE);

            // Open window before a text is loaded,
            // otherwise the background is crippled
            set(win,MUIA_Window_Open,TRUE);

            if(filename[0]) DoMethod(win, MUIM_MainWindow_Open,filename);

            while ((id = DoMethod(app,MUIM_Application_NewInput,&sigs)) != MUIV_Application_ReturnID_Quit)
            {
               if (sigs)
               {
                  sigs = Wait(sigs | SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_E | SIGBREAKF_CTRL_F);

                  /* quit when receiving break from console */
                  if (sigs & SIGBREAKF_CTRL_C)
                     break;

                  /* deiconify & activate on ctrl-f just like the other prefs programs */
                  if (sigs & SIGBREAKF_CTRL_F)
                  {
                     set(app,MUIA_Application_Iconified,FALSE);
                     set(win,MUIA_Window_Open,TRUE);
                  }
               }
            }

            // Remove temporary rexx file
            remove(TMPREXX);
            remove(TMPINFO);

            set(win,MUIA_Window_Open,FALSE);
         }
         MUI_DisposeObject(app);
         ExitClasses();
      }
      ExitLibs();
   }

   if (msg)
   {
/*
      char *str = GetStr(msg);
      char *c = strchr(str,'(');
      Write(Output(),str,strlen(str));
      res = c ? atol(c+1) : RETURN_OK;
*/
      res = RETURN_OK;
   }
   else
      res = RETURN_OK;

//   ExitLocale();

   DB("*** finish ***\n");

   exit(res);
}
///

