/**
 * @file libcomprex/directory.h Directory structures
 * 
 * $Id: directory.h,v 1.11 2002/05/30 08:02:44 chipx86 Exp $
 *
 * @Copyright (C) 2001-2002 The GNUpdate Project.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA  02111-1307, USA.
 */
#ifndef _LIBCOMPREX_DIRECTORY_H_
#define _LIBCOMPREX_DIRECTORY_H_

#ifdef __cplusplus
extern "C" {
#endif

typedef struct _CxDirectory CxDirectory; /**< CxDirectory */

#include <libcomprex/file.h>

/**
 * A representation of a directory on the filesystem or in an archive.
 */
struct _CxDirectory
{
	CxArchive *archive;       /**< The parent archive.                    */
	CxDirectory *parentDir;   /**< The parent directory.                  */
	char *name;               /**< The path name of this directory.       */

	CxFile *files;            /**< The first file in this directory.      */
	CxFile *lastFile;         /**< The last file in this directory.       */
	unsigned int fileCount;   /**< The number of files in this directory. */

	CxDirectory *subdirs;     /**< The first directory in this directory. */
	CxDirectory *lastSubDir;  /**< The last directory in this directory.  */
	unsigned int subdirCount; /**< The number of directories in this
	                               directory.                             */

	unsigned int refCount;    /**< The reference count.                   */

	CxDirectory *prev;        /**< The previous directory in a list.      */
	CxDirectory *next;        /**< The next directory in a list.          */
};

/**************************************************************************/
/** @name Structure (De)allocation Functions                              */
/**************************************************************************/
/*@{*/

/**
 * Creates a new CxDirectory structure.
 *
 * This does NOT create a new directory. For that, use cxMkDir().
 *
 * @todo Implement cxMkDir()
 *
 * @return A new, empty CxDirectory structure.
 *
 * @see cxDestroyDirectory()
 */
CxDirectory *cxNewDirectory(void);

/**
 * Destroys a CxDirectory structure.
 *
 * @param dir The CxDirectory to destroy.
 *
 * @see cxNewDirectory()
 */
void cxDestroyDirectory(CxDirectory *dir);

/*@}*/

/**************************************************************************/
/** @name Attribute Modification Functions                                */
/**************************************************************************/
/*@{*/

/**
 * Sets the archive that owns the directory.
 *
 * This should only be used by libcomprex.
 *
 * @param dir     The directory.
 * @param archive The archive that owns this directory.
 *
 * @see cxGetDirArchive()
 */
void cxSetDirArchive(CxDirectory *dir, CxArchive *archive);

/**
 * Sets the specified directory's parent directory.
 *
 * @param dir    The directory.
 * @param parent The parent directory.
 *
 * @see cxGetDirParent()
 */
void cxSetDirParent(CxDirectory *dir, CxDirectory *parent);

/**
 * Sets the path name of this directory.
 *
 * @param dir  The directory.
 * @param name The new path name.
 *
 * @see cxGetDirectoryName()
 */
void cxSetDirectoryName(CxDirectory *dir, const char *name);

/*@}*/

/**************************************************************************/
/** @name Attribute Retrieval Functions                                   */
/**************************************************************************/
/*@{*/

/**
 * Returns the archive that owns the specified directory.
 *
 * @param dir The directory.
 *
 * @return The archive that owns this directory.
 *
 * @see cxSetDirArchive()
 */
CxArchive *cxGetDirArchive(CxDirectory *dir);

/**
 * Returns the specified directory's parent directory.
 *
 * @param dir The directory.
 *
 * @return The specified directory's parent directory.
 *
 * @see cxSetDirParent()
 */
CxDirectory *cxGetDirParent(CxDirectory *dir);

/**
 * Returns the path name of the specified directory.
 *
 * @param dir The directory.
 *
 * @return The path name of the specified directory.
 *
 * @see cxSetDirectoryName()
 */
const char *cxGetDirectoryName(CxDirectory *dir);

/**
 * Returns the number of files in the specified directory.
 *
 * @param dir The directory.
 *
 * @return The number of files in the specified directory.
 *
 * @see cxGetSubDirCount()
 */
unsigned int cxGetFileCount(CxDirectory *dir);

/**
 * Returns the number of subdirectories in the specified directory.
 *
 * @param dir The directory.
 *
 * @return The number of subdirectories in the specified directory.
 *
 * @see cxGetFileCount()
 */
unsigned int cxGetSubDirCount(CxDirectory *dir);

/*@}*/

/**************************************************************************/
/** @name Directory Processing Functions                                  */
/**************************************************************************/
/*@{*/

/**
 * Returns the subdirectory specified in the path.
 *
 * @param base The base directory.
 * @param path The path.
 *
 * @return The subdirectory, or @c NULL if not found.
 *
 * @see cxGetFile()
 */
CxDirectory *cxGetDirectory(CxDirectory *base, const char *path);

/**
 * Returns the file specified in the path.
 *
 * @param base The base directory.
 * @param path The path.
 *
 * @return The file, or @c NULL if not found.
 *
 * @see cxGetDirectory()
 */
CxFile *cxGetFile(CxDirectory *base, const char *path);

/*@}*/

/**************************************************************************/
/** @name Directory Modification Functions                                */
/**************************************************************************/
/*@{*/

/**
 * Adds a file to the directory.
 *
 * Note that this won't actually create a file in that directory.
 * This just modifies the structure itself!
 *
 * The directory will claim the reference on @a file, and will delete
 * the structure when @a dir is deleted. If you wish to keep @a file
 * intact, you must claim a reference to it using CX_LINK().
 *
 * @param dir  The directory.
 * @param file The file to add.
 *
 * @see CxFile
 * @see cxDirAddSubDir()
 * @see cxDirRemoveFile()
 * @see cxDirRemoveSubDir()
 */
void cxDirAddFile(CxDirectory *dir, CxFile *file);

/**
 * Adds a subdirectory to a directory.
 *
 * Note that this won't actually create a subdirectory in that directory.
 * This just modifies the structure itself!
 *
 * The directory will claim the reference on @a subdir, and will delete
 * the structure when @a dir is deleted. If you wish to keep @a subdir
 * intact, you must claim a reference to it using CX_LINK().
 *
 * @param dir    The directory.
 * @param subdir The subdirectory to add.
 *
 * @see CxDirectory
 * @see cxDirAddFile()
 * @see cxDirRemoveFile()
 * @see cxDirRemoveSubDir()
 */
void cxDirAddSubDir(CxDirectory *dir, CxDirectory *subdir);

/**
 * Removes a file from the directory.
 *
 * Note that this won't actually remove the file from the archive.
 * This just modifies the structure itself!
 *
 * @param dir  The directory.
 * @param file The file to remove.
 *
 * @see CxFile
 * @see cxDirAddFile()
 * @see cxDirAddSubDir()
 * @see cxDirRemoveSubDir()
 */
void cxDirRemoveFile(CxDirectory *dir, CxFile *file);

/**
 * Removes a subdirectory from the directory.
 *
 * Note that this won't actually remove the subdirectory from the archive.
 * This just modifies the structure itself!
 *
 * @param dir    The directory.
 * @param subdir The subdirectory to remove.
 *
 * @see CxFile
 * @see cxDirAddFile()
 * @see cxDirAddSubDir()
 * @see cxDirRemoveFile()
 */
void cxDirRemoveSubDir(CxDirectory *dir, CxDirectory *subdir);

/*@}*/

/**************************************************************************/
/** @name Iteration Functions                                             */
/**************************************************************************/
/*@{*/

/**
 * Returns the first file in the directory.
 *
 * @param dir The directory.
 *
 * @return The first file in the directory.
 *
 * @see cxGetFirstSubDir()
 * @see cxGetNextFile()
 * @see cxGetPreviousFile()
 */
CxFile *cxGetFirstFile(CxDirectory *dir);

/**
 * Returns the first subdirectory in the directory.
 *
 * @param dir The directory.
 *
 * @return The first subdirectory in the directory.
 *
 * @see cxGetFirstFile()
 * @see cxGetNextDir()
 * @see cxGetPreviousDir()
 */
CxDirectory *cxGetFirstSubDir(CxDirectory *dir);

/**
 * Returns the previous directory in a list of directories.
 *
 * @param dir The current directory.
 *
 * @return The previous directory in the list.
 *
 * @see cxGetFirstSubDir()
 * @see cxGetNextDir()
 */
CxDirectory *cxGetPreviousDir(CxDirectory *dir);

/**
 * Returns the next directory in a list of directories.
 *
 * @param dir The current directory.
 *
 * @return The next directory in the list.
 *
 * @see cxGetFirstSubDir()
 * @see cxGetPreviousDir()
 */
CxDirectory *cxGetNextDir(CxDirectory *dir);

/*@}*/

#ifdef __cplusplus
}
#endif

#endif /* _LIBCOMPREX_DIRECTORY_H_ */

