
 /* SP_SPOListSubs.c
    - Functions for spobject List Handling -
    (c) 1993-94 by Andreas R. Kleinert
    Last changes : 20.02.1994
 */

#include "SuperPlay.h"


 /* spobject List Handling Functions */

struct SPS_SPOList *  __regargs SPS_GetSPOList(void);
void	              __regargs SPS_FreeSPOList(struct SPS_SPOList *SPOList);
long                  __regargs SPS_AddSPOEntry(struct SPS_SPOList *mlist,  struct SPO_ObjectNode *spo_node);
struct SPS_SPOEntry * __regargs SPS_GetSPOEntry(struct SPS_SPOList *SPOList, long entrynum);


struct SPS_SPOList * __regargs SPS_GetSPOList(void)
{
 struct List           *obj_list = N;
 struct SPS_SPOList    *SPOList  = N;
 struct List           *samelist = N;
 struct SPO_ObjectNode *spo_node = N;
 struct SPS_SPOEntry   *entry    = N;

 samelist = (struct List *) AllocVec(sizeof(struct SPS_SPOList), (MEMF_CLEAR|MEMF_PUBLIC));
 if(samelist)
  {
   SPOList = (APTR) samelist;

   SPOList->spl_NumEntries = 0;

   samelist->lh_Head	 = (struct Node *) &(samelist->lh_Tail);
   samelist->lh_Tail	 = N;
   samelist->lh_TailPred = (struct Node *) &(samelist->lh_Head);
   samelist->lh_Type	 = NT_UNKNOWN;
  }else return(NULL);

 obj_list = (APTR) &SuperPlayBase->spb_SPObjectList;
 if(!obj_list) return(SPOList);

 for(spo_node=(APTR) obj_list->lh_Head;(spo_node)&&(spo_node!=(APTR) &(obj_list->lh_Tail));)
  {
   SPS_AddSPOEntry(SPOList, spo_node);

   spo_node = (APTR) ((struct Node *)spo_node)->ln_Succ;
  }

 SPOList->spl_Labels = (UBYTE **) AllocVec((SPOList->spl_NumEntries+1)*4, (MEMF_CLEAR|MEMF_PUBLIC));
 if(SPOList->spl_Labels)
  {
   long i = 0;

   for(entry=(APTR) SPOList->spl_EntryList.lh_Head;(entry)&&(entry!=(APTR) &(SPOList->spl_EntryList.lh_Tail));)
    {
     SPOList->spl_Labels[i] = &entry->spe_ObjectID[0]; i++;

     entry = (APTR) ((struct Node *)entry)->ln_Succ;
    }
  }else
  {
   SPS_FreeSPOList(SPOList);

   FreeVec(SPOList);

   SPOList = N;
  }

 return(SPOList);
}

void __regargs SPS_FreeSPOList(struct SPS_SPOList *SPOList)
{
 struct SPS_SPOEntry *entry;

 if(SPOList)
  {
   for(entry=(APTR) SPOList->spl_EntryList.lh_Head;(entry)&&(entry!=(APTR) &(SPOList->spl_EntryList.lh_Tail));)
    {
     Remove((APTR) entry);
     FreeVec(entry);

     entry = (APTR) SPOList->spl_EntryList.lh_Head;
    }

   if(SPOList->spl_Labels) FreeVec(SPOList->spl_Labels);
   FreeVec(SPOList);
  }
}

long __regargs SPS_AddSPOEntry(struct SPS_SPOList *mlist, struct SPO_ObjectNode *spo_node)
{
 struct SPS_SPOEntry *entry;
 UBYTE i;

 if(!mlist || !spo_node) return(FALSE);

 for(i=0; i<spo_node->spo_SubTypeNum; i++)
  {
   entry = (APTR) AllocVec(sizeof(struct SPS_SPOEntry), ((MEMF_CLEAR|MEMF_PUBLIC)|MEMF_PUBLIC));
   if(!entry) return(FALSE);

   mlist->spl_NumEntries++;

   strcpy(entry->spe_ObjectID, spo_node->spo_TypeID);
   strcat(entry->spe_ObjectID, " ");
   strcat(entry->spe_ObjectID, spo_node->spo_SubTypeID[i]);

   entry->spe_ObjectCode     = spo_node->spo_TypeCode;
   entry->spe_ObjectSubCode  = spo_node->spo_SubTypeCode[i];

   entry->spe_SPO_ObjectNode = spo_node;

   ((struct Node *)entry)->ln_Name = entry->spe_ObjectID;

   AddTail((APTR)mlist, (APTR)entry);
  }

 return(TRUE);
}

struct SPS_SPOEntry * __regargs SPS_GetSPOEntry(struct SPS_SPOList *SPOList, long entrynum)
{
 struct SPS_SPOEntry *entry;
 struct SPS_SPOEntry *ret_entry = N;
 ULONG i = 0;

 if(!SPOList) return(N);

 for(entry=(APTR) SPOList->spl_EntryList.lh_Head;(entry)&&(entry!=(APTR) &(SPOList->spl_EntryList.lh_Tail));)
  {
   if(i == entrynum)
    {
     ret_entry = entry;

     break;
    }

   entry = (APTR) ((struct Node *)entry)->ln_Succ; i++;
  }

 return(ret_entry);
}
