#include <exec/types.h>
#include <exec/memory.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <intuition/intuitionbase.h>
#include <proto/graphics.h>
#include <arp/arpbase.h>
#include <string.h>

#include "base.h"
#include "baseview.h"

#define ONOFFGADS 9 /* antall gadgets som skal slåes av og på */
#define ON 1
#define OFF 0

/* dette er rutiner som finnes i andre moduler,
   de settes inn av linkeren */

/* hentlagre.c */
extern struct Liste *hent_liste(struct Liste **,struct Liste **);
extern void lagre_liste(struct Liste *,int);
extern struct Liste *geticonfile(struct WBStartup *,struct Liste **,struct Liste **);

/* visliste.c */
extern void show_liste(struct Liste *);
extern void sjekkposisjon(struct Liste *);
extern void visliste(struct Liste *,struct Gadget *,char *,int);
extern void finnantall(struct Liste *);
extern struct Liste *vislpost(struct Liste *,short);
extern void scroll_up_down(short);
extern void juster_liste(int);

/* globale funksjoner */

void sett_ny_YOffset(struct Gadget *,int);
void show_warn(char *);
void sett_inn_post(struct Liste **,struct Liste **,struct Liste *);

/* lokale funksjoner */

static int mystrcmp(UBYTE *,UBYTE *);
static void legg_inn_data(struct Liste *);
static void draw_display();
static struct Liste *finn_post(struct Liste *);
static struct Liste *fjern_post(struct Liste **,struct Liste **,struct Liste *);
static void plukk_ut_post(struct Liste **,struct Liste **,struct Liste *);
static int open_display();
static int open_libs();
static void cleanup();
static struct Liste *ny_post(struct Liste **,struct Liste **,struct liste *);
static void turn_off_gadgets();
static int turn_on_gadgets();
static void vis_nypost(struct Liste *);
static int event(int);
static int big_window();
static void small_window();
static int smallevent();

/* diverse globale variabler -> for alle moduler */

struct Window *w = NULL; 			/* hoved vinduet */
struct Window *lw = NULL; 			/* vis liste vinduet */
struct ArpBase *ArpBase = NULL;

/* diverse lokale variabler -> for denne modulen */

static struct RastPort *rp;
static struct IntuiMessage *mesg;
static struct Gadget *MIAddress;
static ULONG wakeup;
static ULONG class;
static USHORT code;
static USHORT curr_gadget;
static USHORT glpos;

static int yoffset = 0;

static struct Liste *lhode = NULL;
static struct Liste *lslutt = NULL;
static struct Liste *denne = NULL;
static int tilstand;
static int ticks,delay,selected;
static int state;
static int cliked;

/* melding for DisplayAlert, dette er en alvorlig advarsel */
char alert[] = {
	0,80,20,'F','o','r',' ','l','i','t','e',' ','r','a','m',
	' ','t','i','l',' ','å',' ','å','p','n','e',' ','h','o',
	'v','e','d','v','i','n','d','u','e','t','.',' ','S','l',
	'å',' ','a','v',' ','a','n','d','r','e',' ','v','i','n',
	'd','u','e','r','!',0
};

/************************************************************************/
/* spesial STRCMP for å sortere norske æ,ø og å */

static int mystrcmp(str1,str2)
register UBYTE *str1,*str2;
{
	register short s1,s2;
	register UBYTE c1,c2;
	
	while (*str1) {
		c1 = *str1; /* plukk ut et tegn fra tekst 1 */
		c2 = *str2; /* plukk ut et tegn fra tekst 2 */
		s1 = (short)c1; /* gjør tegne 1 om til short */
		s2 = (short)c2; /* gjør tegne 2 om til short */

		if (c1 == 'Å' || c1 == 'å') /* hvis tegn 1 er 'å' øk s1 med 100 */
			s1 += 100;
		if (c2 == 'Å' || c2 == 'å') /* hvis tegn 2 er 'å' øk s2 med 100 */
			s2 += 100;

/* sjekk om de er forskjellig */
		if (s1-s2)
			return(s1-s2); /* returner differansen hvis de er forskjellig */
		str1++; /* øk begge tekst peker med 1 for å sjekke neste tegn */
		str2++;
	}

	return(0); /* hvis tekstene er like returneres 0 */
}

/****************** her starter de GLOBALE funksjonene ********************/

void sett_ny_YOffset(struct Gadget *firstgadget,int yoffset)
{
	register struct Gadget *gd;

	gd = firstgadget;
	while(gd) {
		gd->TopEdge += yoffset;
		gd = gd->NextGadget;
	}
}


/* denne rutinen viser meldinger til bruker */

void show_warn(str)
register char *str;
{
	if (state == OFF)
		return;

	SetDrMd(rp,JAM1);
	SetAPen(rp,0);
	RectFill(rp,WPOSX+2,WPOSY-1+yoffset,w->Width-11,WPOSY+7+yoffset);
	SetAPen(rp,3);

	if (str) {
		Move(rp,(w->Width>>1)-((strlen(str)<<3)>>1),WPOSY+5+yoffset);
		Text(rp,str,strlen(str));
	}
}

/************************************************************************/
/* denne rutinen legger inn de nye postenen i riktig rekkefølge */

void sett_inn_post(lhd,lsl,pst)
struct Liste **lhd;
struct Liste **lsl;
register struct Liste *pst;
{
	register struct Liste *crt;

	if (pst == NULL)
		return;

	crt = *lhd;

	if (crt == NULL) {
		*lhd = pst;
		*lsl = pst;
		return;
	}
	else {
		while (crt) {
			if (mystrcmp(crt->Navn,pst->Navn) < 0)
				crt = crt->neste;
			else
				break;
		}
		if (crt == *lhd) {
			crt->forrige = pst;
			pst->neste = crt;
			*lhd = pst;
		}
		else if (crt) {
			pst->neste = crt;
			pst->forrige = crt->forrige;
			crt->forrige->neste = pst;
			crt->forrige = pst;
		}
		else if (crt == NULL) {
			pst->forrige = *lsl;
			pst->forrige->neste = pst;
			*lsl = pst;
		}
	}
}

/****************** her starter de LOKALE funksjonene ********************/

/* denne rutien åpner alle nødvendige libraries */

static int open_libs()
{
	if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0)))
		return(0);
	if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0)))
		return(0);
	if (!(ArpBase = (struct ArpBase *)OpenLibrary("arp.library",0)))
		return(0);

	return(1);
}

/*************************************************************************/
/* denne rutinen åpner hovedvinduet og aktiviserer menyen */

static int open_display()
{
	if (!(w  = OpenWindow(&hovednw)))
		return(0);

	/* finn ut hvor dragbar i vinduet er */
	yoffset = w->BorderTop;
	if (yoffset > 10) /* Vi har allerede justert for standard WB1.3 høyde */
		yoffset -= 10;
	else
		yoffset = 0;
	

	sett_ny_YOffset(&SleepGad,yoffset);
	if (w->TopEdge > yoffset)
		MoveWindow(w,0,-yoffset);

	if ((w->TopEdge + w->Height + yoffset) <= 256)
		SizeWindow(w,0,yoffset);

	AddGList(w,&SleepGad,-1,-1,NULL); /* legg til gadgetlisten */
	RefreshGList(&SleepGad,w,NULL,-1); /* tegn opp alle gadgets */

	juster_liste(yoffset); /* juster gadgets i vislistevinduet til ny offset */


	rp = w->RPort;
	SetMenuStrip(w,&Menu1);
	return(1);
}

/*************************************************************************/
/* denne rutinen sletter alle poster i listen */

static void slett_alt(hode)
register struct Liste *hode;
{
	register struct Liste *lst,*dummy;

	lst = hode;

	while (lst) {
		dummy = lst->neste;
		FreeMem(lst,LLENGDE);
		lst = dummy;
	}
}

/*************************************************************************/
/* denne rutine lukker alt vi har åpnet */

static void cleanup()
{
	slett_alt(lhode);
	
	if (w) {
		while ((mesg = (struct IntuiMessage *)GetMsg(w->UserPort)) != NULL)
			ReplyMsg((struct Message *)mesg);
		ModifyIDCMP(w,NULL);
		ClearMenuStrip(w);
		CloseWindow(w);
	}

	if (lw) {
		while ((mesg = (struct IntuiMessage *)GetMsg(lw->UserPort)) != NULL)
			ReplyMsg((struct Message *)mesg);	
		ClearMenuStrip(lw);
		ModifyIDCMP(lw,NULL);
		CloseWindow(lw);
	}

	if (ArpBase) CloseLibrary((struct Library *)ArpBase);
	if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
	if (GfxBase) CloseLibrary((struct Library *)GfxBase);
}

/*************************************************************************/
/*
  denne rutinen lukker alle vindu og åpner et lite vindu på toppen av
  skjermen
*/
static void small_window()
{

	if (lw) { /* slå av vislistevinduet dersom det er åpent */
		visliste(lhode,&VisListeGad,vliste,yoffset);
	}


	if (w) {
		ClearMenuStrip(w);
		CloseWindow(w);
	}

/* sett nye verdier inn i NewWindow strukturen til hoved vinduet */

	hovednw.LeftEdge = 285;
	hovednw.TopEdge = 0;
	hovednw.IDCMPFlags = SMALLIDCMPFLAGS;
	hovednw.Flags = SMALLFLAGS;
	hovednw.Width = MINXSIZE;
	hovednw.Height = MINYSIZE+yoffset;
	hovednw.FirstGadget = NULL;

/* åpne det lille vinduet */

	w = OpenWindow(&hovednw);
	rp = w->RPort;
}

/*************************************************************************/
/* denne rutine åpner det gammle hoved vinduet og lukker det lille */

static int big_window()
{
/* lukk det lille vinduet */

	CloseWindow(w);

/* sett NewWindow for hoved vinduet tilbake til orginal innstilling */

	hovednw.LeftEdge = 0;
	hovednw.TopEdge = 11;
	hovednw.Width = MAXXSIZE;
	hovednw.Height = MAXYSIZE+yoffset;
	hovednw.IDCMPFlags = NORMIDCMPFLAGS;
	hovednw.Flags = NORMFLAGS;
	hovednw.FirstGadget = &SleepGad;
/*
  Hvis vi får for lite minne til å åpne stor vinduet åpner vi det
  lille vinduet igjen, det burde ikke være noe problem.
*/
	if ((w = OpenWindow(&hovednw)) == NULL) {
		small_window();
		return(0);
	}
	else {
		rp = w->RPort;
		SetMenuStrip(w,&Menu1);
		state = ON;
		DrawBorder(rp,&WarnBorder,(long)WPOSX,(long)WPOSY-3+yoffset);
	}
	return(1);
}

/*************************************************************************/
/* denne rutinen slår av gadgets som ikke må brukes */

static void turn_off_gadgets()
{
	register struct Gadget *p;
	register int x;
	
	p = &SleepGad;

	Forbid();
	for (x=0;x<ONOFFGADS;x++,p=p->NextGadget)
		OffGadget(p,w,NULL);
	Permit();

	NavnGad.Flags ^=SELECTED;
	ActivateGadget(&NavnGad,w,NULL);
}

/*************************************************************************/
/* denne rutinen slår på alle gadgets som ble slått av */

static int turn_on_gadgets()
{
	register struct Gadget *p;
	register int x;
	
	p = &SleepGad;

	Forbid();
	for (x=0;x<ONOFFGADS;x++,p=p->NextGadget)
		OnGadget(p,w,NULL);
	Permit();

/* Fjern "ghosting" av "boolgadgets" */
	SetAPen(rp,0);
	RectFill(rp,5,w->BorderTop,w->Width-5,w->Height-5);

	DrawBorder(rp,&WarnBorder,(long)WPOSX,(long)WPOSY-3+yoffset);
	RefreshGList(&SleepGad,w,NULL,-1);

	return(0);
}

/**************************************************************************/
/* Her overføres data i string gadget bufferen til Liste structuren post */

static void legg_inn_data(post)
register struct Liste *post;
{
	if (post) {
		strcpy(post->Navn,NavnGadBuff);
		strcpy(post->Adresse,AdresseGadBuff);
		strcpy(post->PostSted,PostStedGadBuff);
		strcpy(post->Telefon,TelefonGadBuff);
		strcpy(post->PostNr,PostNrGadBuff);
	}
}

/**************************************************************************/
/* denne rutine finner den posten vi leter etter
   eller den som ligger nærmest */

static struct Liste *finn_post(lhd)
struct Liste *lhd;
{
	register struct Liste *cr;

	cr = lhd;

	while (mystrcmp(cr->Navn,NavnGadBuff) < 0) {
			if (cr->neste == NULL)
				break;
			else
				cr = cr->neste;
	}

	return(cr);
}

/*************************************************************************/
/* denne rutinen kopierer data fra en post over til string gadget bufferene
   slik at dataene kan vises, hvis den får en NULL peker vil den 
   slette alt som står i string gadgetene */

static void vis_nypost(pst)
register struct Liste *pst;
{
	if (pst) {
		strcpy(NavnGadBuff,pst->Navn);
		strcpy(AdresseGadBuff,pst->Adresse);
		strcpy(PostStedGadBuff,pst->PostSted);
		strcpy(TelefonGadBuff,pst->Telefon);
		strcpy(PostNrGadBuff,pst->PostNr);
	}
	else {
		NavnGadBuff[0]     = '\0';
		AdresseGadBuff[0]  = '\0';
		PostStedGadBuff[0] = '\0';
		TelefonGadBuff[0]  = '\0';
		PostNrGadBuff[0]   = '\0';
	}	
	RefreshGList(&NavnGad,w,NULL,5);
}

/*************************************************************************/
/* denne rutinen flytter en post ut av listen mens den redigeres */

static void plukk_ut_post(hode,slutt,sp)
register struct Liste **hode,**slutt;
register struct Liste *sp;
{
	if (sp == *hode) {
		if ((*hode)->neste) {
			*hode = sp->neste;
			(*hode)->forrige = NULL;
		}
		else {
			*hode = NULL;
			*slutt = NULL;
		}
	}
	else if (sp == *slutt) {
		*slutt = sp->forrige;
		(*slutt)->neste = NULL;
	}
	else {
		sp->forrige->neste = sp->neste;
		sp->neste->forrige = sp->forrige;
	}

	sp->forrige = NULL;
	sp->neste = NULL;
}

/*************************************************************************/
/* denne rutinen fjerner en post fra listen og 
   frigjør minnet posten har */

static struct Liste *fjern_post(hode,slutt,dn)
register struct Liste **hode,**slutt;
register struct Liste *dn;
{
	register struct Liste *dumm;
	
	dumm = NULL;
	if (dn) {
		if (dn->neste)
			dumm = dn->neste;
		else if (dn->forrige)
			dumm = dn->forrige;
		plukk_ut_post(hode,slutt,dn);
		FreeMem(dn,LLENGDE);
	}
	return(dumm);
}

/*************************************************************************/
/* denne rutinen opretter en ny post og legger data fra string gadgetene
   inn i posten. Deretter blir posten satt inn i listen  */

static struct Liste *ny_post(hode,slutt,de)
struct Liste **hode,**slutt,*de;
{
	register struct Liste *p;

	p = (struct Liste *)AllocMem(LLENGDE,MEMF_CLEAR);

	if (p) {
		legg_inn_data(p);
		sett_inn_post(hode,slutt,p);
		tilstand = turn_on_gadgets();
	}
	else {
		DisplayBeep(NULL);
		show_warn("For Lite Minne for ny post!");
	}

	if (lw) {
		finnantall(*hode);
		show_liste(*hode);
	}

	if (p)
		return(p);
	else
		return(de);
}

/*************************************************************************/
/* sjekk hva bruker valgte på menyen på menyen */

static int getmenu()
{
	switch(ITEMNUM(code)){
		case 0: 								/* hent poster */
			if (lhode) {
				if (AutoRequest(NULL,&btekst,&postxt1,&negtxt1,NULL,NULL,270,65)) {
					slett_alt(lhode);
					lhode = lslutt = denne = NULL;
					vis_nypost(NULL);
				}
			}

			denne = hent_liste(&lhode,&lslutt);
			vis_nypost(denne);

			if (lw) {
				finnantall(lhode);
				show_liste(lhode);
			}
			break;

		case 1: 								/* lagre poster */
			lagre_liste(lhode,DIREKTE);
			break;
		
		case 2:
			lagre_liste(lhode,NYTTFILNAVN);
			break;

		case 3: 								/* avslutt */
			if (lhode)
				return(!AutoRequest(NULL,&quit1,&avslutt,&fortsett,NULL,NULL,270,65));
			else
				return(0);
	}
	ticks = delay = selected = curr_gadget = 0;
	return(1);
}

/*************************************************************************/
/* her kontrollerer vi 'sleep' vinduet */

static int smallevent()
{
	static int curr_sec,curr_micro,prev_sec,prev_micro;

	switch (class) {
		case CLOSEWINDOW: /* samme sjekk som hovedvinduet */
			if(lhode)
				return(AutoRequest(NULL,&quit1,&fortsett,&avslutt,NULL,NULL,270,65));
			else
				return(0);

		case MOUSEBUTTONS: /* dobbelt klikk på høyre mustast bringer stor vinduet tilbake */
			switch (code) {
				case MENUDOWN:
					if (!cliked) {
						CurrentTime(&prev_sec,&prev_micro);
					}
					else {
						CurrentTime(&curr_sec,&curr_micro);
						if (DoubleClick(prev_sec,prev_micro,curr_sec,curr_micro))
							if (!big_window())
								DisplayAlert(RECOVERY_ALERT,alert,40);
					}
					cliked ^= 1;
					break;
				default :
					break;
			}
			break;
	}
	return(1);
}		

/**************************************************************************/
/*
  denne rutinen kontrolerer alt som skjer i liste vinduet hvis det er åpent
  funksjoner for dette vinduet er i visliste.c
*/

static int event2()
{
	register struct Liste *post;

	if (!(class & (INTUITICKS|MOUSEMOVE)))
		show_warn(0);

	switch (class) {
		case CLOSEWINDOW:
			visliste(lhode,&VisListeGad,vliste,yoffset);
			return(0);

		case MOUSEMOVE:
			sjekkposisjon(lhode);
			break;

		case INTUITICKS:
			if (selected) {
				if (delay > 2) {
					if (ticks == 1) {
						switch(curr_gadget){
							case 21:
								goto scrollup;
							case 22:
								goto scrolldown;
							default:
								break;
						}
					}
					ticks ^= 1;
				}
				else
					delay++;
			}
			break;

		case GADGETUP:
			ticks = delay = selected = curr_gadget = 0;
			goto skipit;			

		case GADGETDOWN:
			selected = 1;
			curr_gadget = MIAddress->GadgetID;
skipit:
			switch (MIAddress->GadgetID) {
				case 20: 							/* Scroll Gad */
					sjekkposisjon(lhode);
					break;
				case 21: 							/* Up Arrow */
					if (class == GADGETUP)
						break;
scrollup:
					scroll_up_down(SCROLLUP);	
					break;
				case 22: 							/* Down Arrow */
					if (class == GADGETUP)
						break;
scrolldown:
					scroll_up_down(SCROLLDOWN);
					break;
	
				default:							/* en av navnene */
					if (post = vislpost(lhode,MIAddress->GadgetID)) {
						denne = post;
						vis_nypost(denne);
					}
					break;
			}
			break;

		case MENUPICK:
			return(getmenu());
	}
	return(1);
}

/**************************************************************************/
/* denne rutinen kontrolerer hovedvinduet */

static int event1()
{
	if (class != INTUITICKS)
		show_warn(0);

	switch (class) {
		case CLOSEWINDOW:
			if(lhode)
				return(AutoRequest(NULL,&quit1,&fortsett,&avslutt,NULL,NULL,270,65));
			else
				return(0);

		case MENUPICK: 
			return(getmenu());

		case INTUITICKS:
			if (selected) {
				if (delay > 2) {
					if (ticks == 1) {
						switch (curr_gadget) {
							case 12:
								goto nestepos;
							case 13:
								goto forrigepos;
							default:
								break;
						}
					}
					ticks ^= 1;
				}
				else
					delay++;
			}
			break;

		case GADGETUP:
			ticks = delay = selected = curr_gadget = 0;
			goto around;

		case GADGETDOWN:
			selected = 1;
			curr_gadget = MIAddress->GadgetID;
around:
			switch (MIAddress->GadgetID) {
				case 1: 								/* navn */
					if (tilstand == 3)		/* er 'finn post' aktivert? */
						goto finnpostpos;	/* i så fall hopp direkte til finn post */

					ActivateGadget(&AdresseGad,w,NULL);
					break;

				case 2: 								/* adresse */
					ActivateGadget(&PostNrGad,w,NULL);
					break;

				case 3: 								/* post nr */
					ActivateGadget(&PostStedGad,w,NULL);
					break;

				case 4: 								/* post sted */
					ActivateGadget(&TelefonGad,w,NULL);
					break;

				case 5: 								/* telefon */
					switch(tilstand){
						case 0:
							show_warn("Velg Ny/Endre/Slett/Finn - post først");
							break;

						case 1: 						/* ny post */
							denne = ny_post(&lhode,&lslutt,denne);
							tilstand = turn_on_gadgets();
							break;

						case 2: 						/* endre post */ 
							plukk_ut_post(&lhode,&lslutt,denne);
							legg_inn_data(denne);
							sett_inn_post(&lhode,&lslutt,denne);
							tilstand = turn_on_gadgets();
							show_warn("Post endret!");

							if (lw)
								show_liste(lhode);

							break;

						case 3: 						/* finn post */
finnpostpos:
							denne = finn_post(lhode);
							tilstand = turn_on_gadgets();
							vis_nypost(denne);	
							show_warn("Nærmeste post funnet!");
							break;
					}
					break;

				case 6: 								/* ny post */
					vis_nypost(NULL);
					turn_off_gadgets();
					tilstand = 1;
					show_warn("Skriv inn data!");
					break;

				case 7: 								/* endre post */
					if (lhode == NULL || denne == NULL)
						break;

					turn_off_gadgets();
					tilstand = 2;
					show_warn("Endre data!");
					break;

				case 8: 								/* slett post */
					if (lhode == NULL)
						break;

					denne = fjern_post(&lhode,&lslutt,denne);					
					vis_nypost(denne);

					if (lw) {
						finnantall(lhode);
						show_liste(lhode);
					}

						show_warn("Post fjernet!");
					break;

				case 9: 								/* finn post */
					vis_nypost(NULL);

					if(lhode == NULL)
						break;

					turn_off_gadgets();
					tilstand = 3;
					break;

				case 10: 								/* vis liste */
					visliste(lhode,&VisListeGad,vliste,yoffset);

					if (lw)
						SetMenuStrip(lw,&Menu1);

					break;

				case 11:								/* slett alle */
					if (lhode) {
						if (AutoRequest(NULL,&atekst,&postxt,&negtxt,NULL,NULL,250,65)) {
							slett_alt(lhode);
							lhode = lslutt = denne = NULL;
							if(lw){
								finnantall(NULL);
								show_liste(NULL);
							}
							vis_nypost(NULL);
						}
					}

					break;

				case 12: 								/* neste post */
					if (class == GADGETUP)
						break;
nestepos:
					if (lhode == NULL || denne->neste == NULL) {
						show_warn("Siste post i listen!");
						ticks = delay = selected = curr_gadget = 0;
					}
					else if (NesteGad.Flags & SELECTED)
						denne = denne->neste;
					else
						ticks = delay = selected = curr_gadget = 0;

					vis_nypost(denne);
					break;

				case 13: 								/* forrige post */
					if (class == GADGETUP)
						break;
forrigepos:
					if (lhode == NULL || denne->forrige == NULL) {
						show_warn("Første post eller listener tom!");
						ticks = delay = selected = curr_gadget = 0;
					}
					else if (ForrigeGad.Flags & SELECTED)
						denne = denne->forrige;
					else
						ticks = delay = selected = curr_gadget = 0;

					vis_nypost(denne);
					break;
				case 15:								/* Sleep gadget */
					small_window();
					state = OFF;
					break;
			}
			break;
	}
	return(1);
}

/************************* her er hovedprogrammet ************************/
void _main(char *tline)
{
	_tinymain(tline);
}
void main(int argc,char *argv[])
{

	lhode = lslutt = NULL;
	lw = NULL;
	denne = NULL;
	ticks = delay = cliked = 0;

	state = ON;
	if (!open_libs())
		goto avslutt;

	if (!open_display())
		goto avslutt;

	DrawBorder(rp,&WarnBorder,(long)WPOSX,(long)WPOSY-3+yoffset);

/*
  Hvis argc = 0 er programmet startet fra Workbench
  og argv er en peker til en WBStartup struktur
  Hvis argc > 0 ble programmet startet fra CLI
  og argv er en peker til en array av tekststrenger som inneholder
  hvert ord på kommandolinjen.
*/
	if (argc == 0) { /* Hvis startet fra WB, sjekk om ikonet inneholder filnavn */
		if((denne = geticonfile((struct WBStartup *)argv,&lhode,&lslutt)) != NULL)
			vis_nypost(denne);
	}

	FOREVER {
/* sjekk om visliste vinduet er åpnet og vent på at noe skal skje */

		if (lw)
			wakeup = Wait((1 << w->UserPort->mp_SigBit) |
						  (1 << lw->UserPort->mp_SigBit)); /* vent på melding fra begge vinduer */
		else
			wakeup = Wait(1 << w->UserPort->mp_SigBit); /* vent kun på melding fra hovedvinduet */

/* finn ut hvilket vindu det ble gjort noe i */

		if (wakeup & (1 << w->UserPort->mp_SigBit)) { /* hovedvinduet */
			while (mesg = (struct IntuiMessage *)GetMsg(w->UserPort)) {
				class = mesg->Class;
				code = mesg->Code;
				MIAddress = (struct Gadget *)mesg->IAddress;
				ReplyMsg((struct Message *)mesg);

				if (state == OFF) {
					if (!smallevent())
						goto avslutt;
				}
				else if (!event1())
					goto avslutt;
			}
		}
		else if (lw && (wakeup & (1 << lw->UserPort->mp_SigBit))) { /* visliste vinduet */
			while (mesg = (struct IntuiMessage *)GetMsg(lw->UserPort)) {
				class = mesg->Class;
				code = mesg->Code;
				MIAddress = (struct Gadget *)mesg->IAddress;
				ReplyMsg((struct Message *)mesg);

				if (!event2()) /* hvis vinduet ble lukket, avbryt resten av beskjedene */
					 break;
			}
		}
	}

avslutt:
	cleanup();
}
