#include <CrashTickPrefs.h>

#include <dos/dostags.h>

/* presets */

struct Preset
{
   uchar *Format;
   uchar *AreaHeader;
   uchar *AreaFooter;
};

struct Preset presets[4] = { { "Area: %a\\nFile: %n\\nSize: %b\\nOrig: %o\\nDesc: %d\\n\\n",
                               "",
                               "" },
                             { "Area.........: %a\\nFilename.....: %n\\nSize.........: %b\\nOrigin.......: %o\\nDescription..: %d\\n\\n",
                               "",
                               "" },
                             { "%-30.30n %6b bytes (Hatched by %o)\\n  %d\\n\\n",
                               "%-50.50d %25.25a\\n>---------------------------------------------------------------------------\\n",
                               "" },
                             { "%-30.30n %6b %-50.50d\\n",
                               "%-50.50d %25.25a\\n>---------------------------------------------------------------------------\\n",
                               "\\n" }};

struct NewMenu annnewmenus[] = { {NM_TITLE,"",NULL,0,0,NULL},                     /* >Edit        */
                                 {NM_ITEM, "",NULL,0,0,NULL},                     /* Duplicate... */
                                 {NM_TITLE,"",NULL,0,0,NULL},                     /* >Presets     */
                                 {NM_ITEM, "",NULL,0,0,NULL},                     /* 1            */
                                 {NM_ITEM, "",NULL,0,0,NULL},                     /* 2            */
                                 {NM_ITEM, "",NULL,0,0,NULL},                     /* 3            */
                                 {NM_ITEM, "",NULL,0,0,NULL},                     /* 4            */
                                 {NM_END,  "",NULL,0,0,NULL}};

struct Hook AnnounceHelpHook = { {NULL}, HelpHookEntry,NULL,(APTR)HELP_ANNOUNCE};

struct List Announce_TempList;
struct TempNode *Announce_CurrentNode;

uchar Announce_Groupbuf[50];
uchar Announce_Akabuf[50];

uchar *Announce_Methodnames[3];

void Announce_UpdateList(void)
{
   struct TempNode *tempnode;
   struct Announce *announce;
   ulong num;

   LV_DetachList(parthandle,4000);
   FreeTempNodes(&Announce_TempList);
   NewList(&Announce_TempList);

   num=0;

   for(announce=(struct Announce *)config.AnnounceList.First;announce;announce=announce->Next)
   {
      if(tempnode=AllocCleared(sizeof(struct TempNode)))
      {
         strcpy(tempnode->buf,announce->Name);
         tempnode->Node.ln_Name=tempnode->buf;
         tempnode->UserData=announce;
         tempnode->num=num;

         num++;

         AddTail(&Announce_TempList,(struct Node *)tempnode);
      }
   }

   LV_AttachList(parthandle,4000,&Announce_TempList);
}

void Announce_ChangedNum(void)
{
   LV_ChangedNum(parthandle,4000,&Announce_TempList);

   if(!Announce_TempList.lh_Head->ln_Succ)
   {
      LT_SetAttributes(parthandle,1,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,10,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,11,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,12,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,13,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,14,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,15,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,16,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,17,GA_Disabled,TRUE,TAG_END);
      LT_SetAttributes(parthandle,18,GA_Disabled,TRUE,TAG_END);

      OffMenu(partwin,FULLMENUNUM(0,0,0));
      OffMenu(partwin,FULLMENUNUM(1,0,0));
      OffMenu(partwin,FULLMENUNUM(1,1,0));
      OffMenu(partwin,FULLMENUNUM(1,2,0));
      OffMenu(partwin,FULLMENUNUM(1,3,0));
   }
   else
   {
      LT_SetAttributes(parthandle,1,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,10,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,11,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,12,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,13,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,14,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,15,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,16,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,17,GA_Disabled,FALSE,TAG_END);
      LT_SetAttributes(parthandle,18,GA_Disabled,FALSE,TAG_END);

      OnMenu(partwin,FULLMENUNUM(0,0,0));
      OnMenu(partwin,FULLMENUNUM(1,0,0));
      OnMenu(partwin,FULLMENUNUM(1,1,0));
      OnMenu(partwin,FULLMENUNUM(1,2,0));
      OnMenu(partwin,FULLMENUNUM(1,3,0));
   }
}

void Announce_SetCurrent(ulong num)
{
   ulong c;
   struct Announce *announce;

   if(!Announce_TempList.lh_Head->ln_Succ)
   {
      LV_SetCurrent(parthandle,4000,&Announce_TempList,NULL);
      Announce_CurrentNode=NULL;
      return;
   }

   Announce_CurrentNode=(struct TempNode *)Announce_TempList.lh_Head;

   for(c=0;c<num;c++)
      Announce_CurrentNode=(struct TempNode *)Announce_CurrentNode->Node.ln_Succ;

   LV_SetCurrent(parthandle,4000,&Announce_TempList,Announce_CurrentNode);

   announce=(struct Announce *)Announce_CurrentNode->UserData;

   if(announce->Groups[0]==0)
      strcpy(Announce_Groupbuf,getString(PREFS_NO_GROUP));

   else
      strcpy(Announce_Groupbuf,announce->Groups);

   LT_SetAttributes(parthandle,10,GTTX_Text,Announce_Groupbuf,TAG_END);

   PrintFull4D(&announce->Aka->Node,Announce_Akabuf);
   LT_SetAttributes(parthandle,11,GTTX_Text,Announce_Akabuf,TAG_END);

   LT_SetAttributes(parthandle,12,GTST_String,announce->Format,TAG_END);
   LT_SetAttributes(parthandle,13,GTST_String,announce->AreaHeader,TAG_END);
   LT_SetAttributes(parthandle,14,GTST_String,announce->AreaFooter,TAG_END);
   LT_SetAttributes(parthandle,15,GTST_String,announce->Header,TAG_END);
   LT_SetAttributes(parthandle,16,GTST_String,announce->Footer,TAG_END);
   LT_SetAttributes(parthandle,17,GTST_String,announce->Subject,TAG_END);
   LT_SetAttributes(parthandle,18,GTST_String,announce->Origin,TAG_END);

   if(announce->Method == ANNOUNCE_PKT)
      LT_SetAttributes(parthandle,9,GTCY_Active,0,TAG_END);

   else
      LT_SetAttributes(parthandle,9,GTCY_Active,1,TAG_END);
}

void Announce_UpdateConfig(void)
{
   struct Announce *ann;

   if(!Announce_CurrentNode)
      return;

   ann=(struct Announce *)Announce_CurrentNode->UserData;

   strcmpcpy(ann->Format,(uchar *)LT_GetAttributes(parthandle,12,TAG_END));
   strcmpcpy(ann->AreaHeader,(uchar *)LT_GetAttributes(parthandle,13,TAG_END));
   strcmpcpy(ann->AreaFooter,(uchar *)LT_GetAttributes(parthandle,14,TAG_END));
   strcmpcpy(ann->Header,(uchar *)LT_GetAttributes(parthandle,15,TAG_END));
   strcmpcpy(ann->Footer,(uchar *)LT_GetAttributes(parthandle,16,TAG_END));
   strcmpcpy(ann->Subject,(uchar *)LT_GetAttributes(parthandle,17,TAG_END));
   strcmpcpy(ann->Origin,(uchar *)LT_GetAttributes(parthandle,18,TAG_END));

   if(LT_GetAttributes(parthandle,9,TAG_END)==0)
      ann->Method = ANNOUNCE_PKT;

   else
      ann->Method = ANNOUNCE_FILE;
}

uchar announcetestbuf[100];

uchar *table[30];

void MakeAnnounceLine(uchar *dest,ulong destsize,uchar *fmt,uchar **table)
{
   ulong c,d,e;
   ulong width,trunc;
   short left,haspercent,settrunc;

   d=0;

   haspercent=FALSE;

   for(c=0;c<strlen(fmt) && d!=destsize-1;c++)
   {
      if(haspercent)
      {
         if(fmt[c] >= '0' && fmt[c] <= '9')
         {
            if(settrunc)
               trunc=trunc*10+fmt[c]-'0';

            else
               width=width*10+fmt[c]-'0';
         }
         else if(fmt[c]=='.')
         {
            settrunc=TRUE;
         }
         else if(fmt[c]=='-')
         {
            left=TRUE;
         }
         else if(fmt[c]>='a' && fmt[c]<='z' && table[fmt[c]-'a'])
         {
            if(!left && width!=0 && strlen(table[fmt[c]-'a'])<width)
            {
               for(e=0;e<width-strlen(table[fmt[c]-'a']) && d!=destsize-1;e++)
                  dest[d++]=' ';
            }

            if(trunc!= 0 && trunc < destsize-1-d)
               strncpy(&dest[d],table[fmt[c]-'a'],trunc);

            else
               strncpy(&dest[d],table[fmt[c]-'a'],destsize-1-d);

            dest[destsize-1]=0;
            d=strlen(dest);

            if(left && width!=0 && strlen(table[fmt[c]-'a'])<width)
            {
               for(e=0;e<width-strlen(table[fmt[c]-'a']) && d!=destsize-1;e++)
                  dest[d++]=' ';
            }

            haspercent=FALSE;
         }
         else
         {
            dest[d++]=fmt[c];
            haspercent=FALSE;
         }
      }
      else
      {
         if(fmt[c]=='\\' && (fmt[c+1]|32)=='n')
         {
            strncpy(&dest[d],"\n",destsize-1-d);
            dest[destsize-1]=0;
            d=strlen(dest);
            c++;
         }
         else if(fmt[c]=='%')
         {
            settrunc=FALSE;
            left=FALSE;
            width=0;
            trunc=0;

            haspercent=TRUE;
         }
         else
         {
            dest[d++]=fmt[c];
         }
      }
   }

   dest[d]=0;
}


void Announce_Test(void)
{
   struct Announce *announce;
   BPTR fhin,fhout;
   ulong rlen,c;
   uchar *screenname;
   struct Screen *s;
   struct PubScreenNode *psnode;

   announce=(struct Announce *)Announce_CurrentNode->UserData;

   LT_LockWindow(partwin);

   if(!(fhout=Open("T:CrashTickPrefs.tmp",MODE_NEWFILE)))
   {
      sprintf(announcetestbuf,getString(PREFS_ERR_FAILED_OPEN_WRITE),"T:CrashTickPrefs.tmp");

      rtEZRequestTags(announcetestbuf,getString(PREFS_TXT_OK),NULL,NULL,
         RT_Underscore,'_',
         RT_Window,partwin,
         RTEZ_Flags, EZREQF_CENTERTEXT,
         TAG_END);

      LT_UnlockWindow(partwin);
      return;
   }

   if(announce->Method == ANNOUNCE_PKT)
      FPrintf(fhout,"Subject: %s\n\n",announce->Subject);

   Flush(fhout);

   /* Header */

   if(announce->Header[0])
   {
      if(!(fhin=Open(announce->Header,MODE_OLDFILE)))
      {
         sprintf(announcetestbuf,getString(PREFS_ERR_FAILED_OPEN_READ),announce->Header);

         rtEZRequestTags(announcetestbuf,getString(PREFS_TXT_OK),NULL,NULL,
            RT_Underscore,'_',
            RT_Window,partwin,
            RTEZ_Flags, EZREQF_CENTERTEXT,
            TAG_END);

         Close(fhout);
         DeleteFile("T:CrashTickPrefs.tmp");
         LT_UnlockWindow(partwin);
         return;
      }

      while(rlen=Read(fhin,announcetestbuf,500))
         Write(fhout,announcetestbuf,rlen);

      Close(fhin);
   }

   /* Area 1 */

   for(c=0;c<30;c++)
      table[c]=NULL;

   table['a'-'a']="AREANAME_1";
   table['d'-'a']="Area description 1";

   MakeAnnounceLine(announcetestbuf,1000,announce->AreaHeader,table);
   Write(fhout,announcetestbuf,strlen(announcetestbuf));

   for(c=0;c<30;c++)
      table[c]=NULL;

   table['a'-'a']="AREANAME_1";
   table['n'-'a']="File1.ext";
   table['p'-'a']="FILES:Area1";
   table['s'-'a']="FILES:Area1/File1.ext";
   table['b'-'a']="1024";
   table['o'-'a']="1:2/3.4";
   table['f'-'a']="5:6/7.8";
   table['m'-'a']="MAGIC1";
   table['d'-'a']="Test file #1";

   MakeAnnounceLine(announcetestbuf,1000,announce->Format,table);
   Write(fhout,announcetestbuf,strlen(announcetestbuf));

   table['a'-'a']="AREANAME_1";
   table['n'-'a']="File2.ext";
   table['p'-'a']="FILES:Area1";
   table['s'-'a']="FILES:Area1/File2.ext";
   table['b'-'a']="2048";
   table['o'-'a']="1:2/3.4";
   table['f'-'a']="5:6/7.8";
   table['m'-'a']="MAGIC2";
   table['d'-'a']="Test file #2";

   MakeAnnounceLine(announcetestbuf,1000,announce->Format,table);
   Write(fhout,announcetestbuf,strlen(announcetestbuf));

   for(c=0;c<30;c++)
      table[c]=NULL;

   table['a'-'a']="AREANAME_1";
   table['d'-'a']="Area description 1";

   MakeAnnounceLine(announcetestbuf,1000,announce->AreaFooter,table);
   Write(fhout,announcetestbuf,strlen(announcetestbuf));

   /* Area 2 */

   for(c=0;c<30;c++)
      table[c]=NULL;

   table['a'-'a']="AREANAME_2";
   table['d'-'a']="Area description 2";

   MakeAnnounceLine(announcetestbuf,1000,announce->AreaHeader,table);
   Write(fhout,announcetestbuf,strlen(announcetestbuf));

   for(c=0;c<30;c++)
      table[c]=NULL;

   table['a'-'a']="AREANAME_2";
   table['n'-'a']="File3.ext";
   table['p'-'a']="FILES:Area2";
   table['s'-'a']="FILES:Area2/File3.ext";
   table['b'-'a']="4096";
   table['o'-'a']="1:2/3.4";
   table['f'-'a']="5:6/7.8";
   table['m'-'a']="MAGIC3";
   table['d'-'a']="Test file #3";

   MakeAnnounceLine(announcetestbuf,1000,announce->Format,table);
   Write(fhout,announcetestbuf,strlen(announcetestbuf));

   table['a'-'a']="AREANAME_2";
   table['n'-'a']="File4.ext";
   table['p'-'a']="FILES:Area2";
   table['s'-'a']="FILES:Area2/File4.ext";
   table['b'-'a']="8192";
   table['o'-'a']="1:2/3.4";
   table['f'-'a']="5:6/7.8";
   table['m'-'a']="MAGIC4";
   table['d'-'a']="Test file #4";

   MakeAnnounceLine(announcetestbuf,1000,announce->Format,table);
   Write(fhout,announcetestbuf,strlen(announcetestbuf));

   for(c=0;c<30;c++)
      table[c]=NULL;

   table['a'-'a']="AREANAME_1";
   table['d'-'a']="Area description 1";

   MakeAnnounceLine(announcetestbuf,1000,announce->AreaFooter,table);
   Write(fhout,announcetestbuf,strlen(announcetestbuf));

   /* Footer */

   if(announce->Footer[0])
   {
      if(!(fhin=Open(announce->Footer,MODE_OLDFILE)))
      {
         sprintf(announcetestbuf,getString(PREFS_ERR_FAILED_OPEN_READ),announce->Footer);

         rtEZRequestTags(announcetestbuf,getString(PREFS_TXT_OK),NULL,NULL,
            RT_Underscore,'_',
            RT_Window,partwin,
            RTEZ_Flags, EZREQF_CENTERTEXT,
            TAG_END);

         Close(fhout);
         DeleteFile("T:CrashTickPrefs.tmp");
         LT_UnlockWindow(partwin);
         return;
      }

      while(rlen=Read(fhin,announcetestbuf,500))
         Write(fhout,announcetestbuf,rlen);

      Close(fhin);
   }

   /* Origin */

   Print4D(&announce->Aka->Node,announcetestbuf);

   Flush(fhout);

   if(announce->Method == ANNOUNCE_PKT)
      FPrintf(fhout,"---\n * Origin: %s (%s)\n",
         announce->Origin,
         announcetestbuf);

   Close(fhout);

   s=partwin->WScreen;

   screenname=NULL;
   if(s->Flags & WBENCHSCREEN)
   {
      screenname="Workbench";
   }
   else
   {
      if(s->Flags & PUBLICSCREEN)
      {
         /* s is a public screen so find its name */

         psnode=(struct PubScreenNode *)LockPubScreenList();

         while ((psnode) && !(screenname))
         {
            if((psnode->psn_Flags != PSNF_PRIVATE) && (psnode->psn_Screen == s))
            {
               /* found it */
               screenname = psnode->psn_Node.ln_Name;
            }
            else
            {
               /* check next one */
               psnode = (struct PubScreenNode *)psnode->psn_Node.ln_Succ;
            }
         }
         UnlockPubScreenList();
      }
   }

   sprintf(announcetestbuf,"CON:0/25//150/%s/SCREEN%s",
      getString(PREFS_ANN_TESTCONTITLE),
      screenname);

   if(fhout=Open(announcetestbuf,MODE_READWRITE))
   {
      SystemTags("more T:CrashTickPrefs.tmp",
         SYS_Input,fhout,
         SYS_Output,NULL,
         TAG_END);

      Close(fhout);
   }
   else
   {
      DisplayBeep(NULL);
   }

   DeleteFile("T:CrashTickPrefs.tmp");

   LT_UnlockWindow(partwin);
   return;
}

void Announce_SetPreset(ulong num,struct Announce *announce)
{
   strcpy(announce->Format,presets[num].Format);
   strcpy(announce->AreaHeader,presets[num].AreaHeader);
   strcpy(announce->AreaFooter,presets[num].AreaFooter);
}

void Announce_Add(void)
{
   BOOL res;
   struct Announce *ann;
   UBYTE buf[80];
   struct TempNode *tn;

   buf[0]=0;

   res=rtGetString(buf,79,getString(PREFS_LIST_ADD),NULL,
            RTGS_TextFmt,getString(PREFS_ANN_ADD),
            RTGS_Flags, GSREQF_CENTERTEXT,
            RT_Window,  partwin,
            RT_WaitPointer, TRUE,
            RT_LockWindow, TRUE,
            RT_Underscore,'_',
            TAG_END);

   if(!res)
      return;

   if(!(ann=AllocCleared(sizeof(struct Announce))))
   {
      DisplayBeep(NULL);
      return;
   }

   ann->Method=ANNOUNCE_PKT;
   strcpy(ann->Name,buf);
   ann->Aka=(struct Aka *)config.AkaList.First;
   strcpy(ann->Subject,"New files");
   strcpy(ann->Origin,"Brought to you by CrashTick");
   jbNewList(&ann->LineList);
   Announce_SetPreset(0,ann);
   jbAddNode(&config.AnnounceList,(struct jbNode *)ann);
   Announce_UpdateList();

   tn=(struct TempNode *)Announce_TempList.lh_TailPred;

   Announce_ChangedNum();
   Announce_SetCurrent(tn->num);
   config.configchanged=TRUE;
}

void Announce_Duplicate(void)
{
   BOOL res;
   struct Announce *ann,*oldann;
   UBYTE buf[80];
   struct TempNode *tn;

   oldann=(struct Announce *)Announce_CurrentNode->UserData;

   strcpy(buf,oldann->Name);

   res=rtGetString(buf,79,getString(PREFS_LIST_ADD),NULL,
            RTGS_TextFmt,getString(PREFS_ANN_ADD),
            RTGS_Flags, GSREQF_CENTERTEXT,
            RT_Window,  partwin,
            RT_WaitPointer, TRUE,
            RT_LockWindow, TRUE,
            RT_Underscore,'_',
            TAG_END);

   if(!res)
      return;

   if(!(ann=AllocCleared(sizeof(struct Announce))))
   {
      DisplayBeep(NULL);
      return;
   }

   ann->Method=oldann->Method;
   strcpy(ann->Name,buf);
   ann->Aka=oldann->Aka;
   strcpy(ann->Groups,oldann->Groups);
   strcpy(ann->Format,oldann->Format);
   strcpy(ann->Header,oldann->Header);
   strcpy(ann->Footer,oldann->Footer);
   strcpy(ann->AreaHeader,oldann->AreaHeader);
   strcpy(ann->AreaFooter,oldann->AreaFooter);
   strcpy(ann->Subject,oldann->Subject);
   strcpy(ann->Origin,oldann->Origin);
   jbNewList(&ann->LineList);
   jbAddNode(&config.AnnounceList,(struct jbNode *)ann);
   Announce_UpdateList();

   tn=(struct TempNode *)Announce_TempList.lh_TailPred;

   Announce_ChangedNum();
   Announce_SetCurrent(tn->num);
   config.configchanged=TRUE;
}

void Announce_Remove(void)
{
   struct Announce *ann;
   UBYTE buf[200];
   BOOL res;
   ULONG tmp;

   ann=(struct Announce *)Announce_CurrentNode->UserData;

   sprintf(buf,getString(PREFS_ANN_REM),ann->Name);

   res=rtEZRequestTags(buf,getString(PREFS_TXT_REMOVE_CANCEL),NULL,NULL,
      RT_Underscore,'_',
      RT_Window,partwin,
      RT_WaitPointer,TRUE,
      RT_LockWindow, TRUE,
      RTEZ_Flags, EZREQF_CENTERTEXT | EZREQF_NORETURNKEY,
      TAG_END);

   if(!res)
      return;

   tmp=Announce_CurrentNode->num;

   if(!Announce_CurrentNode->Node.ln_Succ->ln_Succ)
      tmp--;

   jbFreeNode(&config.AnnounceList,(struct jbNode *)Announce_CurrentNode->UserData,sizeof(struct Announce));

   Announce_UpdateList();
   Announce_ChangedNum();
   Announce_SetCurrent(tmp);

   config.configchanged=TRUE;
}

void PartAnnounce(void)
{
   struct IntuiMessage *IntuiMessage;
   APTR iaddress;
   ULONG class,code,qualifier;
   struct Announce *announce;
   struct Menu *annmenus;
   struct MenuItem *menuitem;
   ulong num;
   struct Aka *aka;

   if(!config.AkaList.First)
   {
      rtEZRequestTags(getString(PREFS_SECTION_AKA_NEEDED),getString(PREFS_TXT_PROCEED),NULL,NULL,
         RT_Underscore,'_',
         RT_Window,partwin,
         RTEZ_Flags, EZREQF_CENTERTEXT,
         TAG_END);

      return;
   }

   NewList(&Announce_TempList);

   parthandle = LT_CreateHandleTags(scr,LH_EditHook,     &StrEditHook,
                                        LH_RawKeyFilter, FALSE,
                                        LH_LocaleHook,   &LocaleHook,
                                        TAG_DONE);

   if(!parthandle)
      return;

   annnewmenus[0].nm_Label   = getString(PREFS_EDITMENU_EDIT);

   annnewmenus[1].nm_CommKey = getString(PREFS_EDITMENU_DUP);
   annnewmenus[1].nm_Label   = getString(PREFS_EDITMENU_DUP)+2;

   annnewmenus[2].nm_Label   = getString(PREFS_ANN_PRESET);

   annnewmenus[3].nm_CommKey = getString(PREFS_ANN_PRESET_1);
   annnewmenus[3].nm_Label   = getString(PREFS_ANN_PRESET_1)+2;

   annnewmenus[4].nm_CommKey = getString(PREFS_ANN_PRESET_2);
   annnewmenus[4].nm_Label   = getString(PREFS_ANN_PRESET_2)+2;

   annnewmenus[5].nm_CommKey = getString(PREFS_ANN_PRESET_3);
   annnewmenus[5].nm_Label   = getString(PREFS_ANN_PRESET_3)+2;

   annnewmenus[6].nm_CommKey = getString(PREFS_ANN_PRESET_4);
   annnewmenus[6].nm_Label   = getString(PREFS_ANN_PRESET_4)+2;

   annmenus=LT_LayoutMenus(parthandle,annnewmenus,
         GTMN_FrontPen,        0L,
         GTMN_TextAttr,        scr->Font,
         GTMN_NewLookMenus,    TRUE,
         LH_MenuGlyphs,        TRUE,
         TAG_DONE);

	if(!annmenus)
   {
      DisplayBeep(NULL);
      LT_DeleteHandle(parthandle);
      return;
   }

   Announce_Methodnames[0]=getString(PREFS_ANN_METHOD_PKT);
   Announce_Methodnames[1]=getString(PREFS_ANN_METHOD_FILE);
   Announce_Methodnames[2]=NULL;

   LT_New(parthandle,
      LA_Type, HORIZONTAL_KIND,
      LA_LabelID, PREFS_ANN_ANN,
      TAG_DONE);

      LT_New(parthandle,
         LA_Type,      VERTICAL_KIND,
         TAG_DONE);

         LV_CreateListView(parthandle,10,4000);

         LT_New(parthandle,
            LA_Type,      XBAR_KIND,
            TAG_DONE);

         LT_New(parthandle,
            LA_Type,      BUTTON_KIND,
            LA_LabelID,   PREFS_ANN_TEST,
            LA_Chars,     15,
            LA_ID,        1,
            TAG_DONE);

      LT_EndGroup(parthandle);

      LT_New(parthandle,
         LA_Type,      VERTICAL_KIND,
         LA_ExtraSpace,TRUE,
         TAG_DONE);

         LT_New(parthandle,
            LA_Type,      CYCLE_KIND,
            LA_LabelID,   PREFS_ANN_METHOD,
            LA_Chars,     25,
            LA_ID,        9,
            GTCY_Labels,  Announce_Methodnames,
            TAG_DONE);

         LT_New(parthandle,
            LA_Type,      TEXT_KIND,
            LA_LabelID,   PREFS_ANN_GROUPS,
            LA_Chars,     25,
            LA_ID,        10,
            LATX_Picker,  TRUE,
            GTTX_Border,  TRUE,
            TAG_DONE);

         LT_New(parthandle,
            LA_Type,       STRING_KIND,
            LA_LabelID,    PREFS_ANN_FORMAT,
            LA_Chars,      25,
            LA_ID,         12,
            GTST_MaxChars, 199,
            TAG_DONE);

         LT_New(parthandle,
            LA_Type,       STRING_KIND,
            LA_LabelID,    PREFS_ANN_AREAHEADER,
            LA_Chars,      25,
            LA_ID,         13,
            GTST_MaxChars, 499,
            TAG_DONE);

         LT_New(parthandle,
            LA_Type,       STRING_KIND,
            LA_LabelID,    PREFS_ANN_AREAFOOTER,
            LA_Chars,      25,
            LA_ID,         14,
            GTST_MaxChars, 499,
            TAG_DONE);

         LT_New(parthandle,
            LA_Type,       STRING_KIND,
            LA_LabelID,    PREFS_ANN_HEADER,
            LA_Chars,      25,
            LA_ID,         15,
            GTST_MaxChars, 39,
            LAST_Picker,  TRUE,
            TAG_DONE);

         LT_New(parthandle,
            LA_Type,       STRING_KIND,
            LA_LabelID,    PREFS_ANN_FOOTER,
            LA_Chars,      25,
            LA_ID,         16,
            GTST_MaxChars, 39,
            LAST_Picker,  TRUE,
            TAG_DONE);

         LT_New(parthandle,
            LA_Type,      TEXT_KIND,
            LA_LabelID,   PREFS_ANN_AKA,
            LA_Chars,     25,
            GTTX_Border,  TRUE,
            LA_ID,        11,
            LATX_Picker,  TRUE,
            TAG_DONE);

         LT_New(parthandle,
            LA_Type,       STRING_KIND,
            LA_LabelID,    PREFS_ANN_SUBJECT,
            LA_Chars,      25,
            LA_ID,         17,
            GTST_MaxChars, 71,
            TAG_DONE);

         LT_New(parthandle,
            LA_Type,       STRING_KIND,
            LA_LabelID,    PREFS_ANN_ORIGIN,
            LA_Chars,      25,
            LA_ID,         18,
            GTST_MaxChars, 79,
            TAG_DONE);

      LT_EndGroup(parthandle);

   LT_EndGroup(parthandle);

   partwin=LT_Build(parthandle,LAWN_IDCMP,    IDCMP_CLOSEWINDOW|IDCMP_RAWKEY,
                               LAWN_Parent,   mainwin,
                               LAWN_HelpHook, &AnnounceHelpHook,
                               LAWN_Title,    getString(PREFS_BUTTON_ANNOUNCE),
                               WA_Flags,      WFLG_ACTIVATE|WFLG_CLOSEGADGET|WFLG_DEPTHGADGET|WFLG_DRAGBAR|WFLG_NEWLOOKMENUS,
                               LAWN_Menu,     annmenus,
                               TAG_END);

   if(!partwin)
   {
      LT_DeleteHandle(parthandle);
	   FreeMenus(annmenus);
      DisplayBeep(NULL);
      return;
   }

   Announce_UpdateList();
   Announce_SetCurrent(0);
   Announce_ChangedNum();

   for(;;)
   {
      while(IntuiMessage=(struct IntuiMessage *)LT_GetIMsg(parthandle))
      {
         class=IntuiMessage->Class;
         code=IntuiMessage->Code;
         iaddress=IntuiMessage->IAddress;
         qualifier=IntuiMessage->Qualifier;

         LT_ReplyIMsg(IntuiMessage);

         switch(class)
         {
            case IDCMP_RAWKEY:         if(code == RAWKEY_TAB) LT_Activate(parthandle,4000+LV_STRING);
                                       break;

            case IDCMP_IDCMPUPDATE:    if(Announce_CurrentNode)
                                       {
                                          announce=(struct Announce *)Announce_CurrentNode->UserData;

                                          switch(((struct Gadget *)iaddress)->GadgetID)
                                          {
                                             case 10:
                                                if(EditGroups(announce->Groups,getString(PREFS_EDIT_GROUPS),partwin))
                                                {
                                                   Announce_UpdateConfig();
                                                   Announce_SetCurrent(Announce_CurrentNode->num);
                                                   config.configchanged=TRUE;
                                                }
                                                break;

                                             case 11:
                                                if(aka=AskAka(partwin))
                                                {
                                                   announce->Aka=aka;
                                                   Announce_UpdateConfig();
                                                   Announce_SetCurrent(Announce_CurrentNode->num);
                                                   config.configchanged=TRUE;
                                                }
                                                break;

                                             case 15:
                                               if(OpenReq(announce->Header,39,getString(PREFS_REQ_SELECT_FILE),partwin,FALSE))
                                                   config.configchanged=TRUE;

                                               LT_SetAttributes(parthandle,15,GTST_String,announce->Header,TAG_END);
                                            break;

                                             case 16:
                                               if(OpenReq(announce->Footer,39,getString(PREFS_REQ_SELECT_FILE),partwin,FALSE))
                                                   config.configchanged=TRUE;

                                               LT_SetAttributes(parthandle,16,GTST_String,announce->Footer,TAG_END);
                                               break;
                                          }
                                       }
                                       break;

            case IDCMP_GADGETUP:       /* No current node necessary */

                                       switch(((struct Gadget *)iaddress)->GadgetID)
                                       {
                                          case 4000+LV_ADD:
                                             Announce_UpdateConfig();
                                             Announce_Add();
                                             break;
                                       }

                                       /* Current node necessary */

                                       if(Announce_CurrentNode)
                                       {
                                          announce=(struct Announce *)Announce_CurrentNode->UserData;

                                          switch(((struct Gadget *)iaddress)->GadgetID)
                                          {
                                             case 1:
                                                Announce_UpdateConfig();
                                                Announce_Test();
                                                break;

                                             case 4000+LV_LIST:
                                                Announce_UpdateConfig();
                                                Announce_SetCurrent(code);
                                                break;

                                             case 4000+LV_STRING:
                                                strcpy(announce->Name,getgadgetstring((struct Gadget *)iaddress));
                                                LV_DetachList(parthandle,4000);
                                                strcpy(Announce_CurrentNode->buf,announce->Name);
                                                LV_AttachList(parthandle,4000,&Announce_TempList);
                                                config.configchanged=TRUE;
                                                break;

                                             case 4000+LV_REMOVE:
                                                Announce_Remove();
                                                break;

                                             case 4000+LV_UP:
                                                LV_MoveUp(parthandle,4000,&Announce_TempList,Announce_CurrentNode,&config.AnnounceList);
                                                config.configchanged=TRUE;
                                                break;

                                             case 4000+LV_DOWN:
                                                LV_MoveDown(parthandle,4000,&Announce_TempList,Announce_CurrentNode,&config.AnnounceList);
                                                config.configchanged=TRUE;
                                                break;
                                          }
                                      }
                                      break;

            case IDCMP_MENUPICK:      num=code;
                                      while(num!=MENUNULL)
                                      {
                                          if(Announce_CurrentNode)
                                          {
                                             announce=(struct Announce *)Announce_CurrentNode->UserData;

                                             if(MENUNUM(num)==0 && ITEMNUM(num)==0)
                                             {
                                                Announce_UpdateConfig();
                                                Announce_Duplicate();
                                             }

                                             if(MENUNUM(num)==1)
                                             {
                                               Announce_SetPreset(ITEMNUM(num),announce);
                                               Announce_SetCurrent(Announce_CurrentNode->num);
                                             }

                                             menuitem=ItemAddress(annmenus,num);
                                             num=menuitem->NextSelect;
                                          }
                                       }
                                      break;


            case IDCMP_CLOSEWINDOW:   Announce_UpdateConfig();
                                      ClearMenuStrip(parthandle->Window);
                                      LT_DeleteHandle(parthandle);
                                      FreeMenus(annmenus);
                                      parthandle=NULL;

                                      FreeTempNodes(&Announce_TempList);
                                      return;

         }
      }
      WaitPort(partwin->UserPort);
   }
}

/* aka, groups */
