/* -*- ObjC -*- */
#ifndef _seb_included_seborrhea_h
#define _seb_included_seborrhea_h

#include <objc/Object.h>
#include "seborrhea-dirlist.h"
#include "token.h"

#define MAX_METAFILE_COMMANDS		10
#define MAX_METAFILE_PROPERTY_HANDLERS	5
#define MAX_FILETYPE_HANDLERS		10

#define not			!
#define streq(a,b)		(strcmp(a,b) == 0)
#define strneq(a,b)		(strcmp(a,b) != 0)
#define strcaseeq(a,b)		(strcasecmp(a,b) == 0)
#define strcaseneq(a,b)		(strcasecmp(a,b) != 0)

/*--------------------------------------------------------------*/

@interface Sebum: Object
{
    char *name;
}
- initWithName:(const char *)name_;
- (const char *) name;
@end

extern char *seborrhea_data_root_directories[];
void seborrhea_add_root_directory(const char *dir);
void seborrhea_free_root_directories(void);

/*--------------------------------------------------------------*/
/* Protocols.							*/
/*--------------------------------------------------------------*/

@protocol SebContainer
- (BOOL) addToList:(Sebum *)child;
- (BOOL) startLoadingSebumDirectory:(const char *)top_dir :(const char *)sub_dir WithDirList:(DirectoryList *)dirlist;
- (BOOL) loadSebumDirectory:(const char *)dirname;
@end

#include "seborrhea-image.h"
#include "seborrhea-sample.h"

@protocol UniqueSebum
/* This is a dummy protocol to mark that this sebum is not shared, but
   only used by one thing, so when that thing is freed, we need to
   free it. */
@end

/*--------------------------------------------------------------*/

typedef BOOL (*command_handler_proc_t)(const char *, unsigned int, unsigned int, Token *[], Sebum<SebContainer> *, DirectoryList *);
typedef void (*property_handler_proc_t)(Sebum *, unsigned int, Token *[]);
typedef BOOL (*filetype_handler_proc_t)(const char *, const char *, unsigned int, Sebum<SebContainer> *, DirectoryList *);

typedef struct {
    const char *command;
    command_handler_proc_t proc;
} metafile_command_handler_t;

typedef struct {
    const char *prop;
    property_handler_proc_t proc;
} metafile_property_handler_t;

typedef struct {
    const char *ext;
    filetype_handler_proc_t proc;
} filename_extension_handler_t;

extern metafile_command_handler_t metafile_command_handlers[MAX_METAFILE_COMMANDS];
extern metafile_property_handler_t metafile_property_handlers[MAX_METAFILE_PROPERTY_HANDLERS];
extern filename_extension_handler_t filename_extension_handlers[MAX_FILETYPE_HANDLERS];

/*--------------------------------------------------------------*/

@interface AbstractSebContainer: Sebum <SebContainer>
{
    BOOL process_directories;

    unsigned int nelements;
    Sebum **element;
}
- (BOOL) loadContentsOfDirectory:(const char *)top_dir :(const char *)sub_dir WithDirList:(DirectoryList *)dirlist;
@end

void delimited_strdup(char *dest, const char *start, const char *end, size_t size);

/*--------------------------------------------------------------*/

void seborrhea_register_metafile_command(const char *, command_handler_proc_t);
void seborrhea_register_metafile_property(const char *, property_handler_proc_t);
void seborrhea_register_filetype_handler(const char *, filetype_handler_proc_t);

#endif
