#include "MP.h"

/*
    mprefs will hold a shared lock on ListSem,
    mpatch will obatin a shared lock
    
    RemDNode & AddDNode must get a normal lock
*/

extern struct MPSem MPSem;

void RemDNode(struct DefaultNode *DN)
{
  if(DN)
  {
    Forbid();
    SendPrefsMsg(MP_LISTSTATUS, MPLS_UPDATING, 0);
    ObtainSemaphore(&MPSem.ListSem); // maybe shared with prefs
    ObtainSemaphore(&MPSem.NodeSem);
    Remove((struct Node *)DN);
    ReleaseSemaphore(&MPSem.NodeSem);
    ReleaseSemaphore(&MPSem.ListSem);
    Permit();

    SendPrefsMsg(MP_LISTSTATUS, MPLS_NORMAL, 0);
    SendPrefsMsg(MP_REMNODE,0,DN);
    FreeDNode(DN);
  }
}
    
void AddDNode(ULONG dest, struct DefaultNode *n)
{
  if(dest < 2 && n)
  {
    Forbid();
    SendPrefsMsg(MP_LISTSTATUS, MPLS_UPDATING, 0);
    ObtainSemaphore(&MPSem.ListSem); // maybe shared with prefs
    ObtainSemaphore(&MPSem.NodeSem);
    AddHead(&MPSem.PromotionList[dest],(struct Node *)n);
    n->Depth=max(1,n->Depth);
    ReleaseSemaphore(&MPSem.NodeSem);
    ReleaseSemaphore(&MPSem.ListSem);
    Permit();

    SendPrefsMsg(MP_LISTSTATUS, MPLS_NORMAL, 0);
    SendPrefsMsg(MP_NEWNODE,dest,n);
  }
  else
    FreeDNode(n);
}

struct DefaultNode *FindDNode(struct List *list,UBYTE *name)
{
  struct DefaultNode *dn;
  UWORD l;
  UBYTE str[128],patsrc[128];
  UBYTE pat[258];


  
  if(IsListEmpty(list))
  {
    return(NULL);
  }
  for(l=0;l<127 && name[l];l++)
    str[l]=ToUpper(name[l]);
  str[l]=0;

  dn=(struct DefaultNode *)list->lh_Head;
  while(dn && dn->Def_Node.ln_Succ!=0)
  {
    for(l=0;l<127 && dn->Def_Node.ln_Name[l];l++)
      patsrc[l]=ToUpper(dn->Def_Node.ln_Name[l]);
    patsrc[l]=0;
      
    ParsePatternNoCase(patsrc,pat,258);
    
    if(MatchPatternNoCase(pat,name))
      return(dn);
    dn=(struct DefaultNode *)dn->Def_Node.ln_Succ;
  }
  return(NULL);
}
