/* vim: set noet ts=8 sts=8 sw=8 : */

/**
 * \file ecma119_tree.h
 *
 * Declarations for creating, modifying and printing filesystem trees that
 * are compatible with ecma119.
 */

#ifndef LIBISO_ECMA119_TREE_H
#define LIBISO_ECMA119_TREE_H

#include <sys/stat.h>

#include "file.h"

struct ecma119_write_target;
struct iso_tree_node;

enum ecma119_node_type {
	ECMA119_FILE,
	ECMA119_SYMLINK,
	ECMA119_DIR,
	ECMA119_PLACEHOLDER /**< placeholder for a relocated dir. */
};

struct ecma119_dir_info {
	struct susp_info self_susp;	/**< susp entries for "." */
	struct susp_info parent_susp;	/**< susp entries for ".." */

	size_t len;			/**< sum of the lengths of children's
					  * Directory Records (including SU) */
	size_t CE_len;			/**< sum of the lengths of children's
					  * SUSP CE areas */
	size_t block;

	int depth;
	size_t path_len;		/**< The length of a path up to, and
					  * including, this directory. This
					  * cannot exceed 255. */
	size_t nchildren;
	struct ecma119_tree_node **children;

	struct ecma119_tree_node *real_parent;
					/**< The parent before relocation */
};

/**
 * A node for a tree containing all the information necessary for writing
 * an ISO9660 volume.
 */
struct ecma119_tree_node
{
	char *iso_name;			/**< in ASCII, conforming to the
	                          * current ISO level. */
	char *full_name;        /**< full name, in current locale (TODO put this in UTF-8?) */
	size_t dirent_len;		/**< Length of the directory record,
	                          * not including SU. */

	struct ecma119_tree_node *parent;
	struct ecma119_write_target *target;

	struct stat attrib;

	struct susp_info susp;

	enum ecma119_node_type type; /**< file, symlink, directory or placeholder */
	union {
		struct iso_file *file;
		char *dest;
		struct ecma119_dir_info dir;
		struct ecma119_tree_node *real_me; /**< this field points to
					                        *  the relocated directory.
					                        */
	} info;
};

/**
 * Create a new ecma119_tree that corresponds to the tree represented by
 * \p iso_root.
 */
struct ecma119_tree_node*
ecma119_tree_create(struct ecma119_write_target *target,
		    struct iso_tree_node *iso_root);

/**
 * Free an ecma119 tree.
 */
void
ecma119_tree_free(struct ecma119_tree_node *root);

/**
 * Print an ecma119 tree.
 */
void
ecma119_tree_print(struct ecma119_tree_node *root, int spaces);

#endif /* LIBISO_ECMA119_TREE_H */
