
#include "StringList.h"
#include <stdlib.h>
#include <string.h>
#include "amigamem.h"

#define QUALFLAG (BYTE*) -1

void StringList_Init( StringList *slist, BOOL Qualify )
{
   slist->Entries    = NULL;
   slist->nEntries   = 0;
   slist->Qualifiers = (Qualify ? QUALFLAG : 0);
}

#ifdef STRINGLIST_VERBOSE

void dump_StringList( StringList *list )
{
   int i;
   
   printf("dump_StringList: nEntries=%d\n", list->nEntries );
   
   for (i=0; i<list->nEntries; i++)
      printf("%d (%d), %s\n", 
         i, list->Entries[i], list->Entries[i] );
}

#endif

void StringList_CleanUp( StringList *slist )
{  
   StringList_DeleteAllStrings( slist );
}

BOOL StringList_AddString( StringList *slist,
                           char       *string,
                           BYTE        qualifiers )
{
   char **new_entries;
   BYTE  *new_quals;
   char *new_entry;
   USHORT n, i;

   n = slist->nEntries + 1;
   /*printf("about to malloc\n");*/
   if (new_entries = (char**) Amalloc( sizeof(char*) * n ))
   {
      /*printf("copying to new array...\n");*/
      for (i=0; i<slist->nEntries; i++)
         new_entries[i] = slist->Entries[i];
      /*printf("StringList_AddString: adding new string, n=%d, string=\"%s\"\n", n, string);*/
      new_entries[n-1] = new_entry = Astrdup( string );

      if (slist->Qualifiers)
      {
         /*printf("doing qualifiers...\n");*/
         if (new_quals = (BYTE*) Amalloc( sizeof(BYTE) * n ))
         {
            for (i=0; i<slist->nEntries; i++)
               new_quals[i] = slist->Qualifiers[i];

            new_quals[n-1] = qualifiers;
            /*printf("finished qualifiers!\n");*/

            Afree( slist->Entries );
            if (slist->Qualifiers != QUALFLAG)
              Afree( slist->Qualifiers );
            slist->Entries    = new_entries;
            slist->nEntries++;
            slist->Qualifiers = new_quals;
            /*printf("StringList_AddString : DONE!\n");*/
            return TRUE;
         }
         else
         {
            /*printf("couldn't allocate qualifiers\n");*/
            Afree( new_entry );
            Afree( new_entries );
            return FALSE;
         }
      }
      else
      {
         Afree( slist->Entries );
         slist->Entries = new_entries;
         slist->nEntries++;
         return TRUE;
      }
   }
   else
   {
      ; /*printf("StringList_AddString: Amalloc failed.\n");*/
   }
   return FALSE;
}

BOOL StringList_DeleteString( StringList *slist, USHORT n )
{
   USHORT i;


   if (n >= slist->nEntries) return FALSE;

/*DUMPWAIT("StringList_DeleteString: before Afree\n");*/
   Afree( slist->Entries[n] );
/*DUMPWAIT("StringList_DeleteString: after Afree\n");*/
   
   for (i=n; i<slist->nEntries-1; i++)
   {
      slist->Entries[i] = slist->Entries[i+1];
      if (slist->Qualifiers)
         slist->Qualifiers[i] = slist->Qualifiers[i+1];
   }
   slist->nEntries--;

   slist->Entries = (char**) Arealloc( slist->Entries,
                                       sizeof(char*)*slist->nEntries );
   if (slist->Qualifiers)
   {
      if (slist->nEntries)
         slist->Qualifiers = (BYTE*) Arealloc( slist->Qualifiers,
                                               sizeof(BYTE)*slist->nEntries );
      else
         slist->Qualifiers = QUALFLAG;
   }

 /*DUMPWAIT("end StringList_DeleteString\n");*/

   return TRUE;
}

BOOL StringList_DeleteAllStrings( StringList *slist )
{
   int i;
   
   for (i=0; i<slist->nEntries; i++)
   {
      Afree( slist->Entries[i] ); 
   }

   if (slist->Entries)
   {
      Afree(slist->Entries);
      slist->Entries=NULL;
   }
   if ((slist->Qualifiers) && (slist->Qualifiers != QUALFLAG))
   {
      Afree(slist->Qualifiers);
      slist->Qualifiers = QUALFLAG;
   }
   slist->nEntries = 0;
   return TRUE;
}

void StringList_Sort( StringList *slist )
{
   USHORT j, i, i1;
   char *e_i, *e_i1;
   BYTE q;

   for (j=0; j<slist->nEntries-1; j++)
   {
      for (i=j; i<slist->nEntries-1; i++)
      {
         i1   = i+1;
         e_i  = slist->Entries[i];
         e_i1 = slist->Entries[i1];

         if (strcmp( e_i, e_i1 ) > 0)
         {
            slist->Entries[i]  = e_i1;
            slist->Entries[i1] = e_i;

            if (slist->Qualifiers)
            {
               q = slist->Qualifiers[i];
               slist->Qualifiers[i]  = slist->Qualifiers[i1];
               slist->Qualifiers[i1] = q;
            }
         }
      }
   }
}


BOOL StringList_Dup( StringList *source, StringList *target )
{
   USHORT i, j, n;

   if ((n = source->nEntries) >0)
   {
      target->nEntries = n;

      if (target->Entries = (char**) Amalloc( n * sizeof(char**)) )
      {
         for (i=0; i<n; i++)
         {
            if (!(target->Entries[i] = Astrdup( source->Entries[i] )))
            {
               /* release memory already allocated. */
               for (j=0; j<i; j++)
                  Afree( target->Entries[j] );
               Afree( target->Entries );

               return FALSE;
            }
         }

         if (source->Qualifiers)
         {
            if (target->Qualifiers = (UBYTE*) Amalloc( n * sizeof(UBYTE)))
            {
               for (i=0; i<n; i++)
                  target->Qualifiers[i] = source->Qualifiers[i];
            }
            else
            {
               /* release memory already allocated. */
               StringList_CleanUp(target);
               return FALSE;
            }
         }
         return TRUE;

      }
   }
   else
   {
      StringList_Init( target, (BOOL) source->Qualifiers );
      return TRUE;
   }
}

BOOL StringList_AddStrings( StringList  *slist,
                            char       **strings,
                            BYTE        *qualifiers )
{
   USHORT i;

   for(i=0; strings[i] != NULL; i++)
   {
      if (! StringList_AddString( slist, strings[i],
                           (qualifiers ? qualifiers[i] : 0) ) )
         return FALSE;
   }

   return TRUE;
}
