#define DEBUG
#define ADD_DEBUG_CODE
#include <debug.h>

#include "MP.h"
#include <extras/macros/exec.h>

struct SignalSemaphore LockPubSem;

extern struct Process  *MPTask;
extern BYTE   PublicSignal;
extern struct MPSem *MPSem;
extern UBYTE   ModePro[];

extern struct Screen * __asm (*OldLockPubScreen)(register __a0 UBYTE *Name,
                                                 register __a6 struct Library *);
extern void __asm (*OldUnlockPubScreen)(register __a0 UBYTE *Name,
                                        register __a1 struct Screen *,
                                        register __a6 struct Library *);


struct Screen * __saveds __asm NewLockPubScreen(register __a0 UBYTE *Name,
                                                register __a6 struct IntuitionBase *IBase)
{
  struct OpenNode *on;
  struct Screen *scr, *ps;
  struct DefaultNode *dnode;
  LONG button;
  char tnamebuffer[52];
  char *tname;
  static ULONG stackid=0xc0de0020;
  
  tname=SetupTaskName(tnamebuffer,", LPS",50);

DEBUG_CODE(DKP("LockPubScreen(%s)\n",Name););

  ps=0;

  if(scr=OldLockPubScreen(Name,(struct Library *)IntuitionBase))
  {
DEBUG_CODE(DKP("  RV=0x%08lx\n",ps););

    SetTaskName(tname);
    
    return(scr);
  }
  else
  {
    if(strcmp("Workench",Name)) // Can't f with Workbench! //4.53 @1 rewired 
    {
      ObtainSemaphore(&LockPubSem);               //4.53 @11      // 4.54 @1 (comment out)
      if(scr=OldLockPubScreen(Name,(struct Library *)IntuitionBase))
      {
DEBUG_CODE
        (
          DKP("  Second lock attempt succeeded!\n");
          DKP("  RV=0x%08lx\n",ps);
        );
  
        SetTaskName(tname);
  
        ReleaseSemaphore(&LockPubSem);      //4.53 @11    
        
        return(scr);
      }
      else    
      {
        ObtainSemaphoreShared(&MPSem->ListSem);   //4.53 @11 (comment out) // 4.54 @1 (UNcomment out)
        ObtainSemaphore(&MPSem->NodeSem);         //4.53 @11 (comment out) // 4.54 @1 (UNcomment out)
        
        if(dnode=FindDNode(&MPSem->PromotionList[PL_PUBLICSCREENS],Name))
        {
          if(dnode->Flags & DNF_NEVER_PROMOTE)
            dnode=0;
          else
            dnode=DupDNode(dnode);
  
          ReleaseSemaphore(&MPSem->NodeSem);    
        }
        else
        {
          ReleaseSemaphore(&MPSem->NodeSem);    
          if(MPSem->CatchPubScreens)
          {
            if(button=EZReq(0,0,ModePro,GetString(MSG_NEW_PUBSCREEN),GetString(MSG_NEW_PUBSCREEN_BUTTONS),(ULONG)Name))
            {
              if(dnode=AllocDefaultNode(Name))
              {
                dnode->Type=PL_PUBLICSCREENS;
                dnode->ModeSelect=2;
                CloneWB(dnode);
                dnode=ForceEdit(dnode);
              }   
            }
          }
        }
        
        
        ReleaseSemaphore(&MPSem->ListSem);
        
        ps=0;
        
        if(dnode)
        {

DEBUG_CODE(DKP("  Creating new pubscreen %s\n",Name););
          
          FreeVec(dnode->PubName);
          dnode->PubName=Name;
          dnode->PubOptions=1;
      
          if(scr=OpenScreenTags(0, SA_Title                 ,Name,
                                   SA_ModeProNode           ,dnode,
                                   TAG_DONE))
          {
            if(ps=OldLockPubScreen(Name,(struct Library *)IntuitionBase))
            {
              //4.53 @8 now clears ON_OPEN flag
              ObtainSemaphore(&MPSem->OpenListSem);
              if(on=FindOpenNode(ps))
              {
                // clear the open flag so MP can close the screen
                on->Flags&=(~ON_OPEN);
              }
              ReleaseSemaphore(&MPSem->OpenListSem);
            }
          }
          
          dnode->PubName=0;
          dnode->PubOptions=0;
          
          FreeDNode(dnode);
        }      
        ReleaseSemaphore(&LockPubSem);
      } // end if(!"workbench")
    }
  }

DEBUG_CODE(DKP("  RV=0x%08lx\n",ps););

  SetTaskName(tname);
  
  return(ps);
}                          



// 4.53 @9 New patch
void __saveds __asm NewUnlockPubScreen(register __a0 UBYTE *Name, 
                                       register __a1 struct Screen *Scr,
                                       register __a6 struct Library *IBase)
{
  //BOOL signal=0;
  //struct List *plist;
  //struct PubScreenNode *psn;
  //struct OpenNode *on;
  char tnamebuffer[52];
  char *tname;
  static ULONG stack2=0xc0de0021;
  
  tname=SetupTaskName(tnamebuffer,", ULPS",50);

DEBUG_CODE(DKP("UnLockPubScreen(%s,0x%08lx)\n",Name,Scr););

  OldUnlockPubScreen(Name,Scr,IBase);

  // signal MP, birdie kludge
  Signal((struct Task *)MPTask,1<<PublicSignal);
  
  SetTaskName(tname);
}
