/*
 *	Displays the properties of an object using Endeavour's
 *	Properties Dialog.
 */

#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <glib.h>
#include <endeavour2.h>
#include "../config.h"


static void print_help(const gchar *prog_name);


#define ATOI(s)		(((s) != NULL) ? atoi(s) : 0)
#define ATOL(s)		(((s) != NULL) ? atol(s) : 0)
#define ATOF(s)		(((s) != NULL) ? atof(s) : 0.0f)
#define STRDUP(s)	(((s) != NULL) ? g_strdup(s) : NULL)

#define MAX(a,b)	(((a) > (b)) ? (a) : (b))
#define MIN(a,b)	(((a) < (b)) ? (a) : (b))
#define CLIP(a,l,h)	(MIN(MAX((a),(l)),(h)))
#define STRLEN(s)	(((s) != NULL) ? strlen(s) : 0)
#define STRISEMPTY(s)	(((s) != NULL) ? (*(s) == '\0') : TRUE)


static void print_help(const gchar *prog_name)
{
	g_print(
"Usage: %s <path> [page_name] [options]\n",
	    prog_name
	);
	g_print("\n\
The <path> specifies the path to the object.\n\
\n\
The [page_name] specifies the initial page to map the properties\n\
dialog at, valid values are; \"General\", \"Details\", \"Link\",\n\
\"Device\", or \"Device Node\".\n\
\n\
The [options] can be any of the following:\n\
\n\
        --help                  Prints (this) help screen and exits.\n\
        --version               Prints version information and exits.\n\
\n\
    Return values:\n\
\n\
        0       Success.\n\
        1       General error.\n\
        2       Invalid value.\n\
        3       Systems error or memory allocation error.\n\
        4       User aborted.\n\
\n"
	);
}

int main(int argc, char *argv[])
{
	struct stat lstat_buf;
	gint i, status;
	const gchar *arg, *path, *page_name;
	edv_context_struct *ctx = EDVContextNew();

#define DO_FREE_LOCALS	{	\
 EDVContextDelete(ctx);		\
 ctx = NULL;			\
}

	EDVContextLoadConfigurationFile(ctx, NULL);

	/* Insufficient arguments? */
	if(argc <= 1)
	{
	    print_help(argv[0]);
	    DO_FREE_LOCALS
	    return(2);
	}

	/* Handle the arguments */
	for(i = 1; i < argc; i++)
	{
	    arg = argv[i];
	    if(arg == NULL)
		continue;

	    /* Help */
	    if(!g_strcasecmp(arg, "--help") ||
	       !g_strcasecmp(arg, "-help") ||
	       !g_strcasecmp(arg, "--h") ||
	       !g_strcasecmp(arg, "-h")
	    )
	    {
		print_help(argv[0]);
		DO_FREE_LOCALS
		return(0);
	    }
	    /* Version */
	    else if(!g_strcasecmp(arg, "--version") ||
                    !g_strcasecmp(arg, "-version")
	    )
	    {
                g_print(
"Endeavour Mark II Properties Version " PROG_VERSION "\n"
PROG_COPYRIGHT
                );
		DO_FREE_LOCALS
		return(0);
	    }
	}

	/* Get the first argument as the path */
	path = (argc > 1) ? argv[1] : NULL;
	if(STRISEMPTY(path))
	{
	    g_printerr("Invalid path.\n");
	    DO_FREE_LOCALS
	    return(2);
	}

	/* Get the second argument as the page name */
	page_name = (argc > 2) ? argv[2] : NULL;

	/* Check if the object exists locally */
	if(lstat(path, &lstat_buf) == 0)
	{
	    /* Map the Properties Dialog for the object specified
	     * by path
	     */
	    EDVWindowPropertiesDialogNewWithPage(
		ctx,			/* Context */
		path,			/* Object Path */
		page_name		/* Page Name */
	    );
	    status = 0;
	}
	else
	{
	    /* Unable to stat the object locally */
	    const gint error_code = (gint)errno;
	    gchar *error_msg = STRDUP(strerror((int)error_code));
	    if(error_msg != NULL)
	    {
		g_printerr(
"%s: %s.\n",
		    path,
		    error_msg
		);
		g_free(error_msg);
	    }
	    status = 1;
	}

	EDVContextSync(ctx);

	DO_FREE_LOCALS

	return(status);
#undef DO_FREE_LOCALS
}
