#define DEBUG_DELAY 50
//#define DEBUG
#include <debug.h>
#include <extras/macros/intuition.h>

#include "MPP.h"
#include <ctype.h>
#include <utility/hooks.h>

long __stack = 8192;

void FixScreenModeNames(void);

extern struct LG_Control *GadControl;

BOOL MyScreen;

struct List ForcedEditList;

extern UBYTE   Version[];
extern UBYTE   ModePro[];
extern LONG SemVersion,
            SemRevision;

ULONG  Arg_Promo, Arg_NLM, Arg_Ask, Arg_CH, Arg_CV, Arg_Debug;

UBYTE   AboutText[]="ModePro\n"
                     "©1994-1997 by Michael Rivers\n"
                     "  DonationWare (see Docs)\n\n"
                     "%s\n"
                     "%s\n"
                     "  E-Mail:\n"
                     "    mrivers@gte.net\n"
                     "  WWW:\n"
                     "    http://home1.gte.net/mrivers/\n"
                     "  Mail:\n"
                     "    Michael Rivers\n"
                     "    4302 Wisconsin Court\n"
                     "    Tampa, FL, USA, 33616";


UBYTE EnvFile[]   ="ENV:ModePro.pref",
      EnvArcFile[]="ENVARC:ModePro.pref";

ULONG ActivateStrGad=0;
struct List PenList;
LONG ActivePen=0;
extern UBYTE PenNameGad[];
struct PenNode pennode[DRIPENS];
UWORD NumDriPens;
UWORD defaultpens[]=
{
  0,1,1,2,1,3,1,0,2,1,2,1
};
float XScale=1.0,
      YScale=1.0;
extern STRPTR MiscText[];
extern struct Hook StrHook,PenLVHook,StrCursorHook;
//extern struct Hook MainWinHook,PaletteWinHook;

extern struct NewGadget nglist[];
extern ULONG gtype[];
extern ULONG gtags[];
extern struct BevelBox BBox[];
extern UBYTE PenNames[DRIPENS][32];
extern UWORD PenNumbers[];
extern struct GUI_String GText[];
extern WORD PenNameLength[],
            BevelBoxes;
struct TextAttr *TAttr, User, SysFont;
struct Menu *MenuStrip;
extern struct   NewMenu nm[];      
struct TextAttr Topaz8 = { "topaz.font",8,0,0};

WORD LeftEdge,TopEdge; 

struct FontRequester *FontReq;
struct FileRequester *FileReq=NULL;
struct ScreenModeRequester *ScrReq;

APTR VI=0;
struct Gadget   *glist=0;
struct Screen   *Scr=0;
struct Window   *Win=0;
struct DrawInfo *DrawInfo;

BOOL    V39;

UBYTE   filename[513];

LONG   LVActive=0,NodeCnt=0;

ULONG  ArgEdit,ArgUse,ArgSave;
STRPTR ArgFrom,ArgPubscreen;
UBYTE  *UserFontName;
LONG   UserFontSize;

UBYTE *WindowName,
      *WinAdd,
      *Title1=" = <",
      *Title2=">";

struct Catalog *Catalog;

BOOL ClosePrefs=FALSE;
struct MPSem   *MPSem;
struct MsgPort *PrefsPort,*ReplyPort;

struct IntuitionBase *IntuitionBase; 
struct GfxBase       *GfxBase;
struct Library       *AslBase,
                     *CxBase,
                     *DiskfontBase,
                     *GadToolsBase,
                     *IconBase,
                     *IFFParseBase,
                     *LocaleBase,
                     *UtilityBase;

struct Libs MP_Libs[]=
{
  (APTR *)&AslBase,      "asl.library",        38,
  (APTR *)&CxBase,       "commodities.library",36,
  (APTR *)&DiskfontBase, "diskfont.library",   36,
  (APTR *)&GadToolsBase, "gadtools.library",   36,
  (APTR *)&GfxBase,      "graphics.library",   36,
  (APTR *)&IconBase,     "icon.library",       36,
  (APTR *)&IFFParseBase, "iffparse.library",   36,
  (APTR *)&IntuitionBase,"intuition.library",  36,
//  (APTR *)&LocaleBase,   "locale.library",     38,
  (APTR *)&UtilityBase,  "utility.library",    36,
  0,0,0
};

ULONG ListToCyc[]={1,0,2,3};
WORD  CurrentList_2=0,
      CurrentList=1;

struct NewMenu *FindNM(struct NewMenu *Array, APTR UserData);
void RefreshMenus(void);
BOOL RemakeGads(void);

void SetMPSem(void);

void main(int argc, char **argv)
{
  ULONG l;
  struct Screen *ps;
  
  LONG gotsem=0;

  if(LocaleBase=OpenLibrary("locale.library",38))
    Catalog=OpenCatalog(NULL,(STRPTR)"modeproprefs.catalog", TAG_DONE);
  else
    Catalog=NULL;
  
  InitStrings();
  NewList(&ForcedEditList);

  if(OpenLibs(ModePro,MP_Libs))
  {
    if(ps=LockPubScreen(NULL))
    {
      if(DrawInfo=GetScreenDrawInfo(ps))
      {
        for(l=0;l<DrawInfo->dri_NumPens && l<NumDriPens;l++)
          defaultpens[l]=DrawInfo->dri_Pens[l];      
        FreeScreenDrawInfo(ps,DrawInfo);
      }
      UnlockPubScreen(NULL,ps);
    }

    if(GetArgs(argc,argv))
    {
//      printf("Got Args\n");
      if(Scr=GetScreen())
      {
//        printf("Got Scr\n");
        Forbid();
        MPSem=(struct MPSem *)FindSemaphore((UBYTE *)"ModePro");
        if(MPSem)
          gotsem=AttemptSemaphoreShared(&MPSem->SharedSem);
        Permit();
        
        if(!gotsem)
        {
          EZReq(0,0,ModePro,GetString(MSG_ERR_NOPATCH),GetString(MSG_REQ_OK),0);
        }
        else
        {
//          printf("Got Sem\n");
       
          SetMPSem();
          
          if(AttemptSemaphore(&MPSem->PrefsSem))
          {
//            printf("Got P Args\n");
            if(MPSem->Version==SemVersion && MPSem->Revision==SemRevision)
            {
//              printf("Got Vers\n");

 
              if(ArgFrom)
              {
                //printf("ArgFrom = %s\n",ArgFrom);
                ObtainSemaphore(&MPSem->ListSem);
                ObtainSemaphore(&MPSem->NodeSem);
                FreeAllDefLists(MPSem->PromotionList);
                PrefLoadFile(ArgFrom);
                ReleaseSemaphore(&MPSem->NodeSem);
                ReleaseSemaphore(&MPSem->ListSem);
              }
              
              if(ArgEdit)
              {
                if(ReplyPort=CreateMsgPort())
                {
                  //printf("Got RPort\n");
                  if(PrefsPort=CreateMsgPort())
                  {
                    //printf("Got PPort\n");
                    ObtainSemaphore(&MPSem->PortSem);
                    MPSem->PrefsPort=PrefsPort;
                    ReleaseSemaphore(&MPSem->PortSem);
                    StrHook.h_Entry             =(HOOKFUNC)ExcludeHook;
                    PenLVHook.h_Entry           =(HOOKFUNC)PensLVFunc;
                    StrCursorHook.h_Entry       =(HOOKFUNC)PenValFunc;
                    //MainWinHook.h_Entry=WinBackFillHook;
                    //PaletteWinHook.h_Entry=WinBackFillHook;
               
                    NumDriPens=9;
                    V39=FALSE;
                
                    if(((struct Library *)IntuitionBase)->lib_Version>38)
                    {
                      NumDriPens=12;
                      V39=TRUE;
                    }
                    
                    if(WinAdd=WindowName=AllocVec(strlen(MPSem->HotKey)+
                                                  strlen(GetString(MSG_WINDOW_TITLE))+
                                                  strlen(Title1)+
                                                  strlen(Title2)+1,MEMF_CLEAR|MEMF_PUBLIC))
                    {
                      strcpy(WindowName,GetString(MSG_WINDOW_TITLE));
                      strcat(WindowName,Title1);
                      strcat(WindowName,MPSem->HotKey);
                      strcat(WindowName,Title2);
                    }
                    else
                    {
                      WindowName=ModePro; 
                    }
                      
//                    printf("Got WinName\n");
                    SetupPenNodes();
//            printf("Got PenNodes\n");
      
                    ObtainSemaphoreShared(&MPSem->ListSem);
                    FixScreenModeNames();
                    
//                    printf("Got ModeNames\n");
                    if(GadgetInit())
                    {
                      if(ShowGUI())
                      {
                        struct Process *proc;
                        struct Window *winptr;
  
//                            printf("Got GUI\n");
                        proc=(struct Process *)FindTask(0);
                        winptr=proc->pr_WindowPtr;
                        proc->pr_WindowPtr=Win;
                        ProcessInput();
                        DKP("main() 119\n");
                        proc->pr_WindowPtr=winptr;
                        DKP("main() 120\n");
                        HideGUI();
                      }
                      GadgetCleanup();
                    }
                    DKP("main() 200\n");
                    ReleaseSemaphore(&MPSem->ListSem);
                    DKP("main() 201\n");                     
                    FreeVec(WinAdd);
                    DKP("main() 202\n");             
                    ObtainSemaphore(&MPSem->PortSem);
                    DKP("main() 203\n");
                    MPSem->PrefsPort=0;
                    {
                      struct Message *msg;
                      while(msg=GetMsg(PrefsPort)
                        ReplyMsg(msg);
                    
                      while(msg=(struct Message *)RemHead(&ForcedEditList))
                        ReplyMsg(msg);
                    
                    }
                    DKP("main() 204\n");
                    ReleaseSemaphore(&MPSem->PortSem);
                    DKP("main() 205\n");
                    DeleteMsgPort(PrefsPort);
                    DKP("main() 206\n");                    
                  }// endif CreateMsgPort(PrefsPort)
                  DeleteMsgPort(ReplyPort);
                  DKP("main() 207\n");
                }// if CreateMsgPort(ReplyPort)
              }// endif(ArgEdit)
              else
                if(ArgSave)
                {
                  ObtainSemaphore(&MPSem->ListSem);
                  ObtainSemaphore(&MPSem->NodeSem);
                  PrefSaveFile(EnvArcFile);
                  PrefSaveFile(EnvFile);
                  ReleaseSemaphore(&MPSem->NodeSem);            
                  ReleaseSemaphore(&MPSem->ListSem);
                }
            }
            else
              EZReq(0,0,ModePro,GetString(MSG_ERR_WRONGVERSIONS),MiscText[OK],
                                         MPSem->Version,MPSem->Revision,SemVersion,SemRevision);          
            ReleaseSemaphore(&MPSem->PrefsSem);
          }//if(attemptsemshared()        
        }//endelse (gotsem)
        ReleaseScreen(Scr);
      }
      CleanupArgs();
    }
    CloseLibs(MP_Libs);
  } 
  if(LocaleBase)
  {
    CloseCatalog(Catalog);
    CloseLibrary(LocaleBase);
  }
}

void SetMPSem(void)
{
  if(Arg_Promo!=5)
  {
    MPSem->Enabled=Arg_Promo;
  }
    
  if(Arg_NLM!=5)
  {
    MPSem->EnabledNLM=Arg_NLM;
  }
    
  if(Arg_Ask!=5)
  {
    MPSem->CatchScreens=Arg_Ask;
  }
    
  if(Arg_CH!=5)
  {
    MPSem->CenterAll=(MPSem->CenterAll & ~1) | ( Arg_CH ? 1 : 0);
  }
  
  if(Arg_CV!=5)
  {
    MPSem->CenterAll=(MPSem->CenterAll & ~2) | ( Arg_CV ? 2 : 0);
  }
   
  if(Arg_Debug!=5)
  {
    MPSem->Debug=Arg_Debug;
  }
}


void ProcessInput(void)
{
  struct IntuiMessage *imsg;
  ULONG  winsig, signal, prefsig, allsigs,replysig;
  
  replysig= 1 << ReplyPort->mp_SigBit;
  prefsig = 1 << PrefsPort->mp_SigBit; 
  winsig  = 1 << Win->UserPort->mp_SigBit;  
  allsigs = replysig | winsig | prefsig | SIGBREAKF_CTRL_C;
  
  while (!ClosePrefs)
  {

    signal=Wait(allsigs);
    
    if(replysig & signal)
    {
      struct MPMessage *mpm;
      while(mpm=(struct MPMessage *)GetMsg(ReplyPort))
      {
        //printf("Freeing Replied Msg %8x\n",mpm);
        FreeVec(mpm);
      }
    }
    
    
    if(SIGBREAKF_CTRL_C & signal)
      ClosePrefs=TRUE;

    if(winsig & signal)
    {
      while(imsg = GT_GetIMsg(Win->UserPort))
      {
        switch (imsg->Class)
        {
          case IDCMP_NEWSIZE:
            if(!RemakeGads())
            {
              ClosePrefs=TRUE;   
            }
            break;
          case IDCMP_MOUSEMOVE:
            process_mousemoves(imsg);
            break;
          case IDCMP_GADGETUP:           
            process_gadgetups(imsg);
            break;
          case IDCMP_VANILLAKEY:
            Process_Keys(imsg);
            break;
          case IDCMP_REFRESHWINDOW:

            GT_BeginRefresh(Win);
            RefreshGUI();
            GT_EndRefresh(Win,TRUE);
            break;
          case IDCMP_MENUPICK:
            process_menus(imsg);
            break;            
        }
        GT_ReplyIMsg(imsg);
      }
      {
        struct DefaultNode *n;
        
        if(n=GetActiveNode())
        {
          switch(ActivateStrGad)
          {
            /*****************************************************************************
            case GD_NAME:
              if(CurrentList==PL_SCREENMODES)
                ActivateStrGad=0;
                break;
            ******************************************************************************/
            case GD_WIDTH:
            case GD_HEIGHT:
              if(n->ModeSelect!=MS_PROMOTE_SCREENMODE && n->ModeSelect!=MS_PROMOTE_REQUESTER)
                ActivateStrGad=0;
              break;
            case GD_PENVAL:
              if(!n->Look3D)
                ActivateStrGad=0;
              break;
            case GD_LOCKEDPENS:
              if(!(n->Flags & SHAREPENS))
                ActivateStrGad=0;
              break;
            case GD_PUBNAME:
              if(n->PubOptions==0)
                ActivateStrGad=0;
              break;
            case GD_HOTKEYSTR:
              if(!(n->Flags & SCRHOTKEY))
                ActivateStrGad=0;
              break;
          }
        }
        else
          ActivateStrGad=0;
      }
      if(ActivateStrGad)
      {
        
        ActivateGadget(LG_GetGadget(GadControl,ActivateStrGad),Win,NULL);
        ActivateStrGad=0;
      }
    }
    
    if(prefsig & signal)
      ProcessPrefsMessages();
  }
}       

struct TextFont *GUIFont=0;

BOOL RemakeGads(void)
                    }
                    
                    if(ForcedEditMsg)
                      ReplyMsg(ForcedEditMsg);
                    
                    DKP("main() 204\n");
                    ReleaseSemaphore(&MPSem->PortSem);
                    DKP("main() 205\n");
                    DeleteMsgPort(PrefsPort);
                    DKP("main() 206\n");                    
                  }// endif CreateMsgPort(PrefsPort)
                  DeleteMsgPort(ReplyPort);
                  DKP("main() 207\n");
                }// if CreateMsgPort(ReplyPort)
              }// endif(ArgEdit)
              else
                if(ArgSave)
                {
                  ObtainSemaphore(&MPSem->ListSem);
                  ObtainSemaphore(&MPSem->NodeSem);
                  PrefSaveFile(EnvArcFile);
                  PrefSaveFile(EnvFile);
                  ReleaseSemaphore(&MPSem->NodeSem);            
                  ReleaseSemaphore(&MPSem->ListSem);
                }
            }
            else
              EZReq(0,0,ModePro,GetString(MSG_ERR_WRONGVERSIONS),MiscText[OK],
                                         MPSem->Version,MPSem->Revision,SemVersion,SemRevision);          
            ReleaseSemaphore(&MPSem->PrefsSem);
          }//if(attemptsemshared()        
        }//endelse (gotsem)
        ReleaseScreen(Scr);
      }
      CleanupArgs();
    }
    CloseLibs(MP_Libs);
  } 
  if(LocaleBase)
  {
    CloseCatalog(Catalog);
    CloseLibrary(LocaleBase);
  }
}

void SetMPSem(void)
{
  if(Arg_Promo!=5)
  {
    MPSem->Enabled=Arg_Promo;
  }
    
  if(Arg_NLM!=5)
  {
    MPSem->EnabledNLM=Arg_NLM;
  }
    
  if(Arg_Ask!=5)
  {
    MPSem->CatchScreens=Arg_Ask;
  }
    
  if(Arg_CH!=5)
  {
    MPSem->CenterAll=(MPSem->CenterAll & ~1) | ( Arg_CH ? 1 : 0);
  }
  
  if(Arg_CV!=5)
  {
    MPSem->CenterAll=(MPSem->CenterAll & ~2) | ( Arg_CV ? 2 : 0);
  }
   
  if(Arg_Debug!=5)
  {
    MPSem->Debug=Arg_Debug;
  }
}


void ProcessInput(void)
{
  struct IntuiMessage *imsg;
  ULONG  winsig, signal, prefsig, allsigs,replysig;
  
  replysig= 1 << ReplyPort->mp_SigBit;
  prefsig = 1 << PrefsPort->mp_SigBit; 
  winsig  = 1 << Win->UserPort->mp_SigBit;  
  allsigs = replysig | winsig | prefsig | SIGBREAKF_CTRL_C;
  
  while (!ClosePrefs)
  {

    signal=Wait(allsigs);
    
    if(replysig & signal)
    {
      struct MPMessage *mpm;
      while(mpm=(struct MPMessage *)GetMsg(ReplyPort))
      {
        //printf("Freeing Replied Msg %8x\n",mpm);
        FreeVec(mpm);
      }
    }
    
    
    if(SIGBREAKF_CTRL_C & signal)
      ClosePrefs=TRUE;

    if(winsig & signal)
    {
      while(imsg = GT_GetIMsg(Win->UserPort))
      {
        switch (imsg->Class)
        {
          case IDCMP_NEWSIZE:
            if(!RemakeGads())
            {
              ClosePrefs=TRUE;   
            }
            break;
          case IDCMP_MOUSEMOVE:
            process_mousemoves(imsg);
            break;
          case IDCMP_GADGETUP:           
            process_gadgetups(imsg);
            break;
          case IDCMP_VANILLAKEY:
            Process_Keys(imsg);
            break;
          case IDCMP_REFRESHWINDOW:

            GT_BeginRefresh(Win);
            RefreshGUI();
            GT_EndRefresh(Win,TRUE);
            break;
          case IDCMP_MENUPICK:
            process_menus(imsg);
            break;            
        }
        GT_ReplyIMsg(imsg);
      }
      {
        struct DefaultNode *n;
        
        if(n=GetActiveNode())
        {
          switch(ActivateStrGad)
          {
            /*****************************************************************************
            case GD_NAME:
              if(CurrentList==PL_SCREENMODES)
                ActivateStrGad=0;
                break;
            ******************************************************************************/
            case GD_WIDTH:
            case GD_HEIGHT:
              if(n->ModeSelect!=MS_PROMOTE_SCREENMODE && n->ModeSelect!=MS_PROMOTE_REQUESTER)
                ActivateStrGad=0;
              break;
            case GD_PENVAL:
              if(!n->Look3D)
                ActivateStrGad=0;
              break;
            case GD_LOCKEDPENS:
              if(!(n->Flags & SHAREPENS))
                ActivateStrGad=0;
              break;
            case GD_PUBNAME:
              if(n->PubOptions==0)
                ActivateStrGad=0;
              break;
            case GD_HOTKEYSTR:
              if(!(n->Flags & SCRHOTKEY))
                ActivateStrGad=0;
              break;
          }
        }
        else
          ActivateStrGad=0;
      }
      if(ActivateStrGad)
      {
        
        ActivateGadget(LG_GetGadget(GadControl,ActivateStrGad),Win,NULL);
        ActivateStrGad=0;
      }
    }
    
    if(prefsig & signal)
      ProcessPrefsMessages();
  }
}       

struct TextFont *GUIFont=0;

BOOL RemakeGads(void)
{
  
  FreeMPPGadgets();
  if(MakeMPPGadgets(Win,VI,TAttr))
  {
    WORD x1,x2,y1,y2;
              
    x1=Win->BorderLeft;
    x2=Win->Width-Win->BorderRight-1;
    y1=Win->BorderTop;
    y2=Win->Height-Win->BorderBottom-1;
    if(x1<=x2 && y1<=y2)
      EraseRect(Win->RPort,x1,y1,x2,y2);
    
    LG_AddGadgets(Win,GadControl);
    UpdateGadgets();
    RefreshGUI();
    RefreshWindowFrame(Win);
    return(1);
  }
  return(0)
}

extern WORD WindowWidth,WindowHeight;  

BOOL ShowGUI(void)
{
  WORD zoom[4];

  if(VI=GetVisualInfo(Scr,TAG_END))
  {
    zoom[2]=160;
    zoom[3]=Scr->WBorTop + Scr->RastPort.TxHeight + 1;
    if(V39)
    {
      zoom[0]=zoom[1]=~0;
    }
    else
    {
      zoom[0]=0;
      zoom[1]=zoom[3];
    }
    
    if(MPSem->FirstPrefsOpen)
    {
      MPSem->TopEdge  =Scr->BarHeight+1;
      MPSem->LeftEdge =0;
      MPSem->FirstPrefsOpen=0;
      MPSem->WinWidth=(WORD)(WindowWidth  * XScale);
      MPSem->WinHeight=(WORD)(WindowHeight  * YScale);
    }
    else
    {
      LVActive    =MPSem->LVActive;
      CurrentList =MPSem->CurrentList;
      MPSem->WinWidth   =max(MPSem->WinWidth ,(WORD)(WindowWidth  * XScale));
      MPSem->WinHeight  =max(MPSem->WinHeight,(WORD)(WindowHeight * YScale));
    }
     if(Win=OpenWindowTags(NULL, 
                        WA_MaxWidth         ,~0,
                        WA_MaxHeight        ,~0,
                        
                        TAG_SKIP            ,(MyScreen?13:0),
                        WA_MinHeight        ,(LONG)(WindowHeight * YScale + Scr->WBorTop  + Scr->RastPort.TxHeight + 1 + Scr->WBorBottom) ,
                        WA_InnerWidth       ,MPSem->WinWidth,
                        WA_InnerHeight      ,MPSem->WinHeight,
                        WA_Left             ,MPSem->LeftEdge,
                        WA_Top              ,MPSem->TopEdge,
                        WA_DragBar          ,TRUE,
                        WA_DepthGadget      ,TRUE,
                        WA_Zoom             ,zoom,
                        WA_Title            ,WindowName ,
                        WA_SizeGadget       ,1,
                        WA_SizeBBottom      ,1,
                        TAG_SKIP            ,6,
                        
                        WA_InnerWidth       ,(LONG)(WindowWidth  * XScale),
                        WA_InnerHeight      ,(LONG)(WindowHeight  * YScale),
                        WA_Backdrop         ,MyScreen,
                        WA_Borderless       ,TRUE,
                        WA_Left             ,0,
                        WA_Top              ,Scr->BarHeight+1,
                        
                        WA_NewLookMenus     ,TRUE,
                        WA_AutoAdjust       ,TRUE,
                        WA_Activate         ,TRUE,
                        WA_SimpleRefresh    ,TRUE,
                        WA_IDCMP            ,MPP_IDCMP | IDCMP_NEWSIZE,
                        WA_PubScreen        ,Scr  ))
    {
      Win->MinWidth =(WORD)(WindowWidth  * XScale + Win->BorderLeft + Win->BorderRight);
      Win->MinHeight=(WORD)(WindowHeight * YScale + Win->BorderTop  + Win->BorderBottom);
      SetFont(Win->RPort,GUIFont);
      FindMaxPenNameSize(TAttr);
      if(MakeMPPGadgets(Win,VI,TAttr))
      {
        LG_AddGadgets(Win,GadControl);
        GT_RefreshWindow(Win,0);
        //DrawBevelBoxes(Win,VI,BBox,BevelBoxes,XScale,YScale);
        RefreshGUI();
         {
          struct NewMenu *menu;
          
          if(menu=FindNM(nm,(APTR)M_ENABLENL))
          {
            if(!V39)
              menu->nm_Flags =((menu->nm_Flags | NM_ITEMDISABLED) & ~CHECKED);
          }
        }
         if((MenuStrip=CreateMenus(nm,TAG_END))!=NULL)
        {
          if((LayoutMenus(MenuStrip,VI,
                          GTMN_NewLookMenus,TRUE,
                          TAG_END))!=NULL)
          {          
            if((SetMenuStrip(Win,MenuStrip))!=NULL)
            {
              //LVActive=0;
               GT_RefreshWindow(Win,NULL);
              RefreshMenus();
              UpdateGadgets();
              ScreenToFront(Scr);
              return(TRUE);
            }
          }
        }
      }
    }
  }
  HideGUI();
  return(FALSE);
}

struct NewMenu *FindNM(struct NewMenu *Array, APTR UserData)
{
  struct NewMenu *nm;
  
  nm=Array;
  
  while(nm->nm_UserData!=UserData && nm->nm_Type!=NM_END)
    nm++;
    
  if(nm->nm_Type==NM_END)
  {
    return(0);
  }
  return(nm);
}

void HideGUI()
{
  DKP("HideGUI()\n");
  CleanUp();
  if(Win)           
  { 
    MPSem->CurrentList=CurrentList;
    MPSem->LVActive   =LVActive;
  DKP("HideGUI() 1\n");
    ClearMenuStrip(Win);
  DKP("HideGUI() 2\n");
    MPSem->LeftEdge=Win->LeftEdge;
    MPSem->TopEdge=Win->TopEdge;
    MPSem->WinWidth=GetWinInnerWidth(Win);
    MPSem->WinHeight=GetWinInnerHeight(Win);
  DKP("HideGUI() 3\n");
    FreeMPPGadgets();
  DKP("HideGUI() 5\n");
    CloseWindow(Win);    
  DKP("HideGUI() 6\n");
    
    Win=0;
  }
    DKP("HideGUI() 7\n");       
  FreeMenus(MenuStrip);       MenuStrip=0;
    DKP("HideGUI() 8\n");
  FreeVisualInfo(VI);         VI=0;
    DKP("HideGUI() 9\n");
  
  
  DKP("HideGUI() 10\n");
  if(GUIFont) CloseFont(GUIFont);
    DKP("HideGUI() 11\n");
  
  /* These functions I KNOW are safe to call with a NULL */

}

struct TextAttr *WhichFont(struct Screen *Scr, struct TextAttr *TA, ... );

struct TextAttr *WhichFont(struct Screen *Scr, struct TextAttr *TA, ... )
{
  struct TextAttr **ta;
//  struct TaxtFont *avail;
  
  ta=&TA;
  
  while(*ta)
  {
    if(GUIFont=OpenDiskFont(*ta))
    {
      GetGUIScale(*ta,GText,&XScale,&YScale);
      if(CheckInnerWindowSize(Scr,WindowWidth,WindowHeight,XScale,YScale))
      {
        return(*ta);
      }
      CloseFont(GUIFont);
      GUIFont=0;
    }
    ta++;
  }
  return(0);
}

struct Screen *GetScreen(void)
{
  struct Screen *gs;
  WORD pens[]={~0};
  ULONG dispid;
  struct TextAttr *ta;
  
  MyScreen=FALSE;
  
  if(gs=LockPubScreen(ArgPubscreen))
  {
    SysFont=*gs->Font;
    
    if(UserFontName)
    {
      User.ta_Name  =UserFontName;
      User.ta_YSize =UserFontSize;
      User.ta_Style =0;
      User.ta_Flags =0;
      ta=&User;
    }
    else
      ta=&SysFont;

    if(!(TAttr=WhichFont(gs,ta,gs->Font,&Topaz8,0)))
    {
      TAttr=ta;
      dispid=GetVPModeID(&(gs->ViewPort));
      UnlockPubScreen(0,gs);
      gs=0;      
      GetGUIScale(TAttr,GText,&XScale,&YScale);
      if(GUIFont=OpenDiskFont(TAttr))
      {
        MyScreen=TRUE;
        gs=OpenScreenTags(0, SA_LikeWorkbench, TRUE,
                             SA_Title        , ModePro,
                             SA_DisplayID    , dispid,
                             SA_Overscan     , OSCAN_TEXT,
                             SA_AutoScroll   , TRUE,
                             SA_Font         , TAttr,
                             SA_Width        , (LONG)(WindowWidth  * XScale),
                             SA_Height       , (LONG)(WindowHeight * YScale + TAttr->ta_YSize + 2),
                             SA_Depth        , 2,
                             SA_Pens         , pens,
                             TAG_DONE);
      }
    }
  }
  if(gs)
  {
    if(DrawInfo=GetScreenDrawInfo(gs))
    {
    //  MainWinHook.h_Data=DrawInfo->dri_Pens[BACKGROUNDPEN];
    }
  }
  else
  {
    if(GUIFont)
      CloseFont(GUIFont);
  }
  return(gs);
}

void ReleaseScreen(struct Screen *S)
{
  if(S)
  {
    FreeScreenDrawInfo(S,DrawInfo);
    if(MyScreen)
      CloseScreen(S);
    else
      UnlockPubScreen(0,S);
  }
  if(GUIFont)
    CloseFont(GUIFont);
}

void CleanUp(void)
{
  if(ScrReq)
  {
    FreeAslRequest(ScrReq);
    ScrReq=0;
  }
  if(FileReq)
  {
    FreeAslRequest(FileReq);
    FileReq=0;
  }
  if(FontReq)
  {
    FreeAslRequest(FontReq);
    FontReq=0;
  }
}

void CheckMenuItem(ULONG MenuItem, BOOL Checked);

void ProcessPrefsMessages(void)
{
  ULONG listupd=FALSE;
  struct MPMessage *mpm;

loopy:

  while(mpm=(struct MPMessage *)GetMsg(PrefsPort))
  {
    //printf("Recieved %8x - Command %d Code %d Data %8x\n",mpm,mpm->Command,mpm->Code,mpm->Data);   
    switch(mpm->Command)
    {
      case MP_FORCEDEDIT:
        ForcedEditMsg=mpm;
        RemakeGads();
        mpm=0;
        break;
      case MP_QUIT:
      case MP_PREFSCLOSE:
        ClosePrefs=TRUE;
        break;
      case MP_PREFSTOFRONT:
        ScreenToFront(Scr);
        WindowToFront(Win);
        ActivateWindow(Win);
        break;
      case MP_LISTSTATUS:
        switch(mpm->Code)
        {
          case MPLS_UPDATING:
            listupd=TRUE;
            LG_SetGadgetAttrs(GadControl,GD_LIST,
                         GTLV_Labels,~0,
                         TAG_DONE);
            
            ReleaseSemaphore(&MPSem->ListSem);
            break;
          case MPLS_NORMAL:
            listupd=FALSE;          
            ObtainSemaphoreShared(&MPSem->ListSem);
            LVActive=0;
            UpdateGadgets();
            break;
        }
        break;
      case MP_REFRESH:
        RefreshMenus();
        break;
      case MP_NEWNODE:
        GD_Type(ListToCyc[mpm->Code]);  // change to the correct list
        break;
      
    }
    if(mpm)
      ReplyMsg((struct Message *)mpm);
  }
  if(listupd)
  {
    WaitPort(PrefsPort);
    goto loopy;
  }
}

void RefreshMenus(void)
{
  CheckMenuItem(M_ENABLED     ,MPSem->Enabled);
  CheckMenuItem(M_ENABLENL    ,MPSem->EnabledNLM);  
  CheckMenuItem(M_SET_UNKNOWN ,MPSem->CatchScreens);
  CheckMenuItem(M_SET_CENTER_H,MPSem->CenterAll & 1);
  CheckMenuItem(M_SET_CENTER_V,MPSem->CenterAll & 2);
  ResetMenuStrip(Win,MenuStrip);
}

void CheckMenuItem(ULONG MenuItem, BOOL Checked)
{
  struct MenuItem *mi;
  
  if(mi=ItemAddress(MenuStrip,MenuItem))
  {
    if(Checked)
      mi->Flags|=CHECKED;
    else
      mi->Flags&=(~CHECKED);
  }
}
    
void process_gadgetups(struct IntuiMessage *imsg)
{
  struct Gadget *gad;
  struct DefaultNode *n;
  UWORD  code,id;  
  
  code=imsg->Code;
  gad=(struct Gadget*)imsg->IAddress;
  id=gad->GadgetID;  
   
  switch(id)
  {

    case GD_NEW:
      GD_New();
      break;

    case GD_SAVE:
      GD_Save();
      break;
    case GD_USE:
      GD_Use();
      break;
    case GD_CANCEL:
      GD_Cancel();
      break;
      
    case GD_TYPE:
      GD_Type(code);
      break;
  }

  if(n=GetActiveNode())  
  switch(id)
  {
    case GD_LIST:
      GD_List(code,0);
      break;
      
    case GD_SELECT_NAME:
      GD_SelectName(n);
      break;

    case GD_NAME:
      LG_SetGadgetAttrs(GadControl,GD_LIST,
                         GTLV_Labels,~0,TAG_DONE);
      if(GetGadString(LG_GetGadget(GadControl,GD_NAME)))
      {
        STRPTR oldname;
        ObtainSemaphore(&MPSem->NodeSem);
        oldname=n->Def_Node.ln_Name;
        if(n->Def_Node.ln_Name=AllocVec( 1+strlen(GetGadString(LG_GetGadget(GadControl,GD_NAME))),MEMF_CLEAR|MEMF_PUBLIC))
        {
/***************************************************************************************************************************/
          n->OrigDisplayID=INVALID_ID;
/***************************************************************************************************************************/
          strcpy(n->Def_Node.ln_Name,GetGadString(LG_GetGadget(GadControl,GD_NAME)));
          FreeVec(oldname);
        }
        else
        {
          //Remove((struct Node *)n);
          //FreeDNode(n);
          n->Def_Node.ln_Name=oldname;
      //    UpdateGadgets();
        }
        ReleaseSemaphore(&MPSem->NodeSem);
      }
     
      LG_SetGadgetAttrs(GadControl,GD_LIST,
                         GTLV_Labels,&MPSem->PromotionList[CurrentList],
                         TAG_DONE);
                         
      if(imsg->Qualifier&3)
      {//shifted
        switch(code)
        {
          case CURSORUP:
            GD_Move((NodeCnt-LVActive-1)+1);
            LG_SetGadgetAttrs(GadControl,GD_MOVE,
                      GTSL_Level,       (NodeCnt-1)-LVActive,
                      TAG_DONE);
            ActivateStrGad=GD_NAME;   
            break;
          case CURSORDOWN:
            GD_Move((NodeCnt-LVActive-1)-1);
            LG_SetGadgetAttrs(GadControl,GD_MOVE,
                      GTSL_Level,       (NodeCnt-1)-LVActive,
                      TAG_DONE);
            ActivateStrGad=GD_NAME;
            break;
        }
      }
      else
      {
        switch(code)
        {
          case CURSORUP:
            LVActive-=2;
          case CURSORDOWN:
            LVActive++;
            GD_List(LVActive,0);
            LG_SetGadgetAttrs(GadControl,GD_LIST,
                              GTLV_Selected       ,LVActive,
                              TAG_DONE);
            break;
        }        
      }
      break;
      
    case GD_MODESEL:
      GD_ModeSel(n,code,0);
      break;

    case GD_SELMODE:
      GD_SelMode(n);
      break;

    case GD_WIDTH:
      n->Width=GetGadNumber(gad);
      break;

    case GD_HEIGHT:
      n->Height=GetGadNumber(gad);
      break;

    case GD_OVERSCAN:
      GD_Overscan(n,code,FALSE);
      break;

    case GD_REMOVE:
      GD_Remove(n);
      break;

    case GD_LOOK3D:
      GD_Look3D(n,gad->Flags & GFLG_SELECTED);
      break;

    case GD_AUTOSCROLL:
      GD_AutoScroll(n,gad->Flags & GFLG_SELECTED,FALSE);
      break;

    case GD_3D_DEFAULT:
      GD_3D_Default(n,gad->Flags & GFLG_SELECTED,FALSE);
      break;

    case GD_PENLIST:
      GD_PenList(n,code);
      break;

    case GD_PENVAL:
      n->Pens[ActivePen]=GetGadNumber(LG_GetGadget(GadControl,GD_PENVAL));
      switch(code)
      {
        
        case CURSORUP:
          ActivateStrGad=GD_PENVAL;
          ActivePen--;
          if(ActivePen<0)
            ActivePen=NumDriPens-1;
          break;
        case CURSORDOWN:
          ActivateStrGad=GD_PENVAL;
          ActivePen++;
          if(ActivePen>=NumDriPens)
            ActivePen=0;
          break;
      }
      //      if(imsg->Qualifier&3)
      SetPenValues(n->Pens);
      break;

    case GD_RESETPENS:
      GD_ResetPens(n);
      break;

    case GD_PICKFONT:
      GD_PickFont(n);
      break;

    case GD_INTERLEAVE:
      GD_Interleave(n,gad->Flags & GFLG_SELECTED,FALSE);
      break;

    case GD_BEHIND:
      GD_Behind(n,gad->Flags & GFLG_SELECTED,FALSE);
      break;
    
    case GD_BLANK_BORDER:
      GD_Blank_Border(n,gad->Flags & GFLG_SELECTED,FALSE);
      break;
      
    case GD_CENTER:
      n->CenterFlags=code;
      break;

    case GD_FASPECT:
      GD_FAspect(n,gad->Flags & GFLG_SELECTED,FALSE);
      break;

    case GD_SFONT:
      GD_SFont(n,code);
      break;

    case GD_PUBOPT:
      GD_PubOpt(n,gad->Flags & GFLG_SELECTED,FALSE);
      break;
      
    case GD_PUBNAME:
      if(GetGadString(LG_GetGadget(GadControl,GD_PUBNAME)))
      {
        ObtainSemaphore(&MPSem->NodeSem);
        FreeVec(n->PubName);
        if(n->PubName=AllocVec( 1+strlen(GetGadString(LG_GetGadget(GadControl,GD_PUBNAME))),MEMF_CLEAR|MEMF_PUBLIC))
          strcpy(n->PubName,GetGadString(LG_GetGadget(GadControl,GD_PUBNAME)));
        ReleaseSemaphore(&MPSem->NodeSem);
      }      
      break;
      
    case GD_DODEPTH:
      GD_DoDepth(n,gad->Flags & GFLG_SELECTED);
      break;
      
    case GD_SHAREPENS:
      GD_SharePens(n,gad->Flags & GFLG_SELECTED,FALSE);
      break;
      
    case GD_LOCKEDPENS:
      if(GetGadString(LG_GetGadget(GadControl,GD_LOCKEDPENS)))
      {
        ObtainSemaphore(&MPSem->NodeSem);
        FreeVec(n->LockedPens);
        if(n->LockedPens=AllocVec( 1+strlen(GetGadString(LG_GetGadget(GadControl,GD_LOCKEDPENS))),MEMF_CLEAR|MEMF_PUBLIC))
          strcpy(n->LockedPens,GetGadString(LG_GetGadget(GadControl,GD_LOCKEDPENS)));
        ReleaseSemaphore(&MPSem->NodeSem);
      }      
      break;
    
    case GD_HOTKEYOPT:
      GD_HotKeyOpt(n,gad->Flags & GFLG_SELECTED,FALSE);
      break;
      
    case GD_HOTKEYSTR:
      if(GetGadString(LG_GetGadget(GadControl,GD_HOTKEYSTR)))
      {
        ObtainSemaphore(&MPSem->NodeSem);
        FreeVec(n->HotKey);
        if(n->HotKey=AllocVec( 1+strlen(GetGadString(LG_GetGadget(GadControl,GD_HOTKEYSTR))),MEMF_CLEAR|MEMF_PUBLIC))
          strcpy(n->HotKey,GetGadString(LG_GetGadget(GadControl,GD_HOTKEYSTR)));
        ReleaseSemaphore(&MPSem->NodeSem);
      }
      break;
    case GD_PALETTE:
      GD_Palette(n,gad->Flags & GFLG_SELECTED);
      break;
      
    case GD_EDITPALETTE:
      GD_EditPalette(n);
      break;
      
    case GD_FORCE_PLANAR:
      GD_Force_Planar(n,gad->Flags & GFLG_SELECTED,FALSE);
      break;
  } /* End Switch */  
}

void Process_Keys(struct IntuiMessage *IMsg)
{
  ULONG code,gadid;
  WORD dirchange=1;
  WORD letter;
  struct DefaultNode *n;
  
  letter=IMsg->Code;

  if(LG_GadForKey(GadControl,letter,&gadid,&code))  
  {
    if(code&1) dirchange=-1;
    switch(gadid)
    {
      case GD_LIST:
        gadid=GD_NAME;
      case GD_NAME:
      case GD_WIDTH:
      case GD_HEIGHT:
      case GD_LOCKEDPENS:
      case GD_PUBNAME:
      case GD_HOTKEYSTR:
      case GD_PENVAL:
        ActivateStrGad=gadid;
        break;
      case GD_TYPE:
        CurrentList_2+=dirchange;
        GD_Type(CurrentList_2);
        break;
      case GD_NEW:
        GD_New();
        break;
      case GD_SAVE:
        GD_Save();
        break;
      case GD_USE:
        GD_Use();
        break;
      case GD_CANCEL:
        GD_Cancel();
        break;
    }
    if(n=GetActiveNode())
    switch(gadid)
    {
      case GD_SELECT_NAME:
        GD_SelectName(n);
        break;
      case GD_MODESEL:
        GD_ModeSel(n,n->ModeSelect+dirchange,1);
        break;
      case GD_SELMODE:
        GD_SelMode(n);
        break;
      case GD_OVERSCAN: 
        GD_Overscan(n,n->OverscanType+dirchange-1,TRUE);
        break;
      case GD_REMOVE:
        GD_Remove(n);
        break;
      case GD_PENLIST:
        GD_PenList(n,ActivePen+dirchange);
        break;
      case GD_RESETPENS:
        GD_ResetPens(n);
        break;
      case GD_PICKFONT:
        GD_PickFont(n);
        break;
      case GD_INTERLEAVE:
        GD_Interleave(n,!(n->Flags & INTERLEAVE),TRUE);
        break;
      case GD_BEHIND:
        GD_Behind(n,!(n->Flags & DNF_BEHIND),TRUE);
        break;
      case GD_BLANK_BORDER:
        GD_Blank_Border(n,!(n->Flags & DNF_BLANK_BORDER),TRUE);
        break;
      case GD_LOOK3D:
        GD_Look3D(n,!(n->Look3D));
        break;
      case GD_AUTOSCROLL:
        GD_AutoScroll(n,!(n->AutoScroll),TRUE);
        break;
      case GD_3D_DEFAULT:
        GD_3D_Default(n,!(n->Flags & DNF_3D_DEFAULT),TRUE);
        break;
      case GD_CENTER:
        GD_Center(n,n->CenterFlags+dirchange,TRUE);
        break;
      case GD_FASPECT:
        GD_FAspect(n,!(n->Flags & FIXASPECT),TRUE);
        break;
      case GD_SFONT:
        GD_SFont(n,n->FontType+dirchange);
        break;
      case GD_PUBOPT:
        GD_PubOpt(n,!(n->PubOptions),TRUE);
        break;
      case GD_DODEPTH:
        GD_DoDepth(n,!(n->Flags & DEPTH));
        break;
      case GD_SHAREPENS:
        GD_SharePens(n,!(n->Flags & SHAREPENS),TRUE);
        break;
      case GD_HOTKEYOPT:
        GD_HotKeyOpt(n,!(n->Flags & SCRHOTKEY),TRUE);
        break;
      case GD_PALETTE:
        GD_Palette(n,!(n->Flags & DNF_PALETTE));
        break;
      case GD_EDITPALETTE:
        GD_EditPalette(n);
        break;
      case GD_MOVE:
        GD_Move(LVActive+dirchange);
        break;
      case GD_DEPTH:
        GD_Depth(n,n->Depth-dirchange,TRUE);
        break;
      case GD_FORCE_PLANAR:
        GD_Force_Planar(n,!(n->Flags & DNF_FORCEPLANAR),TRUE);
        break;
    }
  }
}


void process_mousemoves(struct IntuiMessage *imsg)
{
  struct Gadget *gad;
  struct DefaultNode *n;
  UWORD  code,id;  
  
  code=imsg->Code;
  gad=(struct Gadget*)imsg->IAddress;
  id=gad->GadgetID;
  if(n=GetActiveNode())
  {
    switch(id)
    {
      case GD_MOVE:
        GD_Move(code);
        break;
      case GD_DEPTH:
        GD_Depth(n,code,FALSE);
        break;
    } /* End Switch */
  }  
}


void process_menus(struct IntuiMessage *imsg)
{
  UWORD  menunumber,ns;
  ULONG  menuid;
  struct MenuItem *mi;
  
  menunumber=imsg->Code;
  mi=ItemAddress(MenuStrip,menunumber);
  if(mi)
  do
  {
    menuid=(ULONG)(GTMENUITEM_USERDATA(mi));
    switch(menuid)
    {
      case M_OPEN:
        if(SelectFile(MiscText[LOAD_MP_PREFS],FALSE) )
        {
           ObtainSemaphore(&MPSem->NodeSem);
           LG_SetGadgetAttrs(GadControl,GD_LIST,
                         GTLV_Labels,~0,TAG_DONE);
           FreeAllDefLists(MPSem->PromotionList);
           ReleaseSemaphore(&MPSem->NodeSem);
           PrefLoadFile(filename);

           LVActive=0;
           UpdateGadgets();
        }
        break;
        /*
      case M_SAVE:
        ObtainSemaphore(&MPSem->NodeSem);
        PrefSaveFile(EnvArcFile);
        PrefSaveFile(EnvFile);
        ReleaseSemaphore(&MPSem->NodeSem);
        break;
        */
      case M_SAVEAS:
        if(SelectFile(MiscText[SAVE_MP_PREFS],TRUE) )
        {
          PrefSaveFile(filename);     
        }
        break;
      case M_ENABLED:
        MPSem->Enabled=(mi->Flags & CHECKED ? 1:0);
        //ActivateCxObj(Broker,MPSem->Enabled);
        break;
      case M_ABOUT:
        {
          EZReq(Win,0,ModePro,AboutText,MiscText[OK],(ULONG)GetString(MSG_ABOUT_TRANSLATOR),
                                                    (ULONG)GetString(MSG_ABOUT_FORINFO));
        }
        break;
      case M_HIDE:
        ClosePrefs=TRUE;
        //PrefSaveFile(EnvFile);
        break;
      case M_LASTSAVED:
        ObtainSemaphore(&MPSem->NodeSem);
        LG_SetGadgetAttrs(GadControl,GD_LIST,
                                 GTLV_Labels,~0,TAG_DONE);
        FreeAllDefLists(MPSem->PromotionList);
        ReleaseSemaphore(&MPSem->NodeSem);
        PrefLoadFile(EnvArcFile);
        LVActive=0;
        UpdateGadgets();
        break;   
      case M_RESTORE:
        ObtainSemaphore(&MPSem->NodeSem);
        LG_SetGadgetAttrs(GadControl,GD_LIST,
                                 GTLV_Labels,~0,TAG_DONE);
        FreeAllDefLists(MPSem->PromotionList);
        ReleaseSemaphore(&MPSem->NodeSem);
        PrefLoadFile(EnvFile);
        LVActive=0;
        UpdateGadgets();
        break;   
      case M_QUIT:
        SendDaemonMsg(MP_QUIT,0,0);
        break;
      case M_ENABLENL:
        MPSem->EnabledNLM=(mi->Flags & CHECKED ? 1:0);
        break;
      case M_SET_UNKNOWN:
        MPSem->CatchScreens=(mi->Flags & CHECKED ? 1:0);
        break;
      case M_SET_CENTER_H:
        MPSem->CenterAll=(MPSem->CenterAll & ~1) | (mi->Flags & CHECKED ? 1:0);
        break;
      case M_SET_CENTER_V:
        MPSem->CenterAll=(MPSem->CenterAll & ~2) | (mi->Flags & CHECKED ? 2:0);
        break;
      case M_COPY_TO_SCR:
      case M_COPY_TO_PRG:
      case M_COPY_TO_PUB:
        if(CurrentList != PL_SCREENMODES)
        {
          struct DefaultNode *dnode; 

          if(dnode=DupDNode(GetActiveNode()))  
          {
            switch(menuid)
            {
              case M_COPY_TO_SCR:
                dnode->Type=PL_SCREENNAMES;
                break;
              case M_COPY_TO_PRG:
                dnode->Type=PL_PROGRAMNAMES;
                break;
              case M_COPY_TO_PUB:
                dnode->Type=PL_PUBLICSCREENS;
                break;
            }
            ObtainSemaphore(&MPSem->NodeSem);
            LG_SetGadgetAttrs(GadControl,GD_LIST,
                              GTLV_Labels      ,~0,
                              GTLV_Selected    ,0,
                              TAG_DONE);
            AddHead(&MPSem->PromotionList[dnode->Type],(struct Node *)dnode);
            ReleaseSemaphore(&MPSem->NodeSem);
            GD_Type(dnode->Type);
          }
        }
        break;
    }
    ns=mi->NextSelect;
    mi=ItemAddress(MenuStrip,mi->NextSelect);
  }while(ns!= MENUNULL && mi);
}

void SetupPenNodes(void)
{
  ULONG pen;
  
  NewList(&PenList);
  for(pen=0;pen<NumDriPens;pen++)
  {
//    printf("%d\n",pen);
    pennode[pen].PenNumber       =PenNumbers[pen];
    pennode[pen].Pen_Node.ln_Name=PenNames[pen];
    pennode[pen].Pen_Node.ln_Succ=pennode[pen].Pen_Node.ln_Pred=0;
    AddTail(&PenList,(struct Node *)&pennode[pen]);
  }  
}

void SetPenValues(WORD *pens)
{
  ULONG pen,maxlenpng;


  LG_SetGadgetAttrs(GadControl,GD_PENLIST,
                    GTLV_Labels,~0,TAG_DONE);  
  if(pens)
  {
    for(pen=0;pen<NumDriPens;pen++)
    {
      stci_d(&PenNames[pen][PenNameLength[pen]],pens[pen]);
    }
    
    LG_SetGadgetAttrs(GadControl,GD_PENVAL,
                         GA_Disabled  ,FALSE,
                         GTIN_Number  ,pens[ActivePen],
                         TAG_DONE);
    LG_SetGadgetAttrs(GadControl,GD_RESETPENS,
                         GA_Disabled  ,FALSE,
                         TAG_DONE);
  }
  else
  {
    for(pen=0;pen<NumDriPens;pen++)
    {
      PenNames[pen][PenNameLength[pen]]=0;
    }
    LG_SetGadgetAttrs(GadControl,GD_PENVAL,
                         GA_Disabled  ,TRUE,
                         TAG_DONE);
    LG_SetGadgetAttrs(GadControl,GD_RESETPENS,
                         GA_Disabled  ,TRUE,
                         TAG_DONE);

  }
  LG_SetGadgetAttrs(GadControl,GD_PENLIST,
                         GTLV_Labels      ,&PenList,
                         GTLV_MakeVisible ,ActivePen,
                         GTLV_Selected    ,ActivePen,
                         GA_Disabled      ,!pens,
                         TAG_DONE);
  //LG_SetGadgetAttrs(GadControl,GD_PENNAME,
  //                       GTTX_Text,NULL,TAG_DONE);
  
  
  maxlenpng=min(31,PenNameLength[ActivePen]);
  strncpy(PenNameGad,PenNames[ActivePen],maxlenpng);
  PenNameGad[maxlenpng]=0;
  //LG_SetGadgetAttrs(GadControl,GD_PENNAME,
  //                       GTTX_Text,PenNameGad,TAG_DONE);
  WritePenNameDisp(PenNameGad);
}    

LONG SendDaemonMsg(ULONG Command, ULONG Code, APTR Data)
{
  LONG rv=0;
  struct MPMessage *mpm;

  if(mpm=AllocVec(sizeof(struct MPMessage),MEMF_PUBLIC|MEMF_CLEAR))
  {
    mpm->Command=Command;
    mpm->Code=Code;
    mpm->Data=Data;
    mpm->mp_Message.mn_ReplyPort=ReplyPort;

    //printf("Sending  %8x - Command %d Code %d Data %8x\n",mpm,mpm->Command,mpm->Code,mpm->Data);   
    PutMsg(MPSem->DaemonPort,(struct Message *)mpm);
    rv=1;
  }

  return(rv);
}

BOOL PrefLoadFile(STRPTR FileName)
{
  LONG error;
  BOOL rv;
  
  ObtainSemaphore(&MPSem->NodeSem);
  rv=LoadFile(MPSem->PromotionList,FileName);
  FixScreenModeNames();
  ReleaseSemaphore(&MPSem->NodeSem);
  if(error=IoErr())
  {
    UBYTE errstr[91];

    Fault(error,MiscText[LOAD_ERROR],errstr,90);
    EZReq(Win,0,ModePro,errstr,MiscText[OK],0);
  }
  RefreshMenus();
  return(rv);
}    


BOOL PrefSaveFile(STRPTR FileName)
{
  LONG error;
  BOOL rv;
  
  ObtainSemaphore(&MPSem->NodeSem);
  rv=SaveFile(MPSem->PromotionList,FileName);
  ReleaseSemaphore(&MPSem->NodeSem);

  if(error=IoErr())
  {
    UBYTE errstr[91];

    Fault(error,MiscText[SAVE_ERROR],errstr,90);
    EZReq(Win,0,ModePro,errstr,MiscText[OK],0);
  }
  return(rv);
}    

void FixScreenModeNames(void)
{
  struct DefaultNode *dn;
  STRPTR newname;

  ObtainSemaphore(&MPSem->NodeSem);
  dn=(struct DefaultNode *)MPSem->PromotionList[PL_SCREENMODES].lh_Head;
  while(dn->Def_Node.ln_Succ)
  {
//    printf("%8lx\n",dn->OrigDisplayID);
    if(newname=GetModeName(dn->OrigDisplayID))
    {
      FreeVec(dn->Def_Node.ln_Name);
      dn->Def_Node.ln_Name=newname;
    }
    dn=(struct DefaultNode *)dn->Def_Node.ln_Succ;
  }
  ReleaseSemaphore(&MPSem->NodeSem);
}
