#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include <exec/types.h>
#include <exec/memory.h>

#include <libraries/dos.h>
#include <libraries/dosextens.h>

#include <dlg/misc.h>

#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/dlg.h>

#include <pragmas/dlg.h>

LONG __saveds __asm LIBStricmp(register __a0 char *,  register __a1 char *);
LONG __saveds __asm LIBStrnicmp(register __a0 char *, register __a1 char *, register __d0 USHORT);


BOOL __saveds __asm LIBDLGPatternMatch(register __a0 char *pat,
                                       register __a1 char *str)

{char *p, *s, *sav=NULL, star=FALSE, saved=FALSE;

 p = pat;
 s = str;

 while(*p && *s)
      {if (*p=='*')
          {saved = FALSE;
           star  = TRUE;
           p++;
           if (!*p)  break;
          }

       if ((*p!='?') && (toupper(*p)!=toupper(*s)))
          {if (saved)
              {saved = FALSE;
               p     = sav;
              }
            else
              if (star)
                  s++;
                else
                  return(FALSE);
          }
        else
          {if (star & !saved)
              {sav   = p;
               saved = TRUE;
              }

           p++;
           s++;
          }
      }

 if (!*p && !*s)
      return(TRUE);

 if (*p)
     if ((*p=='*') && (!*(p+1)))
          return(TRUE);
        else
          return(FALSE);

 if (star && !saved)
     return(TRUE);
 return(FALSE);
}


char * __saveds __asm LIBSearchNext(register __a0 struct SearchCookie *sc)

{if (!sc)             return(NULL);
 if (sc->searchdone)  return(NULL);

 for(;;)
    {if (sc->searchfib->fib_EntryType < 0  ||  sc->searchfib->fib_EntryType == ST_SOFTLINK)
         if (LIBDLGPatternMatch(sc->searchpat, sc->searchfib->fib_FileName))
            {strcpy(sc->currentsearchfile, sc->searchfib->fib_FileName);
             break;
            }

     if (!ExNext(sc->searchlock, sc->searchfib))
        {sc->searchdone = TRUE;
         return(NULL);
        }
    }

 if (!ExNext(sc->searchlock, sc->searchfib))  sc->searchdone = TRUE;
 return(sc->currentsearchfile);
}


struct SearchCookie * __saveds __asm LIBSearchStart(register __a0 char *dir,
                                                    register __a1 char *pat)

{struct SearchCookie *sc;
 struct Process      *proc;
 long                 len;

 sc = AllocMem(sizeof(struct SearchCookie), MEMF_PUBLIC);
 if (!sc)  return(NULL);

 if (dir)
    {if (!(sc->searchlock = Lock(dir,ACCESS_READ)))
        {FreeMem(sc, sizeof(struct SearchCookie));
         return(NULL);
        }
    }
  else
    {proc = (struct Process *)FindTask(NULL);
     if (!(sc->searchlock = DupLock(proc->pr_CurrentDir)))
        {FreeMem(sc, sizeof(struct SearchCookie));
         return(NULL);
        }
    }

 len           = strlen(pat) + 1;
 sc->searchfib = AllocMem(sizeof(struct FileInfoBlock)+len, MEMF_PUBLIC);
 if (!sc->searchfib)
    {UnLock(sc->searchlock);
     FreeMem(sc, sizeof(struct SearchCookie));
     return(NULL);
    }

 sc->searchpat = (char *)((char *)sc->searchfib + sizeof(struct FileInfoBlock));
 strcpy(sc->searchpat, pat);

 sc->searchdone = FALSE;
 if (!Examine(sc->searchlock, sc->searchfib))
      sc->searchdone = TRUE;
    else
      if (!ExNext(sc->searchlock, sc->searchfib))
           sc->searchdone = TRUE;

 return(sc);
}


void __saveds __asm LIBSearchEnd(register __a0 struct SearchCookie *sc)

{if (sc)
    {UnLock(sc->searchlock);
     FreeMem(sc->searchfib, sizeof(struct FileInfoBlock)+strlen(sc->searchpat)+1);
     FreeMem(sc, sizeof(struct SearchCookie));
    }
}


char * __saveds __asm LIBDLGSearch(register __a0 char  *array,
                                   register __a1 char  *structptr,
                                   register __d0 USHORT structsize,
                                   register __d1 USHORT fieldsize,
                                   register __d2 USHORT elements)

{USHORT ele;

 for(ele = 0; ele<elements; ele++)
     if (!LIBStrnicmp(array+(ele*structsize),structptr,fieldsize))
          return(array+(ele*structsize));

 return(NULL);
}


char * __saveds __asm LIBDLGBinSearch(register __a0 char  *array,
                                      register __a1 char  *structptr,
                                      register __d0 USHORT structsize,
                                      register __d1 USHORT fieldsize,
                                      register __d2 USHORT elements)

{USHORT index, high, low, tot;
 long   cmpres;
 char  *buf;

 low  = 0;
 tot  = elements-1;
 high = tot;

 while(low < high)
      {index = (low + high)/2;

       buf    = (char *)((long)array+((long)structsize * (long)index));
       cmpres =  LIBStrnicmp(structptr,buf,fieldsize);
       if (cmpres<0)
           high = index;
         else
           if (cmpres>0)
               low=index+1;
             else
               high=low=index;
      }

 index  = (low + high)/2;
 buf    = (char *)((LONG)array+((LONG)structsize * (LONG)index));
 cmpres =  LIBStrnicmp(structptr,buf,fieldsize);

 if (!cmpres) return(buf);
 return(NULL);
}
