/*
 * Copyright (c)2004 Cat's Eye Technologies.  All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 
 *   Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * 
 *   Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in
 *   the documentation and/or other materials provided with the
 *   distribution.
 * 
 *   Neither the name of Cat's Eye Technologies nor the names of its
 *   contributors may be used to endorse or promote products derived
 *   from this software without specific prior written permission. 
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

/*
 * dfui.h
 * $Id: dfui.h,v 1.7 2004/07/10 06:59:03 cpressey Exp $
 */

#ifndef __DFUI_H
#define __DFUI_H

/*
 * TYPEDEFS
 */

typedef	int		dfui_err_t;
typedef	char *		dfui_id_t;

/*
 * CONSTANTS
 */

#define	DFUI_SUCCESS	(dfui_err_t)1
#define	DFUI_FAILURE	(dfui_err_t)0

/*
 * Transports.
 */

#define DFUI_TRANSPORT_CAPS	1
#define DFUI_TRANSPORT_NPIPE	2
#define DFUI_TRANSPORT_TCP	3

/*
 * Message types.
 */

#define DFUI_BE_MSG_READY	'r'	/* send me back a reply please */

#define DFUI_BE_MSG_STOP	'X'	/* shut down please, we're done */
#define DFUI_BE_MSG_PRESENT	'P'	/* present this form to the user */
#define DFUI_BE_MSG_PROG_BEGIN	'b'	/* begin showing a progress bar */
#define DFUI_BE_MSG_PROG_UPDATE	'u'	/* update the progress bar */
#define DFUI_BE_MSG_PROG_END	'e'	/* stop showing the progress bar */

#define DFUI_FE_MSG_READY	'r'	/* send me a form or something */

#define DFUI_FE_MSG_SUBMIT	'S'	/* submit results of a form */
#define DFUI_FE_MSG_CONTINUE	'c'	/* nothing stopping a progress bar */
#define DFUI_FE_MSG_CANCEL	'C'	/* user cancelled a progress bar */
#define DFUI_FE_MSG_ABORT	'X'	/* something catastrophic (^C?) */

/*
 * STRUCTURES
 */

struct dfui_form;
struct dfui_response;
struct dfui_progress;

/* Connections */

struct dfui_connection {
	int transport;		/* transport layer: CAPS, NPIPE, or TCP */
	char *rendezvous;	/* rendezvous point */
	struct extbuf *ebuf;	/* last message recvd */
	void *t_data;		/* transport-specific connection data */

	dfui_err_t (*be_start)(struct dfui_connection *);
	dfui_err_t (*be_stop)(struct dfui_connection *);
	dfui_err_t (*be_ll_exchange)(struct dfui_connection *, char, char *);

	dfui_err_t (*fe_connect)(struct dfui_connection *);
	dfui_err_t (*fe_disconnect)(struct dfui_connection *);

	dfui_err_t (*fe_ll_request)(struct dfui_connection *, char, char *);
};

/* Common structures on objects */

struct dfui_info {
	char *name;
	char *short_desc;
	char *long_desc;
};

struct dfui_dataset {
	struct dfui_dataset *next;
	struct dfui_celldata *celldata_head;
};

struct dfui_celldata {
	struct dfui_celldata *next;
	dfui_id_t field_id;
	char *value;
};

/* Form objects */

struct dfui_form {
	dfui_id_t id;
	struct dfui_info *info;
	int multiple;
	int extensible;
	struct dfui_field *field_head;
	struct dfui_action *action_head;
	struct dfui_dataset *dataset_head;
	struct dfui_celldata *hint_head;
};

struct dfui_field {
	dfui_id_t id;
	struct dfui_info *info;
	struct dfui_field *next;
	int editable;
	int obscured;
	struct dfui_option *option_head;
	struct dfui_celldata *hint_head;
};

struct dfui_option {
	char *value;
	struct dfui_option *next;
};

struct dfui_action {
	dfui_id_t id;
	struct dfui_info *info;
	struct dfui_action *next;
	struct dfui_celldata *hint_head;
};

/* Progress objects */

struct dfui_progress {
	struct dfui_info *info;
	int amount;
};

/* Response objects */

struct dfui_response {
	dfui_id_t form_id;
	dfui_id_t action_id;
	struct dfui_dataset *dataset_head;
};

/*
 * PROTOTYPES
 */

/*
 * UTILITY (form/field creation, etc)
 */

dfui_id_t			 dfui_id_new(char *);
dfui_id_t			 dfui_id_dup(dfui_id_t);
void				 dfui_id_free(dfui_id_t);
int				 dfui_id_is(dfui_id_t, char *);

struct dfui_info		*dfui_info_new(char *, char *, char *);
void				 dfui_info_free(struct dfui_info *);
char				*dfui_info_get_name(struct dfui_info *);
char				*dfui_info_get_short_desc(struct dfui_info *);
char				*dfui_info_get_long_desc(struct dfui_info *);
void				 dfui_info_set_name(struct dfui_info *, char *);
void				 dfui_info_set_short_desc(struct dfui_info *, char *);
void				 dfui_info_set_long_desc(struct dfui_info *, char *);

struct dfui_celldata		*dfui_celldata_new(dfui_id_t, char *);
void				 dfui_celldata_free(struct dfui_celldata *);
void				 dfui_celldatas_free(struct dfui_celldata *);
void				 dfui_celldatas_foreach(int (*)(struct dfui_celldata *, void *),
							struct dfui_celldata *, void *);
struct dfui_celldata		*dfui_celldata_find(struct dfui_celldata *, dfui_id_t);
struct dfui_celldata		*dfui_celldata_get_next(struct dfui_celldata *);
dfui_id_t			 dfui_celldata_get_field_id(struct dfui_celldata *);
char *				 dfui_celldata_get_value(struct dfui_celldata *);

struct dfui_dataset		*dfui_dataset_new(void);
struct dfui_dataset		*dfui_dataset_dup(struct dfui_dataset *);
void				 dfui_dataset_free(struct dfui_dataset *);
void				 dfui_datasets_free(struct dfui_dataset *);
void				 dfui_datasets_foreach(int (*)(struct dfui_dataset *, void *),
							struct dfui_dataset *, void *);
struct dfui_celldata		*dfui_dataset_celldata_add(struct dfui_dataset *,
					dfui_id_t, char *);
struct dfui_celldata		*dfui_dataset_celldata_get_first(struct dfui_dataset *);
struct dfui_celldata		*dfui_dataset_celldata_find(struct dfui_dataset *, dfui_id_t);
void				 dfui_dataset_celldatas_foreach(
					int (*)(struct dfui_celldata *, void *),
					struct dfui_dataset *, void *);
struct dfui_dataset		*dfui_dataset_get_next(struct dfui_dataset *);
char				*dfui_dataset_get_value(struct dfui_dataset *, dfui_id_t);
char				*dfui_dataset_dup_value(struct dfui_dataset *, dfui_id_t);

struct dfui_field		*dfui_field_new(dfui_id_t, struct dfui_info *);
void				 dfui_field_free(struct dfui_field *);
void				 dfui_fields_free(struct dfui_field *);
void				 dfui_fields_foreach(int (*)(struct dfui_field *, void *),
						     struct dfui_field *, void *);
struct dfui_option		*dfui_field_option_add(struct dfui_field *, char *);
struct dfui_celldata		*dfui_field_hint_add(struct dfui_field *, char *, char *);
char				*dfui_field_hint_find(struct dfui_field *, char *);
int				 dfui_field_hint_is(struct dfui_field *, char *, char *);
struct dfui_field		*dfui_field_get_next(struct dfui_field *);
dfui_id_t			 dfui_field_get_id(struct dfui_field *);
struct dfui_info		*dfui_field_get_info(struct dfui_field *);
void				 dfui_field_set_editable(struct dfui_field *, int);
int				 dfui_field_is_editable(struct dfui_field *);
void				 dfui_field_set_obscured(struct dfui_field *, int);
int				 dfui_field_is_obscured(struct dfui_field *);

struct dfui_option		*dfui_option_new(char *);
void				 dfui_option_free(struct dfui_option *);
void				 dfui_options_free(struct dfui_option *);
void				 dfui_options_foreach(int (*)(struct dfui_option *, void *),
						     struct dfui_option *, void *);

struct dfui_action		*dfui_action_new(dfui_id_t, struct dfui_info *);
void				 dfui_action_free(struct dfui_action *);
void				 dfui_actions_free(struct dfui_action *);
void				 dfui_actions_foreach(int (*)(struct dfui_action *, void *),
						     struct dfui_action *, void *);
struct dfui_action		*dfui_action_get_next(struct dfui_action *);
struct dfui_celldata		*dfui_action_hint_add(struct dfui_action *, char *, char *);
char				*dfui_action_hint_find(struct dfui_action *, char *);
int				 dfui_action_hint_is(struct dfui_action *, char *, char *);
dfui_id_t			 dfui_action_get_id(struct dfui_action *);
struct dfui_info		*dfui_action_get_info(struct dfui_action *);

struct dfui_form		*dfui_form_new(dfui_id_t, struct dfui_info *);
struct dfui_form		*dfui_form_create(char *, char *, char *, char *, ...);
void				 dfui_form_free(struct dfui_form *);
struct dfui_field		*dfui_form_field_add(struct dfui_form *,
					dfui_id_t, struct dfui_info *);
struct dfui_action		*dfui_form_action_add(struct dfui_form *,
					dfui_id_t, struct dfui_info *);
void				 dfui_form_dataset_add(struct dfui_form *,
					struct dfui_dataset *);
struct dfui_dataset		*dfui_form_dataset_get_first(struct dfui_form *);
int				 dfui_form_dataset_count(struct dfui_form *);
void				 dfui_form_datasets_free(struct dfui_form *);
struct dfui_celldata		*dfui_form_hint_add(struct dfui_form *, char *, char *);
char				*dfui_form_hint_find(struct dfui_form *, char *);
int				 dfui_form_hint_is(struct dfui_form *, char *, char *);
void				 dfui_form_fields_foreach(int (*)(struct dfui_field *, void *),
						     struct dfui_form *, void *);
struct dfui_field		*dfui_form_field_find(struct dfui_form *, dfui_id_t);
struct dfui_field		*dfui_form_field_get_first(struct dfui_form *);
int				 dfui_form_field_count(struct dfui_form *);
void				 dfui_form_actions_foreach(int (*)(struct dfui_action *, void *),
						     struct dfui_form *, void *);
struct dfui_action		*dfui_form_action_find(struct dfui_form *, dfui_id_t);
struct dfui_action		*dfui_form_action_get_first(struct dfui_form *);
int				 dfui_form_action_count(struct dfui_form *);
dfui_id_t			 dfui_form_get_id(struct dfui_form *);
struct dfui_info		*dfui_form_get_info(struct dfui_form *);
void				 dfui_form_set_multiple(struct dfui_form *, int);
int				 dfui_form_is_multiple(struct dfui_form *);
void				 dfui_form_set_extensible(struct dfui_form *, int);
int				 dfui_form_is_extensible(struct dfui_form *);

struct dfui_response		*dfui_response_new(dfui_id_t, dfui_id_t);
void				 dfui_response_free(struct dfui_response *);
void				 dfui_response_dataset_add(struct dfui_response *,
					struct dfui_dataset *);
struct dfui_dataset		*dfui_response_dataset_get_first(struct dfui_response *);
int				 dfui_response_dataset_count(struct dfui_response *);
dfui_id_t			 dfui_response_get_form_id(struct dfui_response *);
dfui_id_t			 dfui_response_get_action_id(struct dfui_response *);

struct dfui_progress		*dfui_progress_new(struct dfui_info *, int);
void				 dfui_progress_free(struct dfui_progress *);
struct dfui_info		*dfui_progress_get_info(struct dfui_progress *);
void				 dfui_progress_set_amount(struct dfui_progress *, int);
int				 dfui_progress_get_amount(struct dfui_progress *);

/*
 * PROTOCOL
 */

struct dfui_connection	*dfui_connection_new(int, char *);
void			 dfui_connection_free(struct dfui_connection *);

/*
 * BACKEND VERY HIGH LEVEL INTERFACE
 */

int			 dfui_be_present_dialog(struct dfui_connection *,
						char *, char *, char *, ...);

/*
 * BACKEND HIGH LEVEL INTERFACE
 */
dfui_err_t		dfui_be_start(struct dfui_connection *);
dfui_err_t		dfui_be_stop(struct dfui_connection *);

dfui_err_t		dfui_be_present(struct dfui_connection *,
					struct dfui_form *, struct dfui_response **);
dfui_err_t		dfui_be_progress_begin(struct dfui_connection *,
						struct dfui_progress *);
dfui_err_t		dfui_be_progress_update(struct dfui_connection *,
						struct dfui_progress *, int *);
dfui_err_t		dfui_be_progress_end(struct dfui_connection *);

/*
 * FRONTEND HIGH LEVEL INTERFACE
 */
dfui_err_t		dfui_fe_connect(struct dfui_connection *);
dfui_err_t		dfui_fe_disconnect(struct dfui_connection *);

dfui_err_t		dfui_fe_receive(struct dfui_connection *, char *, void **);
dfui_err_t		dfui_fe_submit(struct dfui_connection *, struct dfui_response *);
dfui_err_t		dfui_fe_progress_continue(struct dfui_connection *);
dfui_err_t		dfui_fe_progress_cancel(struct dfui_connection *);
dfui_err_t		dfui_fe_confirm_stop(struct dfui_connection *);
dfui_err_t		dfui_fe_abort(struct dfui_connection *);

#endif /* !__DFUI_H */
