/*
 *  Yes, yes, yes. No running commentary throughout the code, but I understand it
 *   (I think)
 *   (Yeah, have no fear, I remember now)
 */

void __regargs __chkabort(void);
void __regargs __chkabort(void) {}

#include "adt.h"

LONG __stack = 8192;

#define FILE_PAGE   0
#define README_PAGE 1
#define GET_PAGE    2

#define FILE_NEW_PAGE	 3
#define FILE_RECENT_PAGE 0
#define FILE_ALL_PAGE	 1
#define FILE_TAGGED_PAGE 2

struct Library *MUIMasterBase, *childSocketBase;

static APTR win, hosts_win, add_host_win, config_win;
static APTR mainpage, lvpage, recentlv, shortlv, taggedlv, newlv, hostslv, readtext, getlv;
static APTR adt_statusobj, read_next_but, read_can_but, get_abort_but;
static APTR host_add_but, host_del_but, host_up_but, host_down_but, host_cancel_but, host_connect_but;
static APTR host_add_country, host_add_site, host_add_dir, host_add_done;
APTR get_gauge, app;
static APTR cfg_but, sort_but, view_but, read_but, name_but, get_but, host_but, quit_but;
static APTR search_str, search_next, search_can;
static APTR def_sort_but, def_view_but, def_getdir, def_tmpdir, def_uncomp, def_done;
static LONG sorttype=0, viewtype=0;

static LONG readpos;

static BOOL gotrecent=FALSE, gotshort=FALSE, gotnew=FALSE;
static BOOL sortrecent=TRUE, sortshort=TRUE, sortnew=TRUE, sorttagged=TRUE;
extern BOOL connected;

struct HostLineRec *host=NULL;
struct PrefsRec prefs;

static const char *SortEntries[] = { "Name", "Age", "Dir", NULL };
static const char *ViewEntries[] = { "New", "Recent", "All", "Tagged", NULL };

/*************************/
/* Init & Fail Functions */
/*************************/

static VOID fail(APTR app,char *str)
{
	if (app)
		MUI_DisposeObject(app);

	if (MUIMasterBase)
		CloseLibrary(MUIMasterBase);

	if (str)
	{
		puts(str);
		exit(20);
	}
	exit(0);
}

static VOID init(VOID)
{
	if (!(MUIMasterBase = OpenLibrary(MUIMASTER_NAME,MUIMASTER_VMIN)))
		fail(NULL,"Failed to open "MUIMASTER_NAME".");
}


/*
 * Breaks a string at the token 'mark', returning a pointer to the begining
 * of the string (from the adt1.3 distribution)
 */

char *gettok(char **ptr, char mark, int *toklen)
{
  char *t, *start = *ptr;

  if( (t=(char*)strchr(*ptr,mark))) {
    *t=0;
    *ptr=t+1;
  }
  *toklen = t - start + 1;
  return start;
}


/*
 *  File listview hooks
 */


__saveds __asm struct FileLineRec *file_const_func(REG(a0) struct Hook *hook,
						   REG(a2) APTR mem_pool,
						   REG(a1) char *line)
{
    register struct FileLineRec *flr;
    char *ln = line;
    LONG fsize;
    register char *dir, *name, *readme, *descr;
    int dirlen, namelen, readmelen, descrlen, nothanks;

    flr = (struct FileLineRec *)AllocMem(sizeof(struct FileLineRec), MEMF_ANY);

    sscanf(gettok(&ln, '@', &nothanks), "%lx", &flr->time);
    if (flr->time > prefs.thistime)
	prefs.thistime = flr->time;

    dir = gettok(&ln, '@', &dirlen);
    name = gettok(&ln, ';', &namelen);
    sscanf(gettok(&ln, '@', &nothanks), "%lx", &fsize);
    readme = gettok(&ln, '@', &readmelen);
    descr = gettok(&ln, '\n', &descrlen);

    flr->recsize = dirlen + namelen + 5 + readmelen + descrlen;
    flr->dir = AllocMem(flr->recsize, MEMF_ANY|MEMF_CLEAR);
    flr->name = flr->dir + dirlen;
    flr->size = flr->name + namelen;
    flr->readme = flr->size + 5;
    flr->descr = flr->readme + readmelen;

    strcpy(flr->dir, dir);
    strcpy(flr->name, name);
    flr->intsize = fsize;
    if (fsize < 1000) sprintf(flr->size, "%dB", fsize);
	else if (fsize < 1000000) sprintf(flr->size, "%dK", fsize / 1024);
	else if (fsize < 10000000) sprintf(flr->size, "%.1fM", fsize / 1048576.0);
	else if (fsize < 1000000000) sprintf(flr->size, "%dM", fsize / 1048576);
	else strcpy(flr->size, "big");
    strcpy(flr->readme, readme);
    strcpy(flr->descr, descr);

    if(flr->readme[strlen(flr->readme)-1] == ';') {
	flr->readme[strlen(flr->readme)-1] = '\0';
	flr->flags |= FLAG_README;
    }

    return(flr);
}

static struct Hook file_const_hook = {
    {NULL, NULL},
    (void *)file_const_func,
    NULL, NULL
};

__saveds __asm LONG file_dest_func(REG(a0) struct Hook *hook,
				   REG(a2) APTR mem_pool,
				   REG(a1) struct FileLineRec *flr)
{
    FreeMem(flr->dir, flr->recsize);
    FreeMem(flr, sizeof(struct FileLineRec));
    return(0);
}

static struct Hook file_dest_hook = {
    {NULL, NULL},
    (void *)file_dest_func,
    NULL, NULL
};

__saveds __asm LONG file_disp_func(REG(a0) struct Hook *hook,
				   REG(a2) char *array[],
				   REG(a1) struct FileLineRec *flinerec)
{
    if (flinerec) {
	if (HAS_README(flinerec)) array[0] = "*";
	    else array[0] = "";
	array[1] = flinerec->name;
	array[2] = flinerec->dir;
	array[3] = flinerec->size;
	array[4] = flinerec->descr;
    } else {
	array[0] = "";
	array[1] = "\033c\0338Name";
	array[2] = "\033c\0338Dir";
	array[3] = "\033c\0338Size";
	array[4] = "\033c\0338Description";
   }
   return(0);
}

static struct Hook file_disp_hook = {
     {NULL, NULL},
     (void *)file_disp_func,
     NULL, NULL
};

__saveds __asm LONG file_cmp_func(REG(a1) struct FileLineRec *line1,
				  REG(a2) struct FileLineRec *line2)
{
    switch(sorttype) {
	case 0:
	    return(stricmp(line1->name, line2->name));
	    break;

	case 1:
	    if ((line1->time - line2->time) < 0)
		return(1);
	    else if ((line1->time - line2->time) > 0)
		return(-1);
	    else return(0);
	    break;

	case 2:
	    return(stricmp(line1->dir, line2->dir));
	    break;
    }
}

static struct Hook file_cmp_hook = {
    {NULL, NULL},
    (void *)file_cmp_func,
    NULL, NULL
};


/*
 *  Host listview hooks
 */

__saveds __asm struct HostLineRec *host_const_func(REG(a0) struct Hook *hook,
						   REG(a2) APTR mem_pool,
						   REG(a1) char *line)
{
    register struct HostLineRec *hlr;
    register char *country, *site;
    char *ln=line;
    int dummy;

    hlr = (struct HostLineRec *)AllocMem(sizeof(struct HostLineRec), MEMF_ANY);

    country = gettok(&ln, ':', &dummy);
    site = gettok(&ln, ':', &dummy);
    if (country == NULL || site == NULL)
       return(NULL);
    strcpy(hlr->country, country);
    strcpy(hlr->host, site);
    strcpy(hlr->dir, ln);
    return(hlr);
}

static struct Hook host_const_hook = {
    {NULL, NULL},
    (void *)host_const_func,
    NULL, NULL
};

__saveds __asm LONG host_dest_func(REG(a0) struct Hook *hook,
				   REG(a2) APTR mem_pool,
				   REG(a1) struct HostLineRec *hlinerec)
{
    FreeMem(hlinerec, sizeof(struct HostLineRec));
    return(0);
}

static struct Hook host_dest_hook = {
    {NULL, NULL},
    (void *)host_dest_func,
    NULL, NULL
};

__saveds __asm LONG host_disp_func(REG(a0) struct Hook *hook,
				   REG(a2) char *array[],
				   REG(a1) struct HostLineRec *hlinerec)
{
    if (hlinerec) {
	array[0] = hlinerec->country;
	array[1] = hlinerec->host;
	array[2] = hlinerec->dir;
    } else {
	array[0] = "\033c\0338Country";
	array[1] = "\033c\0338Host";
	array[2] = "\033c\0338Directory";
    }
    return(0);
}

static struct Hook host_disp_hook = {
    {NULL, NULL},
    (void *)host_disp_func,
    NULL, NULL
};

__saveds __asm LONG host_cmp_func(REG(a1) struct HostLineRec *line1,
				  REG(a2) struct HostLineRec *line2)
{
    return(stricmp(line1->host, line2->host));
}

static struct Hook host_cmp_hook = {
    {NULL, NULL},
    (void *)host_cmp_func,
    NULL, NULL
};

main(int argc, char *argv[])
{
    BOOL running = TRUE;

/* Initialise default prefs. */
    prefs.defsort = 0;
    prefs.defview = 0;
    strcpy(prefs.getdir, "RAM:");
    strcpy(prefs.tmpdir, "RAM:");
    strcpy(prefs.defcfg, "ENV:MUIAdt.prefs");
    strcpy(prefs.uncomp, "uncompress");
    prefs.server[0] = '\0';
    prefs.lasttime = 0;
    prefs.thistime = 0;

/* Check for bsdsocket.library */
    if (childSocketBase = OpenLibrary("bsdsocket.library", 2L))
	CloseLibrary(childSocketBase);
    else
	exit(20);

    init();

    app = ApplicationObject,
	  MUIA_Application_Title,	"MUIAdt",
	  MUIA_Application_Version,	"$VER: MUIadt 1.3 (1/9/94)",
	  MUIA_Application_Copyright,	"© 1994 by Jem Atahan",
	  MUIA_Application_Author,	"Jem Atahan",
	  MUIA_Application_Description, "AmiNet Download Tool",
	  MUIA_Application_Base,	"MADT",

	  SubWindow, win = WindowObject,
	      MUIA_Window_ID, MAKE_ID('M','A','I','N'),
	      MUIA_Window_Title, "MUIAdt",
	      MUIA_Window_Width, MUIV_Window_Width_Visible(80),
	      MUIA_Window_Height, MUIV_Window_Height_Visible(60),

/* Main Window */
	      WindowContents, mainpage = PageGroup,

/* Files Page */
		  Child, VGroup,
		      Child, lvpage = PageGroup,
			  Child, recentlv = ListviewObject,
			      MUIA_Listview_MultiSelect, TRUE,
			      MUIA_Listview_DoubleClick, TRUE,
			      MUIA_Listview_List, ListObject,
				  InputListFrame,
				  MUIA_List_Format, "W=1,W=200,W=50,W=10 P=\033r,W=600",
				  MUIA_List_Title, TRUE,
				  MUIA_List_ConstructHook, &file_const_hook,
				  MUIA_List_DestructHook, &file_dest_hook,
				  MUIA_List_CompareHook, &file_cmp_hook,
				  MUIA_List_DisplayHook, &file_disp_hook,
				  End,
			      End,
			  Child, shortlv = ListviewObject,
			      MUIA_Listview_MultiSelect, TRUE,
			      MUIA_Listview_DoubleClick, TRUE,
			      MUIA_Listview_List, ListObject,
				  InputListFrame,
				  MUIA_List_Format, "W=1,W=200,W=50,W=10 P=\033r,W=600",
				  MUIA_List_Title, TRUE,
				  MUIA_List_ConstructHook, &file_const_hook,
				  MUIA_List_DestructHook, &file_dest_hook,
				  MUIA_List_CompareHook, &file_cmp_hook,
				  MUIA_List_DisplayHook, &file_disp_hook,
				  End,
			      End,
			  Child, taggedlv = ListviewObject,
			      MUIA_Listview_MultiSelect, TRUE,
			      MUIA_Listview_DoubleClick, TRUE,
			      MUIA_Listview_List, ListObject,
				  InputListFrame,
				  MUIA_List_Format, "W=1,W=200,W=50,W=10 P=\033r,W=600",
				  MUIA_List_Title, TRUE,
				  MUIA_List_ConstructHook, &file_const_hook,
				  MUIA_List_DestructHook, &file_dest_hook,
				  MUIA_List_CompareHook, &file_cmp_hook,
				  MUIA_List_DisplayHook, &file_disp_hook,
				  End,
			      End,
			  Child, newlv = ListviewObject,
			      MUIA_Listview_MultiSelect, TRUE,
			      MUIA_Listview_DoubleClick, TRUE,
			      MUIA_Listview_List, ListObject,
				  InputListFrame,
				  MUIA_List_Format, "W=1,W=200,W=50,W=10 P=\033r,W=600",
				  MUIA_List_Title, TRUE,
				  MUIA_List_ConstructHook, &file_const_hook,
				  MUIA_List_DestructHook, &file_dest_hook,
				  MUIA_List_CompareHook, &file_cmp_hook,
				  MUIA_List_DisplayHook, &file_disp_hook,
				  End,
			      End,
			  End,
		      Child, HGroup,
			  MUIA_Weight, 1,
			  Child, KeyLabel1("Sort by:", 's'), Child, sort_but = KeyCycle(SortEntries, 's'),
			  Child, KeyLabel1("View:", 'v'), Child, view_but = KeyCycle(ViewEntries, 'v'),
			  Child, VSpace(0),
			  Child, read_but = KeyButton("Readme", 'r'),
			  Child, name_but = PopobjectObject,
			      MUIA_Popstring_String, Label1(""),
			      MUIA_Popstring_Button, KeyButton("Name", 'n'),
			      MUIA_Popobject_Object, VGroup,
				  GroupFrame,
				  Child, KeyLabel1("\33cSearch for:", 'r'),
				  Child, search_str = KeyString("", 256, 'r'),
				  Child, search_next = KeyButton("Next", 'x'),
				  Child, search_can = KeyButton("Cancel", 'a'),
				  End,
			      End,
			  Child, get_but = KeyButton("Download", 'd'),
			  Child, host_but = KeyButton("Host", 'h'),
			  Child, cfg_but = KeyButton("Config", 'c'),
			  Child, quit_but = KeyButton("Quit", 'q'),
			  End,
		      Child, adt_statusobj = TextObject,
			  TextFrame,
			  MUIA_Background, MUII_TextBack,
			  MUIA_Text_PreParse, "\033c\0338",
			  End,
		      End,

/* Readme Page */
		  Child, VGroup,
		      Child, TextObject,
			 TextFrame,
			  MUIA_Background, MUII_TextBack,
			  MUIA_Text_PreParse, "\033c\033b\0338",
			  MUIA_Text_Contents, "Readme file",
			  End,
		      Child, ListviewObject,
			  MUIA_Weight, 200,
			  MUIA_Listview_Input, FALSE,
			  MUIA_Listview_List, readtext = FloattextObject,
			      MUIA_Frame, MUIV_Frame_ReadList,
			      MUIA_Background, MUII_TextBack,
			      MUIA_Floattext_TabSize, 4,
			      MUIA_Floattext_Justify, TRUE,
			      End,
			  End,
		      Child, HGroup,
			  Child, read_next_but = KeyButton("Next", 'x'),
			  Child, read_can_but = KeyButton("Cancel", 'c'),
			  Child, HSpace(13),
			  End,
		      End,

/* Downloading Page */
		  Child, VGroup,
		      Child, TextObject,
			  TextFrame,
			  MUIA_Background, MUII_TextBack,
			  MUIA_Text_PreParse, "\033c\033b\0338",
			  MUIA_Text_Contents, "Downloading",
			  End,
		      Child, getlv = ListviewObject,
			  MUIA_Listview_Input, FALSE,
			  MUIA_Listview_DoubleClick, FALSE,
			  MUIA_Listview_List, ListObject,
			      InputListFrame,
			      MUIA_List_Format, "W=1,W=200,W=50,W=10 P=\033r,W=600",
			      MUIA_List_Title, TRUE,
			      MUIA_List_ConstructHook, &file_const_hook,
			      MUIA_List_DestructHook, &file_dest_hook,
			      MUIA_List_CompareHook, &file_cmp_hook,
			      MUIA_List_DisplayHook, &file_disp_hook,
			      End,
			  End,
		      Child, HGroup,
			  Child, VGroup,
			      MUIA_Weight, 50,
			      Child, get_abort_but = KeyButton("Abort", 'a'),
			      Child, VSpace(13),
			      End,
			  Child, VGroup,
			      GroupSpacing(1),
			      MUIA_Weight, 400,
			      Child, get_gauge = GaugeObject,
				  GaugeFrame,
				  MUIA_Gauge_Horiz, TRUE,
				  End,
			      Child, ScaleObject,
				  MUIA_Scale_Horiz, TRUE,
				  End,
			      End,
			  Child, HSpace(13),
			  End,
		      End,
		  End,
	      End,

/* Hosts Window */
	  SubWindow, hosts_win = WindowObject,
	      MUIA_Window_ID, MAKE_ID('H','O','S','T'),
	      MUIA_Window_Title, "MUIAdt Hosts",
	      MUIA_Window_Width, MUIV_Window_Width_Visible(60),
	      MUIA_Window_Height, MUIV_Window_Height_Visible(35),
	      WindowContents, HGroup,
		  Child, hostslv = ListviewObject,
		      MUIA_Weight, 400,
		      MUIA_Listview_MultiSelect, FALSE,
		      MUIA_Listview_DoubleClick, TRUE,
		      MUIA_Listview_List, ListObject,
			  InputListFrame,
			  MUIA_List_Format, ",,",
			  MUIA_List_Title, TRUE,
			  MUIA_List_ConstructHook, &host_const_hook,
			  MUIA_List_DestructHook, &host_dest_hook,
			  MUIA_List_CompareHook, &host_cmp_hook,
			  MUIA_List_DisplayHook, &host_disp_hook,
			  End,
		      End,
		  Child, VGroup,
		      MUIA_Weight, 1,
		      Child, VSpace(0),
		      Child, host_add_but = KeyButton("Add", 'a'),
		      Child, host_del_but = KeyButton("Delete", 'l'),
/*			Child, host_up_but = KeyButton("Up", 'u'),
		      Child, host_down_but = KeyButton("Down", 'd'),*/
		      Child, VSpace(0),
		      Child, host_connect_but = KeyButton("Connect", 'c'),
		      Child, host_cancel_but = KeyButton("Cancel", 'n'),
		      Child, VSpace(0),
		      End,
		  End,
	      End,

/* Add Host Window */
	  SubWindow, add_host_win = WindowObject,
	      MUIA_Window_ID, MAKE_ID('A','D','D','H'),
	      MUIA_Window_Title, "Add a host",
	      WindowContents, VGroup,
		  Child, HGroup,
		      Child, KeyLabel1("Country", 'c'),
		      Child, host_add_country = StringObject,
			  StringFrame,
			  MUIA_ControlChar, 'c',
			  MUIA_String_MaxLen, 30,
			  MUIA_String_Reject, ":",
			  End,
		      End,
		  Child, HGroup,
		      Child, KeyLabel1("Site", 's'),
		      Child, host_add_site = StringObject,
			  StringFrame,
			  MUIA_ControlChar, 's',
			  MUIA_String_MaxLen, 30,
			  MUIA_String_Reject, ":",
			  End,
		      End,
		  Child, HGroup,
		      Child, KeyLabel1("Directory", 'r'),
		      Child, host_add_dir = StringObject,
			  StringFrame,
			  MUIA_ControlChar, 'r',
			  MUIA_String_MaxLen, 30,
			  MUIA_String_Reject, ":",
			  End,
		       End,
		  Child, host_add_done = KeyButton("Done", 'd'),
		  End,
	      End,
/* Config Window */
	  SubWindow, config_win = WindowObject,
	      MUIA_Window_ID, MAKE_ID('C','O','N','F'),
	      MUIA_Window_Title, "MUIAdt Config Options",
	      WindowContents, VGroup,
		  Child, HGroup, Child, KeyLabel1("Default Sort by:", 's'), Child, def_sort_but = KeyCycle(SortEntries, 's'), End,
		  Child, HGroup, Child, KeyLabel1("Default View by:", 'v'), Child, def_view_but = KeyCycle(ViewEntries, 'v'), End,
		  Child, HGroup,
		      Child, KeyLabel1("Download Directory:", 'd'),
		      Child, def_getdir = PopaslObject,
			  MUIA_Popstring_String, KeyString("", 256, 'd'),
			  MUIA_Popstring_Button, PopButton(MUII_PopDrawer),
			  ASLFR_TitleText  , "Please select a drawer...",
			  ASLFR_DrawersOnly, TRUE,
			  End,
		      End,
		  Child, HGroup,
		      Child, KeyLabel1("Temporary Directory:", 't'),
		      Child, def_tmpdir = PopaslObject,
			  MUIA_Popstring_String, KeyString("", 256, 't'),
			  MUIA_Popstring_Button, PopButton(MUII_PopDrawer),
			  ASLFR_TitleText  , "Please select a drawer...",
			  ASLFR_DrawersOnly, TRUE,
			  End,
		      End,
		  Child, HGroup,
		      Child, KeyLabel1("Uncompress Command:", 'u'),
		      Child, def_uncomp = KeyString("", 256, 'u'),
		      End,
		  Child, HGroup, Child, HSpace(0), Child, def_done = KeyButton("Done", 'o'), Child, HSpace(0), End,
		  End,
	      End,
	  End;
    if (!app) fail(app, "Couldn't create application.");

/* Respond to option button presses */
    DoMethod(sort_but, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, app, 2, MUIM_Application_ReturnID, ID_Sort);
    DoMethod(view_but, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, app, 2, MUIM_Application_ReturnID, ID_View);
    DoMethod(read_but, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_Readme);
    DoMethod(get_but, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_Get);
    DoMethod(host_but, MUIM_Notify, MUIA_Pressed, FALSE, hosts_win, 3, MUIM_Set, MUIA_Window_Open, TRUE);
    DoMethod(cfg_but, MUIM_Notify, MUIA_Pressed, FALSE, config_win, 3, MUIM_Set, MUIA_Window_Open, TRUE);
    DoMethod(quit_but, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);

/* Respond to buttons in the name search popup */
    DoMethod(search_str, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, app, 2, MUIM_Application_ReturnID, ID_Name);
    DoMethod(search_next, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_Name);
    DoMethod(search_can, MUIM_Notify, MUIA_Pressed, FALSE, name_but, 2, MUIM_Popstring_Close, TRUE);

/* Respond to double clicking in one of the file listviews */
    DoMethod(recentlv, MUIM_Notify, MUIA_Listview_DoubleClick,TRUE, app, 2, MUIM_Application_ReturnID, ID_Readme);
    DoMethod(shortlv, MUIM_Notify, MUIA_Listview_DoubleClick,TRUE, app, 2, MUIM_Application_ReturnID, ID_Readme);
    DoMethod(newlv, MUIM_Notify, MUIA_Listview_DoubleClick,TRUE, app, 2, MUIM_Application_ReturnID, ID_Readme);
    DoMethod(taggedlv, MUIM_Notify, MUIA_Listview_DoubleClick,TRUE, app, 2, MUIM_Application_ReturnID, ID_Readme);

/* Respond to the readme page buttons */
    DoMethod(read_next_but, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_ReadNext);
    DoMethod(read_can_but, MUIM_Notify, MUIA_Pressed, FALSE, mainpage, 3, MUIM_Set, MUIA_Group_ActivePage, FILE_PAGE);

/* Respond to the download abort button */
    DoMethod(get_abort_but, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_GetAbort);
/**/DoMethod(get_abort_but, MUIM_Notify, MUIA_Pressed, FALSE, mainpage, 3, MUIM_Set, MUIA_Group_ActivePage, FILE_PAGE);

/* Respond to events in the hosts window */
    DoMethod(hosts_win, MUIM_Window_SetCycleChain, hostslv, host_add_but, host_del_but, host_connect_but, host_cancel_but, NULL);
    set(hosts_win, MUIA_Window_ActiveObject, hostslv);
    DoMethod(hosts_win, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, hosts_win, 3, MUIM_Set, MUIA_Window_Open, FALSE);
    DoMethod(hostslv, MUIM_Notify, MUIA_Listview_DoubleClick,TRUE, app, 2, MUIM_Application_ReturnID, ID_HostsConnect);
    DoMethod(host_add_but, MUIM_Notify, MUIA_Pressed, FALSE, add_host_win, 3, MUIM_Set, MUIA_Window_Open, TRUE);
    DoMethod(host_del_but, MUIM_Notify, MUIA_Pressed, FALSE, hostslv, 2, MUIM_List_Remove, MUIV_List_Remove_Active);
    DoMethod(host_connect_but, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_HostsConnect);
    DoMethod(host_cancel_but, MUIM_Notify, MUIA_Pressed, FALSE, hosts_win, 3, MUIM_Set, MUIA_Window_Open, FALSE);

/* Respond to events in the add a host window */
    DoMethod(add_host_win, MUIM_Window_SetCycleChain, host_add_country, host_add_site, host_add_dir, host_add_done, NULL);

    DoMethod(add_host_win, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, add_host_win, 3, MUIM_Set, MUIA_Window_Open, FALSE);
    DoMethod(host_add_done, MUIM_Notify, MUIA_Pressed, FALSE, add_host_win, 3, MUIM_Set, MUIA_Window_Open, FALSE);
    DoMethod(host_add_done, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_AddHost);

/* Respond to the config page buttons */
    DoMethod(config_win, MUIM_Window_SetCycleChain, def_sort_but, def_view_but, def_getdir, def_tmpdir, def_uncomp, def_done, NULL);
    DoMethod(config_win, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, config_win, 3, MUIM_Set, MUIA_Window_Open, 0);
    DoMethod(def_done, MUIM_Notify, MUIA_Pressed, FALSE, app, 2, MUIM_Application_ReturnID, ID_Config);

/* Get Prefs */
    if (read_prefs()) adt_status("Welcome new user.");
    else adt_status("Welcome.");

/* Start the window up then */
    DoMethod(win, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit);
    set(win, MUIA_Window_Open, TRUE);

    while (running) {
	ULONG signal;

	switch (DoMethod(app, MUIM_Application_Input, &signal))
	{
	    case MUIV_Application_ReturnID_Quit:
		running = FALSE;
		break;

	    case ID_Sort: {
		int page;

		sortrecent = sortshort = sortnew = sorttagged = TRUE;
		get(sort_but, MUIA_Cycle_Active, &sorttype);
		get(lvpage, MUIA_Group_ActivePage, &page);
		switch(page) {
		    case FILE_RECENT_PAGE:
			DoMethod(recentlv, MUIM_List_Sort);
			sortrecent = FALSE;
			break;
		    case FILE_ALL_PAGE:
			DoMethod(shortlv, MUIM_List_Sort);
			sortshort = FALSE;
			break;
		    case FILE_TAGGED_PAGE:
			DoMethod(taggedlv, MUIM_List_Sort);
			sorttagged = FALSE;
			break;
		    case FILE_NEW_PAGE:
			DoMethod(newlv, MUIM_List_Sort);
			sortnew = FALSE;
			break;
		}
		break;
	    }

	    case ID_View:
		if (connected) {
		    get(view_but, MUIA_Cycle_Active, &viewtype);
		    switch(viewtype) {
			case 0:
			    show_new();
			    break;

			case 1:
			    show_recent();
			    break;

			case 2:
			    show_short();
			    break;

			case 3:
			    show_tagged();
			    break;
		    }
		} else adt_status("Not Connected");
		set(win, MUIA_Window_ActiveObject, currentlv());
		break;

	    case ID_Readme: {
		APTR curntlv;
		struct FileLineRec *flr;
		readpos = -1;
		curntlv = currentlv();
		DoMethod(curntlv, MUIM_List_NextSelected, &readpos);
		if (readpos == -1) break;
		DoMethod(curntlv, MUIM_List_GetEntry, readpos, &flr);
		if (HAS_README(flr)) readme(flr->dir, flr->readme);
		break;
	    }

	    case ID_ReadNext: {
		APTR curntlv;
		struct FileLineRec *flr;

		curntlv = currentlv();
		DoMethod(curntlv, MUIM_List_NextSelected, &readpos);
		if (readpos == -1) {
		    set(mainpage, MUIA_Group_ActivePage, FILE_PAGE);
		    break;
		}
		DoMethod(curntlv, MUIM_List_GetEntry, readpos, &flr);
		if (HAS_README(flr)) readme(flr->dir, flr->readme);
		break;
	    }

	    case ID_Name: {
		LONG pos;
		struct FileLineRec *flr;
		char *str;
		register BOOL stop = FALSE;
		register int srclen, destlen;
		register int i;

		get(search_str, MUIA_String_Contents, &str);
		srclen = strlen(str);
		get(currentlv(), MUIA_List_Active, &pos);
		if (pos < 0) pos = 0;
		else pos++;
		for(;!stop;pos++) {
		    DoMethod(currentlv(), MUIM_List_GetEntry, pos, &flr);
		    if (!flr) break;
		    destlen = strlen(flr->name);
		    for (i=0;i<=destlen-srclen&&!stop;i++) {
			if (!strnicmp(str, &flr->name[i], srclen)) {
			    set(currentlv(), MUIA_List_Active, pos);
			    stop=TRUE;
			}
		    }
		}
		break;
	    }

	    case ID_Get: {
		LONG page, pos=-1, pos2;
		struct FileLineRec *flr, *flr2;
		BOOL stop=FALSE;
		int result=0;

		if (connected) {
		    DoMethod(currentlv(), MUIM_List_NextSelected, &pos);
		    if (pos == -1) break;
		    DoMethod(getlv, MUIM_List_Clear, NULL);
		    get(lvpage, MUIA_Group_ActivePage, &page);
		    switch(page) {
			case FILE_RECENT_PAGE:
			    copy_tagged(getlv); break;
			case FILE_ALL_PAGE:
			    copy_tagged(getlv); break;
			case FILE_TAGGED_PAGE:
			    copy_tagged(getlv); break;
			case FILE_NEW_PAGE:
			    copy_tagged(getlv); break;
		    }
		    set(mainpage, MUIA_Group_ActivePage, GET_PAGE);

		    pos = 0;
		    while(result != 2) {
			char file[256], local[256];

			DoMethod(getlv, MUIM_List_GetEntry, pos, &flr);
			if (!flr) break;
			joinpaths(file, flr->dir, flr->name);
			joinpaths(local, prefs.getdir, flr->name);
			result = get_file(file, local, flr->intsize);
			if (!result) {
			    stop = FALSE;
			    pos2 = -1;
			    while(!stop) {
				DoMethod(currentlv(), MUIM_List_NextSelected, &pos2);
				if (pos2 == -1) break;
				DoMethod(currentlv(), MUIM_List_GetEntry, pos2, &flr2);
				if (flr2->time == flr->time) {
				    DoMethod(currentlv(), MUIM_List_Select, pos2, MUIV_List_Select_Off, NULL);
				    stop = TRUE;
				}
			    }
			    DoMethod(getlv, MUIM_List_Remove, pos);
			}
			else {
/*			      printf("error getting %s\n", file); */
			    pos++;
			}
		    }
		    /* Copy remaining entries back to lvpage */
		    set(mainpage, MUIA_Group_ActivePage, FILE_PAGE);
		}
		break;
	    }

	    case ID_HostsConnect: {
		char *error;
		LONG pos=-1;
		struct HostLineRec *hlr;

		/* Connect to a host and download the default file list */
		DoMethod(hostslv, MUIM_List_NextSelected, &pos);
		if (pos >= 0) {
		    set(win, MUIA_Window_Sleep, TRUE);
		    set(hosts_win, MUIA_Window_Open, FALSE);
		    gotrecent = gotshort = gotnew = FALSE;
		    DoMethod(recentlv, MUIM_List_Clear, NULL);
		    DoMethod(newlv, MUIM_List_Clear, NULL);
		    DoMethod(shortlv, MUIM_List_Clear, NULL);
		    {
			char file[256];
			joinpaths(file, prefs.tmpdir, "RECENT.adt");
			remove(file);
			joinpaths(file, prefs.tmpdir, "SHORT.adt");
			remove(file);
		    }

		    pos=-1;
		    DoMethod(hostslv, MUIM_List_NextSelected, &pos);
		    DoMethod(hostslv, MUIM_List_GetEntry, pos, &hlr);
		    adt_status("Connecting");
		    if (!(error = ftp_connect(hlr->host, hlr->dir))) {
			adt_status("Connected");
			DoMethod(app, MUIM_Application_ReturnID, ID_View);
			set(mainpage, MUIA_Group_ActivePage, FILE_PAGE);
			host = hlr;
		    } else if (error[0] == '*') {
			adt_status(error+1);
			fail(app, error+1);
		    } else adt_status(error);
		    set(win, MUIA_Window_Sleep, FALSE);
		}
		break;
	    }

	    case ID_Config: {
		char *tmp;
		get(def_sort_but, MUIA_Cycle_Active, &prefs.defsort);
		get(def_view_but, MUIA_Cycle_Active, &prefs.defview);
		get(def_getdir, MUIA_String_Contents, &tmp);
		strcpy(prefs.getdir, tmp);
		get(def_tmpdir, MUIA_String_Contents, &tmp);
		strcpy(prefs.tmpdir, tmp);
		get(def_uncomp, MUIA_String_Contents, &tmp);
		strcpy(prefs.uncomp, tmp);
		set(config_win, MUIA_Window_Open, FALSE);
		break;
	    }

	    case ID_AddHost: {
		char line[100], *country, *site, *dir;

		get(host_add_country, MUIA_String_Contents, &country);
		get(host_add_site, MUIA_String_Contents, &site);
		get(host_add_dir, MUIA_String_Contents, &dir);
		sprintf(line, "%s:%s:%s", country, site, dir);
		DoMethod(hostslv, MUIM_List_InsertSingle, line, MUIV_List_Insert_Bottom);
		set(host_add_country, MUIA_String_Contents, "");
		set(host_add_site, MUIA_String_Contents, "");
		set(host_add_dir, MUIA_String_Contents, "");
	    }

	}
	if (signal) Wait(signal);
    }
    {
	char file[256];
	joinpaths(file, prefs.tmpdir, "RECENT.adt");
	remove(file);
	joinpaths(file, prefs.tmpdir, "SHORT.adt");
	remove(file);
    }
    if (write_prefs(prefs.defcfg)) MUI_Request(app,win,0,NULL,"OK", "Can't save prefs.");

/* Save to envarc: if defcfg is env: */
    if (!strnicmp(prefs.defcfg, "env:", 4)) {
	char file[256];

	sprintf(file, "envarc:%s", prefs.defcfg + 4);
	if (write_prefs(file)) MUI_Request(app,win,0,NULL,"OK", "Can't save prefs to ENVARC:");
    }

    fail(app, NULL);
}


void adt_status(char *msg)
{
    set(adt_statusobj, MUIA_Text_Contents, msg);
}


/*------------- config file format ----------------
# comment
server = <default server>
prevcall = <time of last call>
getdir = <download directory>
tmpdir = <temporary directory>
defsort = <default sort method (integer)>
defview = <default view method (integer)>
uncompress = <uncompress command>
site = <country> <site> <directory>
*/

int read_prefs()
{
    FILE *fp;
    char line[256], *tag;
    int length, retval;

    if (fp = fopen(prefs.defcfg, "r")) {
	retval = 0;
	while (fgets(line, 256, fp)) {
	    if (line[0] != '#') {
		length = strlen(line);
		if (line[length-1] == '\n') line[length-1] = '\0';
		for (tag=line; *tag!='=' && *tag!='\0'; tag++);
		tag++;
		for (; *tag==' '; tag++);
		if (*tag == '\0') continue;

		if (!strnicmp(line, "server", 6))
		    strcpy(prefs.server, tag);
		if (!strnicmp(line, "prevcall", 8))
		    sscanf(tag, "%lx", &prefs.lasttime);
		if (!strnicmp(line, "getdir", 6))
		    strcpy(prefs.getdir, tag);
		if (!strnicmp(line, "tmpdir", 6))
		    strcpy(prefs.tmpdir, tag);
		if (!strnicmp(line, "defsort", 7))
		    sscanf(tag, "%lx", &prefs.defsort);
		if (!strnicmp(line, "defview", 7))
		    sscanf(tag, "%lx", &prefs.defview);
		if (!strnicmp(line, "uncompress", 10))
		    strcpy(prefs.uncomp, tag);
		if (!strnicmp(line, "site", 4))
		    DoMethod(hostslv, MUIM_List_InsertSingle, tag, MUIV_List_Insert_Bottom);

	    }
	}
	fclose(fp);
    } else {
       int i;

/* If no config file is found, use the default host sites. */
       for (i=0;DefHostList[i]!=NULL;i++) {
	   DoMethod(hostslv, MUIM_List_InsertSingle, DefHostList[i], MUIV_List_Insert_Bottom);
       }
       retval = 1;
    }

    prefs.thistime = prefs.lasttime;
    set(sort_but, MUIA_Cycle_Active, prefs.defsort);
    set(view_but, MUIA_Cycle_Active, prefs.defview);
    set(def_sort_but, MUIA_Cycle_Active, prefs.defsort);
    set(def_view_but, MUIA_Cycle_Active, prefs.defview);
    set(def_getdir, MUIA_String_Contents, prefs.getdir);
    set(def_tmpdir, MUIA_String_Contents, prefs.tmpdir);
    set(def_uncomp, MUIA_String_Contents, prefs.uncomp);
    return(retval);
}

int write_prefs(char *file)
{
    FILE *fp;
    struct HostLineRec *hlr;
    int i;

    if (!(fp = fopen(file, "w"))) return(1);
    fputs("# This is a MUIAdt config file\n", fp);
    fprintf(fp, "server = %s\n", prefs.server);
    fprintf(fp, "prevcall = %lx\n", prefs.thistime);
    fprintf(fp, "getdir = %s\n", prefs.getdir);
    fprintf(fp, "tmpdir = %s\n", prefs.tmpdir);
    fprintf(fp, "defsort = %lx\n", prefs.defsort);
    fprintf(fp, "defview = %lx\n", prefs.defview);
    fprintf(fp, "uncompress = %s\n", prefs.uncomp);
    for(i=0;;i++)
    {
	DoMethod(hostslv, MUIM_List_GetEntry, i, &hlr);
	if (!hlr) break;
	fprintf(fp, "site = %s:%s:%s\n", hlr->country, hlr->host, hlr->dir);
    }
    fclose(fp);
    return(0);
}

void joinpaths(char *str, char *path, char *file)
{
    if (strlen(path)) {
	if (path[strlen(path)-1] == '/' || path[strlen(path)-1] == ':')
	    sprintf(str, "%s%s", path, file);
	else
	    sprintf(str, "%s/%s", path, file);
    } else strcpy(str, file);
}

int get_recent(void)
{
    int retval=0;
    char local[256], command[256];

    set(recentlv, MUIA_List_Quiet, TRUE);
    joinpaths(local, prefs.tmpdir, "RECENT.adt.Z");
    adt_status("Downloading RECENT list");
    if (!get_file("info/adt/RECENT.adt.Z", local, 0)) {
	sprintf(command, "%s \"%s\"", prefs.uncomp, local);
	system(command);
	local[strlen(local)-2] = '\0';
	if (get_parse(local, recentlv) == 0) gotrecent=TRUE;
	else retval = 2;
    } else {
	adt_status("Error downloading RECENT list");
	retval = 1;
    }
    return(retval);
}

void show_new()
{
    LONG pos, numfiles;
    struct FileLineRec *flr;
    char temp[20], line[256];

    set(win, MUIA_Window_Sleep, TRUE);
    set(newlv, MUIA_List_Quiet, TRUE);
    if (!gotrecent) get_recent();
    if (gotrecent) {
	if (!gotnew) {
	    for(pos=0;;pos++) {
		DoMethod(recentlv, MUIM_List_GetEntry, pos, &flr);
		if (!flr) break;
		if (flr->time > prefs.lasttime) {
		    sprintf(line, "%lx@%s@%s;%lx@%s;@%s\n", flr->time, flr->dir, flr->name, flr->intsize, flr->readme, flr->descr);
		    DoMethod(newlv, MUIM_List_InsertSingle, line, MUIV_List_Insert_Bottom);
		}
	    }
	    gotnew = TRUE;
	}
	if (sortnew) {
	    DoMethod(newlv, MUIM_List_Sort, NULL);
	    sortnew = FALSE;
	}
	clone_tagged(newlv);
	get(newlv, MUIA_List_Entries, &numfiles);
	sprintf(temp, "New files (%d)", numfiles);
	adt_status(temp);
    }
    set(lvpage, MUIA_Group_ActivePage, FILE_NEW_PAGE);
    set(newlv, MUIA_List_Quiet, FALSE);
    set(recentlv, MUIA_List_Quiet, FALSE);
    set(win, MUIA_Window_Sleep, FALSE);
}

void show_recent()
{
    LONG numfiles;
    char temp[20];

    set(win, MUIA_Window_Sleep, TRUE);
    if (!gotrecent) get_recent();
    if (gotrecent) {
	if (sortrecent) {
	    DoMethod(recentlv, MUIM_List_Sort, NULL);
	    sortrecent = FALSE;
	}
	clone_tagged(recentlv);

	get(recentlv, MUIA_List_Entries, &numfiles);
	sprintf(temp, "Recent files (%d)", numfiles);
	adt_status(temp);
    }
    set(lvpage, MUIA_Group_ActivePage, FILE_RECENT_PAGE);
    set(recentlv, MUIA_List_Quiet, FALSE);
    set(win, MUIA_Window_Sleep, FALSE);
}

void show_short()
{
    LONG numfiles;
    char temp[20];

    set(win, MUIA_Window_Sleep, TRUE);
    set(shortlv, MUIA_List_Quiet, TRUE);
    if (!gotshort) {
	char local[256], command[256];

	joinpaths(local, prefs.tmpdir, "SHORT.adt.Z");
	adt_status("Downloading LONG list");
	if (!get_file("info/adt/SHORT.adt.Z", local, 0)) {
	    sprintf(command, "%s \"%s\"", prefs.uncomp, local);
	    system(command);
	    local[strlen(local)-2] = '\0';
	    if(!get_parse(local, shortlv)) gotshort=TRUE;
	} else adt_status("Error downloading LONG list");
    }
    if (gotshort) {
	if (sortshort) {
	    DoMethod(shortlv, MUIM_List_Sort, NULL);
	    sortshort = FALSE;
	}
	clone_tagged(shortlv);

	get(shortlv, MUIA_List_Entries, &numfiles);
	sprintf(temp, "All files (%d)", numfiles);
	adt_status(temp);
    }
    set(lvpage, MUIA_Group_ActivePage, FILE_ALL_PAGE);
    set(shortlv, MUIA_List_Quiet, FALSE);
    set(win, MUIA_Window_Sleep, FALSE);
}

void show_tagged()
{
    char temp[40];
    LONG numfiles;

    set(taggedlv, MUIA_List_Quiet, TRUE);
    DoMethod(taggedlv, MUIM_List_Clear, NULL);
    copy_tagged(taggedlv);
    if (sorttagged) {
	DoMethod(taggedlv, MUIM_List_Sort, NULL);
	sorttagged = FALSE;
    }
    set(lvpage, MUIA_Group_ActivePage, FILE_TAGGED_PAGE);
    set(taggedlv, MUIA_List_Quiet, FALSE);

    get(taggedlv, MUIA_List_Entries, &numfiles);
    sprintf(temp, "Tagged files (%d)", numfiles);
    adt_status(temp);
}

void readme(char *dir, char *name)
{
    char fullpath[256], local[256], *buffer;
    int fh;
    struct stat st;
    char adt_status_text[100], temp[100], *ptr;

    set(win, MUIA_Window_Sleep, TRUE);
    get(adt_statusobj, MUIA_Text_Contents, &ptr);
    strcpy(adt_status_text, ptr);
    sprintf(temp, "Downloading %s", name);
    adt_status(temp);

/* download readme and put it in the readme page */
    joinpaths(fullpath, dir, name);
    joinpaths(local, prefs.tmpdir, name);

    if (!get_file(fullpath, local, 0) && (fh = open(local, O_RDONLY))) {
	stat(local, &st);
	if (buffer = AllocMem(st.st_size, MEMF_ANY|MEMF_CLEAR)) {
	    read(fh, buffer, st.st_size);
	    set(readtext, MUIA_Floattext_Text, buffer);
	    set(mainpage, MUIA_Group_ActivePage, README_PAGE);

	    close(fh);
	    FreeMem(buffer, st.st_size);
	}
    }
    remove(local);
    adt_status(adt_status_text);
    set(win, MUIA_Window_Sleep, FALSE);
}

APTR currentlv()
{
    LONG page;

    get(lvpage, MUIA_Group_ActivePage, &page);
    switch(page) {
	case FILE_RECENT_PAGE:
	    return(recentlv); break;
	case FILE_ALL_PAGE:
	    return(shortlv); break;
	case FILE_TAGGED_PAGE:
	    return(taggedlv); break;
	case FILE_NEW_PAGE:
	    return(newlv); break;
    }
}

int get_file(char *dir, char *file, int size)
{
    return(ftp_get(dir, size, file));
}

static APTR beforetagged=NULL;

void clone_tagged(APTR destlv)
{
    APTR curntlv;
    LONG pos=-1;
    struct FileLineRec *srcflr, *destflr;

    curntlv = currentlv();

/* Clone tagged from the previous listview if switching from tagged lv
  (because tagged lines will not hold same positions relative to other lv's) */

    if (curntlv == taggedlv && destlv != taggedlv) curntlv = beforetagged;
    if (curntlv != destlv) {
	DoMethod(destlv, MUIM_List_Select, MUIV_List_Select_All, MUIV_List_Select_Off, NULL);
	for (;;) {
	    DoMethod(curntlv, MUIM_List_NextSelected, &pos);
	    if (pos == -1) break;
	    DoMethod(curntlv, MUIM_List_GetEntry, pos, &srcflr);
	    DoMethod(destlv, MUIM_List_GetEntry, pos, &destflr);
	    if (destflr && (srcflr->time == destflr->time)) {
		DoMethod(destlv, MUIM_List_Select, pos, MUIV_List_Select_On, NULL);
	    }
	}
    }
}

void copy_tagged(APTR destlv)
{
    APTR curntlv;
    LONG pos=-1;
    struct FileLineRec *flr;
    char line[256];

    curntlv = currentlv();
    if (destlv == taggedlv) beforetagged = curntlv;
    for (;;) {
	DoMethod(curntlv, MUIM_List_NextSelected, &pos);
	if (pos == -1) break;
	DoMethod(curntlv, MUIM_List_GetEntry, pos, &flr);
	sprintf(line, "%lx@%s@%s;%lx@%s;@%s\n", flr->time, flr->dir, flr->name, flr->intsize, flr->readme, flr->descr);
	DoMethod(destlv, MUIM_List_InsertSingle, line, MUIV_List_Insert_Bottom);
    }
}

void copy_all(APTR destlv)
{
    APTR curntlv;
    LONG pos;
    struct FileLineRec *flr;
    char line[256];

    curntlv =	currentlv();
    for (pos=0;;pos++){
	DoMethod(curntlv, MUIM_List_GetEntry, pos, &flr);
	if (!flr) break;
	sprintf(line, "%lx@%s@%s;%lx@%s;@%s\n", flr->time, flr->dir, flr->name, flr->intsize, flr->readme, flr->descr);
	DoMethod(destlv, MUIM_List_InsertSingle, line, MUIV_List_Insert_Bottom);
    }
}

int get_parse(char *file, APTR lv)
{
    FILE *fp;
    char temp[40];
    int version=0, err=0;

    DoMethod(lv, MUIM_List_Clear, NULL);
    adt_status("Parsing file list");
    if (!(fp = fopen(file, "r"))) {
	adt_status("Error: Uncompress failed");
	return(1);
    }

    if (fscanf(fp, "adt-v%d\n", &version) != 1) {
	fclose(fp);
	sprintf(temp, "Error parsing %s file list", file);
	adt_status(temp);
	return(1);
    }

/*    switch(version) {
	case 1: */
	    err = adt_parse_v1(fp, lv);
/*	      break;
    } */

    fclose(fp);
    return(err);
}


int adt_parse_v1(FILE *in, APTR lv)
{
    char lnbuf[256];

    while (fgets(lnbuf, 256, in))
	DoMethod(lv, MUIM_List_InsertSingle, lnbuf, MUIV_List_Insert_Bottom);
    return(0);
}

