/*
 * Copyright (C) 2012 - Juan Ferrer Toribio
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef GVN_PARAM_H
#define GVN_PARAM_H

#include <glib-object.h>
#include "gvn-param-spec.h"

#define GVN_PARAM_LOG_DOMAIN		(g_quark_from_string ("GvnParam"))

#define GVN_TYPE_PARAM					(gvn_param_get_type ())
#define GVN_PARAM(self)					(G_TYPE_CHECK_INSTANCE_CAST (self, GVN_TYPE_PARAM, GvnParam))
#define GVN_IS_PARAM(self)				(G_TYPE_CHECK_INSTANCE_TYPE (self, GVN_TYPE_PARAM))
#define GVN_PARAM_GET_INTERFACE(self)	(G_TYPE_INSTANCE_GET_INTERFACE (self, GVN_TYPE_PARAM, GvnParamInterface))

typedef struct _GvnParam GvnParam;
typedef struct _GvnParamInterface GvnParamInterface;

/**
 * GvnParamStatus:
 * @GVN_PARAM_STATUS_OK: The parameter is ready.
 * @GVN_PARAM_STATUS_BUSY: The parameter is busy.
 * @GVN_PARAM_STATUS_ERROR: The parameter value is incompatible to its spec.
 * 
 * The status of the param.
 **/
typedef enum
{
	 GVN_PARAM_STATUS_OK
	,GVN_PARAM_STATUS_BUSY
	,GVN_PARAM_STATUS_ERROR
}
GvnParamStatus;

typedef const GValue *			(* GvnParamGetValueFunc)		(GvnParam * self);
typedef gboolean				(* GvnParamRequestValueFunc)	(GvnParam * self, const GValue * value, GError ** err);
typedef GvnParam *				(* GvnParamGetMasterFunc)		(GvnParam * self);
typedef void					(* GvnParamSetMasterFunc)		(GvnParam * self, GvnParam * master);
typedef const GvnParamSpec *	(* GvnParamGetSpecFunc)			(GvnParam * self);
typedef GvnParamStatus			(* GvnParamGetStatusFunc)		(GvnParam * self);

/**
 * GvnParam:
 * @slaves: (element-type Gvn.Param):
 **/
struct _GvnParam;

struct _GvnParamInterface
{
	/* <private> */
	GInitiallyUnownedClass parent;
	GvnParamGetValueFunc get_value;
	GvnParamRequestValueFunc request_value;
	GvnParamGetMasterFunc get_master;
	GvnParamSetMasterFunc set_master;
	GvnParamGetSpecFunc get_spec;
	GvnParamGetStatusFunc get_status;
};

GType					gvn_param_get_type			();
const GValue *			gvn_param_get_value			(GvnParam * self);
gboolean				gvn_param_request_value		(GvnParam * self, const GValue * value, GError ** err);
void					gvn_param_set_value			(GvnParam * self, const GValue * value);
GvnParam *				gvn_param_get_master		(GvnParam * self);
void					gvn_param_set_master		(GvnParam * self, GvnParam * master);
const GvnParamSpec *	gvn_param_get_spec			(GvnParam * self);
GvnParamStatus			gvn_param_get_status		(GvnParam * self);
void					gvn_param_value_changed		(GvnParam * self);

gboolean				gvn_param_is_null			(GvnParam * self);
void					gvn_param_set_null			(GvnParam * self);
gboolean				gvn_param_get_boolean		(GvnParam * self);
void					gvn_param_set_boolean		(GvnParam * self, gboolean value);
gint					gvn_param_get_int			(GvnParam * self);
void					gvn_param_set_int			(GvnParam * self, gint value);
glong					gvn_param_get_long			(GvnParam * self);
void					gvn_param_set_long			(GvnParam * self, glong value);
gdouble					gvn_param_get_double		(GvnParam * self);
void					gvn_param_set_double		(GvnParam * self, gdouble value);
const gchar *			gvn_param_get_string		(GvnParam * self);
void					gvn_param_set_string		(GvnParam * self, const gchar * value);
gpointer				gvn_param_get_boxed			(GvnParam * self);
void					gvn_param_set_boxed			(GvnParam * self, gpointer value);

#endif