/*
    ####             #    #     # #
    #   #            #    #       #          The FreeWare C library for
    #   #  ##   ###  #  # #     # ###             RISC OS machines
    #   # #  # #     # #  #     # #  #   ___________________________________
    #   # ####  ###  ##   #     # #  #
    #   # #        # # #  #     # #  #    Please refer to the accompanying
    ####   ### ####  #  # ##### # ###    documentation for conditions of use
    ________________________________________________________________________

    File:    Filing.ReadDir.c
    Author:  Copyright  1994, 1995 Sergio Monesi
    Version: 1.01 (6 Jun 1995)
    Purpose: Reads directory content easily
    Mods:    6 June 1995 - changed procedure names to a more
                           DeskLib-compliant style
             07 Jun 1995 - JS - moved definition of __outofmemory to inside
                                function when compiling a DLL - otherwise
                                cc complains about 'RISC OS (or other reentrant 
                                module has static init. to data 'x$dataseg''.

*/

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

#include "Desk.Core.h"
#include "Desk.Filing.h"
#include "Desk.Error2.h"
#include "Desk.DeskMem.h"
#include "Desk.Str.h"

#include "Errors.h"




void	Desk_Filing_OpenDir2(const char *dirname, Desk_filing_dirdata *dirdata,
                         int bufsize, Desk_filing_readdirtype type, const char* wildcard)
{
 Desk_filing_objtype objtype;

 dirdata->buf=NULL;
 dirdata->dirname=NULL;   /* to avoid problems with free in Desk_Filing_CloseDir */
 dirdata->match=NULL;

 Desk_Filing_ReadCatalogue(dirname, &objtype, NULL, NULL, NULL, NULL, NULL);
 if (objtype==1) {
   Desk_Error2_HandleTextf( "Directory '%s' is actually a file", dirname);
 }
 else if (objtype==0) {
   Desk_Error2_HandleTextf( "Directory '%s' doesn't exist", dirname);
 }

 dirdata->dirname = Desk_strdup( dirname);

 dirdata->buf = Desk_DeskMem_Malloc(bufsize);

 dirdata->size=bufsize;
 dirdata->type=type;
 dirdata->offset=0;
 dirdata->read=0;
 dirdata->match = (wildcard) ? Desk_strdup( wildcard) : NULL;
 
 /* adesso bisogna iniziare a leggere la directory... */
 /* ...no, forse e` inutile... per adesso non lo faccio... */

/* switch(type) {
   case Desk_readdirtype_DIRENTRY:
    break;

 }*/

 return;
}


void	Desk_Filing_OpenDir(
		const char		*dirname, 
		Desk_filing_dirdata	*dirdata,
		int			bufsize, 
		Desk_filing_readdirtype	type
		)
	{
	Desk_Filing_OpenDir2( dirname, dirdata, bufsize, type, NULL);
	}



void *Desk_Filing_ReadDir(Desk_filing_dirdata *dirdata)
{

 if (dirdata->read==0) {    /* no more objects read in the buffer */
   if (dirdata->offset==-1) {    /* no more objects to read */
     return NULL;
   }

   dirdata->read=255;   /* objects to read */

   switch(dirdata->type) {
     case Desk_readdirtype_DIRENTRY:
      Desk_Filing_ReadDirEntry(dirdata->dirname, (Desk_filing_direntry *)dirdata->buf,
                             &dirdata->read, &dirdata->offset,
                             dirdata->size, dirdata->match);
      if (dirdata->read==0) {
        dirdata->offset=-1;
        return NULL;
      }
      dirdata->read--;
      dirdata->act.direntry=(Desk_filing_direntry *)dirdata->buf;
      break;
     case Desk_readdirtype_FULLDIRENTRY:
      Desk_Filing_ReadFullDirEntry(dirdata->dirname, (Desk_filing_fulldirentry *)dirdata->buf,
                                 &dirdata->read, &dirdata->offset,
                                 dirdata->size, dirdata->match);
      if (dirdata->read==0) {
        dirdata->offset=-1;
        return NULL;
      }
      dirdata->read--;
      dirdata->act.fulldirentry=(Desk_filing_fulldirentry *)dirdata->buf;
      break;
     case Desk_readdirtype_NAMEONLY:
      Desk_Filing_ReadDirNames(dirdata->dirname, (char *)dirdata->buf,
                             &dirdata->read, &dirdata->offset,
                             dirdata->size, dirdata->match);
      if (dirdata->read==0) {
        dirdata->offset=-1;
        return NULL;
      }
      dirdata->read--;
      dirdata->act.name=(char *)dirdata->buf;
      break;
   }

 }
 else {     /* some object is ready in buffer */
   switch(dirdata->type) {
     case Desk_readdirtype_DIRENTRY:
      dirdata->read--;
      dirdata->act.direntry=(Desk_filing_direntry *)(((int)(&(dirdata->act.direntry->name))+
                                               strlen(dirdata->act.direntry->name)+4)&~3);
      break;
     case Desk_readdirtype_FULLDIRENTRY:
      dirdata->read--;
      dirdata->act.fulldirentry=(Desk_filing_fulldirentry *)(((int)(&(dirdata->act.fulldirentry->name))+
                                                       strlen(dirdata->act.fulldirentry->name)+4)&~3);
      break;
     case Desk_readdirtype_NAMEONLY:
      dirdata->read--;
/*      dirdata->act.name=(char *)(((int)(&(dirdata->act.name))+strlen(dirdata->act.name)+4)&~3);*/
      dirdata->act.name=(char *)(dirdata->act.name+strlen(dirdata->act.name)+1);
      break;
   }

 }

 return (void *)dirdata->act.act;
}

void Desk_Filing_CloseDir(Desk_filing_dirdata *dirdata)
{
Desk_DeskMem_Free( dirdata->buf);
Desk_DeskMem_Free( dirdata->dirname);
Desk_DeskMem_Free( dirdata->match);
dirdata->buf		= NULL;
dirdata->dirname	= NULL;
dirdata->match		= NULL;
/*
 Desk_bool ret=Desk_bool_TRUE;

 if (dirdata->buf!=NULL) {
   FREE(dirdata->buf);
 }
 else {
   ret=Desk_bool_FALSE;
 }

 if (dirdata->dirname!=NULL) {
   FREE(dirdata->dirname);
 }
 else {
   ret=Desk_bool_FALSE;
 }

 return ret;
*/
 }
