/*
 * 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(obj)				(G_TYPE_CHECK_INSTANCE_CAST (obj, GVN_TYPE_PARAM, GvnParam))
#define GVN_IS_PARAM(obj)			(G_TYPE_CHECK_INSTANCE_TYPE (obj, GVN_TYPE_PARAM))
#define GVN_PARAM_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS (obj, GVN_TYPE_PARAM, GvnParamClass))

typedef struct _GvnParam GvnParam;
typedef struct _GvnParamClass GvnParamClass;

/**
 * GvnParamMode:
 * @GVN_PARAM_FREE: It is not set.
 * @GVN_PARAM_SLAVE: It is set as slave.
 * @GVN_PARAM_MASTER: It is set as master.
 * 
 * The mode in which is Binded.
 **/
typedef enum
{
	 GVN_PARAM_FREE
	,GVN_PARAM_SLAVE
	,GVN_PARAM_MASTER
}
GvnParamMode;

/**
 * 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;

/**
 * GvnParam:
 * @slaves: (element-type Gvn.Param):
 **/
struct _GvnParam
{
	GInitiallyUnowned parent;
	GValue * value;
	GError * error;
	GvnParamStatus status;
	GvnParamSpec * spec;
	GvnParamMode mode;
	GvnParam * master;
	GSList * slaves;
};

struct _GvnParamClass
{
	/* <private> */
	GInitiallyUnownedClass parent;
	void	(* put_value)	(GvnParam * obj, const GValue * value);
	void	(* set_spec)	(GvnParam * obj, const GvnParamSpec * spec);
	void	(* set_status)	(GvnParam * obj, GvnParamStatus status);
	void	(* set_error)	(GvnParam * obj, GError * error);
};

GType					gvn_param_get_type			();
GvnParam *				gvn_param_new				();
GvnParam *				gvn_param_new_with_spec		(const GvnParamSpec * spec);
const GValue *			gvn_param_get_value			(GvnParam * param);
gboolean				gvn_param_set_value			(GvnParam * param, const GValue * value, GError ** err);
const GvnParamSpec *	gvn_param_get_spec			(GvnParam * param);
GType					gvn_param_get_gtype			(GvnParam * param);
gboolean				gvn_param_get_null			(GvnParam * param);
gboolean				gvn_param_get_editable		(GvnParam * param);
const GValue *			gvn_param_get_default		(GvnParam * obj);
void					gvn_param_set_to_default	(GvnParam * obj);
GvnParam *				gvn_param_get_master		(GvnParam * sparam);
void					gvn_param_set_master		(GvnParam * sparam, GvnParam * dparam);
void					gvn_param_value_changed		(GvnParam * obj);
GvnParamStatus			gvn_param_get_status		(GvnParam * obj);
const GError *			gvn_param_get_error			(GvnParam * obj);

#endif