#ifndef PATH_MAX
#  if defined (_POSIX_PATH_MAX)
#    define PATH_MAX _POSIX_PATH_MAX
#  elif defined (MAXPATHLEN)
#    define PATH_MAX MAXPATHLEN
#  elif defined (_PC_PATH_MAX)
#    define PATH_MAX _PC_PATH_MAX
#  else
#    define PATH_MAX 1024
#  endif
#endif

/* Holds all needed info about a MP3 file */
typedef struct node {
	int type;
	char * name;   /* Name of file/dir */
	char * path;   /* Absolute path to the MP3 file */
	off_t filesize;
	int id3v1len;
	int id3v2len;
	int length;
	char *title;
	struct node *sibling; /* Linked list of other entries in same dir */
	struct node *child;   /* Pointer to first entry below this dir */
} mp3entry;

/* These numbers matter, they are the order which the items should appear */
#define TYPE_DIR      0
#define TYPE_MP3      1
/* These are used somewhere but should *never* exist in filetree */
#define TYPE_M3U      2
#define TYPE_INVALID -1

#define IS_DIR(entry) ((entry)->type == TYPE_DIR)
#define IS_FILE(entry) ((entry)->type == TYPE_MP3)

#define HASID3V2(entry) entry->id3v2len > 0
#define HASID3V1(entry) entry->id3v1len > 0

/* Root entry in our file tree */
extern mp3entry * root;

/* Finds an entry in the filetree */
extern mp3entry *findentrybypath(mp3entry *base, char *name);

/* Finds the path of an entry in the filetree */
extern char *findpathbyentry(mp3entry *base, mp3entry *tofind, char *path);

/* Finds the index of an entry (must be file) in the filetree */
extern bool findindexbyentry(mp3entry *base, mp3entry *tofind, int *index);

/* Finds the entry by index in the filetree */
extern mp3entry *findentrybyindex(mp3entry *base, int *index);

/* Finds the range of files that exist below base */
extern bool getrange(mp3entry *base, bool recursive, int *min, int *max);

/* Dumps the entire tree to stdout, for debugging */
extern void showtree(int indent, mp3entry *entry);

/* Adds an entry in the filetree */
extern void addentry(mp3entry **baseptr, mp3entry *toadd);

/* Removes an entry from the list pointed to by rootentry */
extern bool removeentry(mp3entry **baseptr, mp3entry *toremove);

/* Clears and frees a tree of MP3 files */
extern void cleartree(mp3entry **rootentry);

/* Writes the virtual tree to a memory location */
extern int writetree(void *basedest, mp3entry *baseentry);

/* Counts the entries in the list pointed to by rootentry */
extern int countentries(mp3entry *rootentry);

/* Calculates the space needed for the entire tree */
extern int spaceneeded(mp3entry *baseentry);

/* Dumps info about one entry, useful for debugging */
extern void dumpentry(mp3entry *entry);

/* Examines all paths in patharray and (depending on kind of path) adds to file list */
void indexpaths(char **patharray);
