/* Make a list of all autodocs in short format */

#include <exec/memory.h>

#include "global.h"
#include "misc.h"
#include "adfile.h"
#include "shortad.h"

/***********************************************/

struct ShortAutodocEntry *ShortAutodocArray;

/***********************************************/

static int InternalSearchShortAutodoc(char *Name)

{
   int Index;

   for (Index=1; Index<=(int)ShortAutodocArray[Index].Name; Index++)
      {
         if (!strcmp(ShortAutodocArray[Index].Name,Name))
            {
               return(Index);
            }
      }
   return(0);
}

/***********************************************/

static int GetResidentIndex(struct AutodocNode *AutodocNode)

{
   static struct
      {
         char *Name;
         int Length;
      } ResidentTypes[]=
      {
         "library",7,   /* 0 */
         "device",6,    /* 1 */
         "datatype",8,  /* 2 */
         "lib",3,       /* 3 */
         "resource",8   /* 4 */
      };

   int Index;
   char *ResidentTypeEnd;
   int Length;

   if (AutodocNode)
      {
         ResidentTypeEnd=FindSlash(AutodocNode->Node.Name);
         Length=ResidentTypeEnd-AutodocNode->Node.Name;
         for (Index=0; Index<5; Index++)
            {
               if (ResidentTypes[Index].Length<=Length)
                  {
                     if (!__builtin_memcmp(ResidentTypeEnd-ResidentTypes[Index].Length,ResidentTypes[Index].Name,ResidentTypes[Index].Length))
                        {
                           return(Index);
                        }
                  }
            }
      }
   return(5);
}

/***********************************************/

BOOL MakeShortAutodocs(void)

{
   struct AutodocNode *TempNode, *PrevNode;
   int Index;
   int CurrentNode;
   int ExistingNode;

   if (ShortAutodocArray=AllocVec((((int)AutodocArray[0])+1)*sizeof(struct ShortAutodocEntry),MEMF_CLEAR))
      {
         for (CurrentNode=1; CurrentNode<=(int)AutodocArray[0]; CurrentNode++)
            {
               if (Break()) return(FALSE);
               if ((int)ShortAutodocArray[0].Name && (ExistingNode=InternalSearchShortAutodoc(FindSlash(AutodocArray[CurrentNode]->Node.Name)+1)))
                  {
                     Index=GetResidentIndex(AutodocArray[CurrentNode]);
                     TempNode=ShortAutodocArray[ExistingNode].AutodocNode;
                     PrevNode=NULL;
                     while (Index>GetResidentIndex(TempNode))
                        {
                           PrevNode=TempNode;
                           TempNode=TempNode->ShortLink;
                        }
                     AutodocArray[CurrentNode]->ShortLink=TempNode;
                     if (PrevNode)
                        {
                           PrevNode->ShortLink=AutodocArray[CurrentNode];
                        }
                     else
                        {
                           ShortAutodocArray[ExistingNode].AutodocNode=AutodocArray[CurrentNode];
                        }
                  }
               else
                  {
                     (int)(ShortAutodocArray[0].Name)++;
                     ShortAutodocArray[(int)ShortAutodocArray[0].Name].Name=FindSlash(AutodocArray[CurrentNode]->Node.Name)+1;
                     ShortAutodocArray[(int)ShortAutodocArray[0].Name].AutodocNode=AutodocArray[CurrentNode];
                  }
            }
         for (CurrentNode=1; CurrentNode<(int)(ShortAutodocArray[0].Name); CurrentNode++)
            {
               if (Break()) return(FALSE);
               for (Index=CurrentNode+1; Index<=(int)(ShortAutodocArray[0].Name); Index++)
                  {
                     if (strcmp(ShortAutodocArray[Index].Name,ShortAutodocArray[CurrentNode].Name)<0)
                        {
                           TempNode=ShortAutodocArray[Index].AutodocNode;
                           ShortAutodocArray[Index].AutodocNode=ShortAutodocArray[CurrentNode].AutodocNode;
                           ShortAutodocArray[CurrentNode].AutodocNode=TempNode;
                           TempNode=(struct AutodocNode *)ShortAutodocArray[Index].Name;
                           ShortAutodocArray[Index].Name=ShortAutodocArray[CurrentNode].Name;
                           ShortAutodocArray[CurrentNode].Name=(char *)TempNode;
                        }
                  }
            }
         return(TRUE);
      }
   PrintFault(ERROR_NO_FREE_STORE,NULL);
   return(FALSE);
}

/***********************************************/

struct AutodocNode *SearchShortAutodoc(char *Name)

{
   int OldIndex;
   int Upper, Lower;
   int Index;
   int Result;
   struct AutodocNode *AutodocNode;

   Lower=1;
   Upper=(int)(ShortAutodocArray[0].Name)+1;
   Index=0;
   do
      {
         OldIndex=Index;
         Index=(Upper+Lower)/2;
         if (!(Result=strcmp(ShortAutodocArray[Index].Name,Name)))
            {
               Upper=strlen(CurrentUnit);
               AutodocNode=ShortAutodocArray[Index].AutodocNode;
               while (AutodocNode)
                  {
                     if (!__builtin_memcmp(CurrentUnit,AutodocNode->Node.Name,Upper))
                        {
                           if (AutodocNode->Node.Name[Upper]=='/')
                              {
                                 return(AutodocNode);
                              }
                        }
                     AutodocNode=AutodocNode->ShortLink;
                  }
               AutodocNode=ShortAutodocArray[Index].AutodocNode;
               if (AutodocNode==CurrentAutodocNode)
                  {
                     AutodocNode=AutodocNode->ShortLink;
                  }
               return(AutodocNode);
            }
         if (Result<0)
            {
               Lower=Index;
            }
         else
            {
               Upper=Index;
            }
      }
   while (Index!=OldIndex);
   return(NULL);
}
