/*
                              Endeavour Device
 */

#ifndef EDV_DEVICE_H
#define EDV_DEVICE_H

#include <glib.h>
#include "edv_types.h"


typedef struct _edv_fs_type_struct	edv_fs_type_struct;
#define EDV_FS_TYPE(p)			((edv_fs_type_struct *)(p))
typedef struct _edv_device_struct	edv_device_struct;
#define EDV_DEVICE(p)			((edv_device_struct *)(p))


/*
 *      Device Flags:
 */
typedef enum {
	EDV_DEVICE_MOUNTED		= (1 << 0),
	EDV_DEVICE_READ_ONLY		= (1 << 1),
	EDV_DEVICE_NO_UNMOUNT		= (1 << 2),
	EDV_DEVICE_UNLISTED		= (1 << 3)	/* Do not show on
							 * "brief" listings */
} edv_device_flags;

/*
 *	Device Icon States:
 */
typedef enum {
	EDV_DEVICE_ICON_STATE_STANDARD,
	EDV_DEVICE_ICON_STATE_SELECTED,		/* Selected or expanded */
	EDV_DEVICE_ICON_STATE_UNMOUNTED		/* Not mounted */
} edv_device_icon_state;
#define EDV_DEVICE_TOTAL_ICON_STATES		3


/*
 *	Filesystem Types Codes & Conical Names:
 */
#define EDV_FS_TYPE_EMPTY		0x0000

#define EDV_FS_TYPE_MSDOS		0x4d44
#define EDV_FS_TYPE_MSDOS_NAME		"msdos"

#define EDV_FS_TYPE_VFAT		0x4d45	/* This is really msdos, 0x4d44 */
#define EDV_FS_TYPE_VFAT_NAME		"vfat"

#define EDV_FS_TYPE_ISO9660		0x9660
#define EDV_FS_TYPE_ISO9660_NAME	"iso9660"

#define EDV_FS_TYPE_HPFS		0xF995E849
#define EDV_FS_TYPE_HPFS_NAME		"hpfs"

#define EDV_FS_TYPE_EXT			0x137D
#define EDV_FS_TYPE_EXT_NAME		"ext"

#define EDV_FS_TYPE_EXT2		0xEF53
#define EDV_FS_TYPE_EXT2_NAME		"ext2"
#define EDV_FS_TYPE_EXT2_OLD		0xEF51
#define EDV_FS_TYPE_EXT2_OLD_NAME	"ext2"

#define EDV_FS_TYPE_EXT3		0xEF53		/* Same as EDV_FS_TYPE_EXT2 */
#define EDV_FS_TYPE_EXT3_NAME		"ext3"

#define EDV_FS_TYPE_MINIX		0x138F
#define EDV_FS_TYPE_MINIX_NAME		"minix"
#define EDV_FS_TYPE_MINIX_ORIG		0x137F   
#define EDV_FS_TYPE_MINIX_ORIG_NAME	"minix"

#define EDV_FS_TYPE_MINIX2		0x2468
#define EDV_FS_TYPE_MINIX2_NAME		"minix2"
#define EDV_FS_TYPE_MINIX2_EXT		0x138F
#define EDV_FS_TYPE_MINIX2_EXT_NAME	"minix2"

#define EDV_FS_TYPE_NCP			0x564c
#define EDV_FS_TYPE_NCP_NAME		"ncp"

#define EDV_FS_TYPE_NFS			0x6969
#define EDV_FS_TYPE_NFS_NAME		"nfs"

#define EDV_FS_TYPE_SMB			0x517B
#define EDV_FS_TYPE_SMB_NAME		"smb"

#define EDV_FS_TYPE_XENIX		0x012FF7B4
#define EDV_FS_TYPE_XENIX_NAME		"xenix"

#define EDV_FS_TYPE_SYSV4		0x012FF7B5
#define EDV_FS_TYPE_SYSV4_NAME		"sysv4"

#define EDV_FS_TYPE_SYSV2		0x012FF7B6
#define EDV_FS_TYPE_SYSV2_NAME		"sysv2"

#define EDV_FS_TYPE_COH			0x012FF7B7
#define EDV_FS_TYPE_COH_NAME		"coh"

#define EDV_FS_TYPE_UFS			0x00011954
#define EDV_FS_TYPE_UFS_NAME		"ufs"

#define EDV_FS_TYPE_XIA			0x012FD16D
#define EDV_FS_TYPE_XIA_NAME		"xia"


#define EDV_FS_TYPE_SWAP                0x0050  /* Universal swap */
#define EDV_FS_TYPE_SWAP_NAME           "swap"

#define EDV_FS_TYPE_PROC		0x9fa0
#define EDV_FS_TYPE_PROC_NAME		"proc"


/*
 *	Filesystems List:
 *
 *	List of filesystem type codes with their corresponding
 *	filesystem names.
 */
#define EDV_FS_TYPE_LIST	{				\
{ EDV_FS_TYPE_MSDOS,	EDV_FS_TYPE_MSDOS_NAME,		0 },	\
{ EDV_FS_TYPE_VFAT,	EDV_FS_TYPE_VFAT_NAME,		0 },	\
								\
{ EDV_FS_TYPE_ISO9660,	EDV_FS_TYPE_ISO9660_NAME,	0 },	\
								\
{ EDV_FS_TYPE_HPFS,	EDV_FS_TYPE_HPFS_NAME,		0 },	\
								\
{ EDV_FS_TYPE_EXT,	EDV_FS_TYPE_EXT_NAME,		0 },	\
{ EDV_FS_TYPE_EXT2,	EDV_FS_TYPE_EXT2_NAME,		0 },	\
{ EDV_FS_TYPE_EXT3,	EDV_FS_TYPE_EXT3_NAME,		0 },	\
								\
{ EDV_FS_TYPE_MINIX,	EDV_FS_TYPE_MINIX_NAME,		0 },	\
{ EDV_FS_TYPE_MINIX2,	EDV_FS_TYPE_MINIX2_NAME,	0 },	\
								\
{ EDV_FS_TYPE_NCP,	EDV_FS_TYPE_NCP_NAME,		0 },	\
{ EDV_FS_TYPE_NFS,	EDV_FS_TYPE_NFS_NAME,		0 },	\
{ EDV_FS_TYPE_SMB,	EDV_FS_TYPE_SMB_NAME,		0 },	\
								\
{ EDV_FS_TYPE_XENIX,	EDV_FS_TYPE_XENIX_NAME,		0 },	\
{ EDV_FS_TYPE_SYSV4,	EDV_FS_TYPE_SYSV4_NAME,		0 },	\
{ EDV_FS_TYPE_SYSV2,	EDV_FS_TYPE_SYSV2_NAME,		0 },	\
								\
{ EDV_FS_TYPE_COH,	EDV_FS_TYPE_COH_NAME,		0 },	\
{ EDV_FS_TYPE_UFS,	EDV_FS_TYPE_UFS_NAME,		0 },	\
{ EDV_FS_TYPE_XIA,	EDV_FS_TYPE_XIA_NAME,		0 },	\
								\
{ EDV_FS_TYPE_SWAP,	EDV_FS_TYPE_SWAP_NAME,		0 },	\
{ EDV_FS_TYPE_PROC,	EDV_FS_TYPE_PROC_NAME,		0 },	\
								\
{ 0,			NULL,				0 }	\
}
/*
 *	Filesystem Type:
 */
struct _edv_fs_type_struct {
	guint32		fs_type;	/* One of EDV_FS_TYPE_* */
	gchar		*name;		/* Filesystem's conical name */
	guint32		flags;		/* Options (reserved) */
};


/*
 *	Device:
 */
struct _edv_device_struct {

	edv_device_flags	flags;

	guint32		fs_type;	/* One of EDV_FS_TYPE_* */

	gchar		*name;		/* Descriptive name */
	gchar		*device_path;	/* Path to device object */
	gchar		*mount_path;	/* Path to mount point directory */

	/* Small 20x20 icons */
	gchar		*small_icon_file[EDV_DEVICE_TOTAL_ICON_STATES];

	/* Medium 32x32 icons */
	gchar		*medium_icon_file[EDV_DEVICE_TOTAL_ICON_STATES];

	/* Large 48x48 icons */
	gchar		*large_icon_file[EDV_DEVICE_TOTAL_ICON_STATES];

	/* Mount and unmount commands, if either of these are not NULL
	 * then its respective command will be issued instead of a mount
	 * performed internally with system calls by this program
	 */
	gchar		*command_mount,
			*command_unmount,
			*command_eject;

	/* Commands to run external programs for device maintainance */
	gchar		*command_check,
			*command_tools,
			*command_format;

	/* Statistics, units are in 1k blocks (or whatever statfs()
	 * gives it in
	 *
	 * Note, statistics are only valid if member is_mounted is TRUE
	 */
	gulong		blocks_total,
			blocks_available,	/* Available to effective user id */
			blocks_free;

	/* Time stamps */
	gulong		last_mount_time,	/* Last time it was used */
			last_check_time;	/* Last time command_check aws runned */

};
#define EDV_DEVICE_IS_MOUNTED(p)	(((p) != NULL) ? \
 ((p)->flags & EDV_DEVICE_MOUNTED) : FALSE)
#define EDV_DEVICE_IS_READ_ONLY(p)	(((p) != NULL) ? \
 ((p)->flags & EDV_DEVICE_READ_ONLY) : FALSE)
#define EDV_DEVICE_IS_NO_UNMOUNT(p)	(((p) != NULL) ? \
 ((p)->flags & EDV_DEVICE_NO_UNMOUNT) : FALSE)
#define EDV_DEVICE_IS_UNLISTED(p)	(((p) != NULL) ? \
 ((p)->flags & EDV_DEVICE_UNLISTED) : FALSE)


/*
 *	Matches the Device from the specified Devices List who's
 *	mount_path matches the specified mount_path.
 */                                       
extern edv_device_struct *EDVDeviceListMatchMountPath(
	edv_device_struct **list, const gint total,
	gint *n,
	const gchar *mount_path
);

/*
 *	Matches the Device from the specified Devices List who's
 *	device_path matches the specified device_path.
 */                                       
extern edv_device_struct *EDVDeviceListMatchDevicePath(
	edv_device_struct **list, const gint total,
	gint *n,
	const gchar *device_path
);

/*
 *	Matches the Device from the specified Devices List that the     
 *	object specified by path exists on.
 */
extern edv_device_struct *EDVDeviceListMatchObject(
	edv_device_struct **list, const gint total,
	gint *n,
	const gchar *path
);


/*
 *	Updates the is_mounted mount state for all the Devices in the
 *	specified Devices List by checking with the system.
 */
extern void EDVDevicesListUpdateMountStates(
	edv_device_struct **list, const gint total
);

/*
 *	Updates the is_mounted mount state for the specified Device
 *	by checking with the system.
 */
extern void EDVDeviceUpdateMountState(edv_device_struct *d);


/*
 *	Updates the blocks_total, blocks_available, and blocks_free
 *	statistics for all the Devices in the specified Devices List
 *	by checking with the system.
 *
 *	Statistics will not be obtained for Devices that are not marked
 *	as mounted so you should call EDVDevicesListUpdateMountStates()
 *	prior to calling this function.
 */
extern void EDVDevicesListUpdateStats(
	edv_device_struct **list, const gint total
);

/*
 *	Updates the blocks_total, blocks_available, and blocks_free
 *	statistics of the specified Device by checking with the system.
 *
 *	Statistics will not be obtained if the Device is not marked
 *	as mounted so you should call EDVDeviceUpdateMountState()
 *	prior to calling this function.
 */
extern void EDVDeviceUpdateStats(edv_device_struct *d);


/*
 *	Returns the Filesystem Type code (one of EDV_FS_TYPE_*) based on
 *	the specified Filesystem Type String.
 */
extern guint32 EDVDeviceGetFSTypeFromName(const gchar *name);

/*
 *	Returns the Filesystem Type string that corresponds to the
 *	specified Filesystem Type code (one of EDV_FS_TYPE_*).
 */
extern const gchar *EDVDeviceGetFSNameFromType(const guint32 type);


/*
 *	Creates a new Device.
 */
extern edv_device_struct *EDVDeviceNew(
	const guint32 fs_type,		/* One of EDV_FS_TYPE_* */
	const gchar *name,		/* Descriptive name */
	const gchar *device_path,	/* Path to device object */
	const gchar *mount_path		/* Path to mount point directory */
);

/*
 *	Coppies the Device.
 */
extern edv_device_struct *EDVDeviceCopy(const edv_device_struct *d);

/*
 *	Deletes the Device.
 */
extern void EDVDeviceDelete(edv_device_struct *d);


#endif	/* EDV_DEVICE_H */
