/*
                                Endeavour Device
 */

#ifndef EDV_DEVICE_H
#define EDV_DEVICE_H

#include <gtk/gtk.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_INTERNAL		= (1 << 3),	/* Internal, do not
							 * save to devices
							 * file */
	EDV_DEVICE_UNLISTED		= (1 << 4),	/* Do not show on
							 * "brief" listings */
	EDV_DEVICE_REALIZED		= (1 << 5)
} 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 Type Codes & 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 */
	GdkPixmap	*small_pixmap[EDV_DEVICE_TOTAL_ICON_STATES];
	GdkBitmap	*small_mask[EDV_DEVICE_TOTAL_ICON_STATES];
	gchar		*small_icon_file[EDV_DEVICE_TOTAL_ICON_STATES];

	/* Medium 32x32 icons */
	GdkPixmap	*medium_pixmap[EDV_DEVICE_TOTAL_ICON_STATES];
	GdkBitmap	*medium_mask[EDV_DEVICE_TOTAL_ICON_STATES];
	gchar		*medium_icon_file[EDV_DEVICE_TOTAL_ICON_STATES];

	/* Large 48x48 icons */
	GdkPixmap	*large_pixmap[EDV_DEVICE_TOTAL_ICON_STATES];
	GdkBitmap	*large_mask[EDV_DEVICE_TOTAL_ICON_STATES];
	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 */
	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_INTERNAL(p)	(((p) != NULL) ? \
 ((p)->flags & EDV_DEVICE_INTERNAL) : FALSE)
#define EDV_DEVICE_IS_UNLISTED(p)	(((p) != NULL) ? \
 ((p)->flags & EDV_DEVICE_UNLISTED) : FALSE)
#define EDV_DEVICE_IS_REALIZED(p)	(((p) != NULL) ? \
 ((p)->flags & EDV_DEVICE_REALIZED) : FALSE)


/* Mount State */
extern void EDVDeviceUpdateMountStateFromSystem(edv_device_struct *d);
extern void EDVDeviceUpdateMountState(edv_device_struct *d);

/* Filesystem */
extern guint32 EDVDeviceGetFSTypeFromName(const gchar *name);
extern const gchar *EDVDeviceGetFSNameFromType(guint32 type);

/* Devices */
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 */
);
extern void EDVDeviceLoadSmallIconsData(
	edv_device_struct *d, guint8 ***data
);
extern void EDVDeviceMediumIconsData(
	edv_device_struct *d, guint8 ***data
);
extern void EDVDeviceLoadLargeIconsData(
	edv_device_struct *d, guint8 ***data
);
extern void EDVDeviceRealize(
	edv_device_struct *d, const gboolean force_rerealize
);
extern void EDVDeviceDelete(edv_device_struct *d);


#endif	/* EDV_DEVICE_H */
