/* rygel-logical-expression.c generated by valac 0.48.5, the Vala compiler
 * generated from rygel-logical-expression.vala, do not modify */

/*
 * Copyright (C) 2009 Nokia Corporation.
 * Copyright (C) 2012 Intel Corporation.
 *
 * Author: Zeeshan Ali (Khattak) <zeeshanak@gnome.org>
 *
 * This file is part of Rygel.
 *
 * Rygel is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * Rygel 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <glib-object.h>
#include <glib.h>
#include <stdlib.h>
#include <string.h>

typedef enum  {
	RYGEL_LOGICAL_OPERATOR_AND,
	RYGEL_LOGICAL_OPERATOR_OR
} RygelLogicalOperator;

#define RYGEL_TYPE_LOGICAL_OPERATOR (rygel_logical_operator_get_type ())

#define RYGEL_TYPE_SEARCH_EXPRESSION (rygel_search_expression_get_type ())
#define RYGEL_SEARCH_EXPRESSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_TYPE_SEARCH_EXPRESSION, RygelSearchExpression))
#define RYGEL_SEARCH_EXPRESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_TYPE_SEARCH_EXPRESSION, RygelSearchExpressionClass))
#define RYGEL_IS_SEARCH_EXPRESSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_TYPE_SEARCH_EXPRESSION))
#define RYGEL_IS_SEARCH_EXPRESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_TYPE_SEARCH_EXPRESSION))
#define RYGEL_SEARCH_EXPRESSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_TYPE_SEARCH_EXPRESSION, RygelSearchExpressionClass))

typedef struct _RygelSearchExpression RygelSearchExpression;
typedef struct _RygelSearchExpressionClass RygelSearchExpressionClass;
typedef struct _RygelSearchExpressionPrivate RygelSearchExpressionPrivate;

#define RYGEL_TYPE_MEDIA_OBJECT (rygel_media_object_get_type ())
#define RYGEL_MEDIA_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_TYPE_MEDIA_OBJECT, RygelMediaObject))
#define RYGEL_MEDIA_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_TYPE_MEDIA_OBJECT, RygelMediaObjectClass))
#define RYGEL_IS_MEDIA_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_TYPE_MEDIA_OBJECT))
#define RYGEL_IS_MEDIA_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_TYPE_MEDIA_OBJECT))
#define RYGEL_MEDIA_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_TYPE_MEDIA_OBJECT, RygelMediaObjectClass))

typedef struct _RygelMediaObject RygelMediaObject;
typedef struct _RygelMediaObjectClass RygelMediaObjectClass;

#define RYGEL_TYPE_LOGICAL_EXPRESSION (rygel_logical_expression_get_type ())
#define RYGEL_LOGICAL_EXPRESSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RYGEL_TYPE_LOGICAL_EXPRESSION, RygelLogicalExpression))
#define RYGEL_LOGICAL_EXPRESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), RYGEL_TYPE_LOGICAL_EXPRESSION, RygelLogicalExpressionClass))
#define RYGEL_IS_LOGICAL_EXPRESSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RYGEL_TYPE_LOGICAL_EXPRESSION))
#define RYGEL_IS_LOGICAL_EXPRESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), RYGEL_TYPE_LOGICAL_EXPRESSION))
#define RYGEL_LOGICAL_EXPRESSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), RYGEL_TYPE_LOGICAL_EXPRESSION, RygelLogicalExpressionClass))

typedef struct _RygelLogicalExpression RygelLogicalExpression;
typedef struct _RygelLogicalExpressionClass RygelLogicalExpressionClass;
typedef struct _RygelLogicalExpressionPrivate RygelLogicalExpressionPrivate;
#define _g_free0(var) (var = (g_free (var), NULL))

struct _RygelSearchExpression {
	GTypeInstance parent_instance;
	volatile int ref_count;
	RygelSearchExpressionPrivate * priv;
	gpointer op;
	gpointer operand1;
	gpointer operand2;
};

struct _RygelSearchExpressionClass {
	GTypeClass parent_class;
	void (*finalize) (RygelSearchExpression *self);
	gboolean (*satisfied_by) (RygelSearchExpression* self, RygelMediaObject* media_object);
	gchar* (*to_string) (RygelSearchExpression* self);
};

struct _RygelLogicalExpression {
	RygelSearchExpression parent_instance;
	RygelLogicalExpressionPrivate * priv;
};

struct _RygelLogicalExpressionClass {
	RygelSearchExpressionClass parent_class;
};

static gpointer rygel_logical_expression_parent_class = NULL;

GType rygel_logical_operator_get_type (void) G_GNUC_CONST;
gpointer rygel_search_expression_ref (gpointer instance);
void rygel_search_expression_unref (gpointer instance);
GParamSpec* rygel_param_spec_search_expression (const gchar* name,
                                                const gchar* nick,
                                                const gchar* blurb,
                                                GType object_type,
                                                GParamFlags flags);
void rygel_value_set_search_expression (GValue* value,
                                        gpointer v_object);
void rygel_value_take_search_expression (GValue* value,
                                         gpointer v_object);
gpointer rygel_value_get_search_expression (const GValue* value);
GType rygel_search_expression_get_type (void) G_GNUC_CONST;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (RygelSearchExpression, rygel_search_expression_unref)
GType rygel_media_object_get_type (void) G_GNUC_CONST;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (RygelMediaObject, g_object_unref)
GType rygel_logical_expression_get_type (void) G_GNUC_CONST;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (RygelLogicalExpression, rygel_search_expression_unref)
static gboolean rygel_logical_expression_real_satisfied_by (RygelSearchExpression* base,
                                                     RygelMediaObject* media_object);
gboolean rygel_search_expression_satisfied_by (RygelSearchExpression* self,
                                               RygelMediaObject* media_object);
static gchar* rygel_logical_expression_real_to_string (RygelSearchExpression* base);
gchar* rygel_search_expression_to_string (RygelSearchExpression* self);
RygelLogicalExpression* rygel_logical_expression_new (void);
RygelLogicalExpression* rygel_logical_expression_construct (GType object_type);
RygelSearchExpression* rygel_search_expression_construct (GType object_type,
                                                          GType g_type,
                                                          GBoxedCopyFunc g_dup_func,
                                                          GDestroyNotify g_destroy_func,
                                                          GType h_type,
                                                          GBoxedCopyFunc h_dup_func,
                                                          GDestroyNotify h_destroy_func,
                                                          GType i_type,
                                                          GBoxedCopyFunc i_dup_func,
                                                          GDestroyNotify i_destroy_func);
static GType rygel_logical_expression_get_type_once (void);

static GType
rygel_logical_operator_get_type_once (void)
{
	static const GEnumValue values[] = {{RYGEL_LOGICAL_OPERATOR_AND, "RYGEL_LOGICAL_OPERATOR_AND", "and"}, {RYGEL_LOGICAL_OPERATOR_OR, "RYGEL_LOGICAL_OPERATOR_OR", "or"}, {0, NULL, NULL}};
	GType rygel_logical_operator_type_id;
	rygel_logical_operator_type_id = g_enum_register_static ("RygelLogicalOperator", values);
	return rygel_logical_operator_type_id;
}

GType
rygel_logical_operator_get_type (void)
{
	static volatile gsize rygel_logical_operator_type_id__volatile = 0;
	if (g_once_init_enter (&rygel_logical_operator_type_id__volatile)) {
		GType rygel_logical_operator_type_id;
		rygel_logical_operator_type_id = rygel_logical_operator_get_type_once ();
		g_once_init_leave (&rygel_logical_operator_type_id__volatile, rygel_logical_operator_type_id);
	}
	return rygel_logical_operator_type_id__volatile;
}

static gboolean
rygel_logical_expression_real_satisfied_by (RygelSearchExpression* base,
                                            RygelMediaObject* media_object)
{
	RygelLogicalExpression * self;
	gconstpointer _tmp0_;
	gboolean result = FALSE;
	self = (RygelLogicalExpression*) base;
	g_return_val_if_fail (media_object != NULL, FALSE);
	_tmp0_ = ((RygelSearchExpression*) self)->op;
	switch ((RygelLogicalOperator) ((gintptr) _tmp0_)) {
		case RYGEL_LOGICAL_OPERATOR_AND:
		{
			gboolean _tmp1_ = FALSE;
			gconstpointer _tmp2_;
			_tmp2_ = ((RygelSearchExpression*) self)->operand1;
			if (rygel_search_expression_satisfied_by ((RygelSearchExpression*) _tmp2_, media_object)) {
				gconstpointer _tmp3_;
				_tmp3_ = ((RygelSearchExpression*) self)->operand2;
				_tmp1_ = rygel_search_expression_satisfied_by ((RygelSearchExpression*) _tmp3_, media_object);
			} else {
				_tmp1_ = FALSE;
			}
			result = _tmp1_;
			return result;
		}
		case RYGEL_LOGICAL_OPERATOR_OR:
		{
			gboolean _tmp4_ = FALSE;
			gconstpointer _tmp5_;
			_tmp5_ = ((RygelSearchExpression*) self)->operand1;
			if (rygel_search_expression_satisfied_by ((RygelSearchExpression*) _tmp5_, media_object)) {
				_tmp4_ = TRUE;
			} else {
				gconstpointer _tmp6_;
				_tmp6_ = ((RygelSearchExpression*) self)->operand2;
				_tmp4_ = rygel_search_expression_satisfied_by ((RygelSearchExpression*) _tmp6_, media_object);
			}
			result = _tmp4_;
			return result;
		}
		default:
		{
			result = FALSE;
			return result;
		}
	}
}

static gchar*
rygel_logical_expression_real_to_string (RygelSearchExpression* base)
{
	RygelLogicalExpression * self;
	gchar* _tmp0_ = NULL;
	gconstpointer _tmp1_;
	gchar* operand1 = NULL;
	gchar* _tmp5_;
	gchar* _tmp6_ = NULL;
	gconstpointer _tmp7_;
	gchar* operand2 = NULL;
	gchar* _tmp11_;
	const gchar* _tmp12_;
	gconstpointer _tmp13_;
	gchar* _tmp14_;
	gchar* result = NULL;
	self = (RygelLogicalExpression*) base;
	_tmp1_ = ((RygelSearchExpression*) self)->operand1;
	if (((RygelSearchExpression*) _tmp1_) != NULL) {
		gconstpointer _tmp2_;
		gchar* _tmp3_;
		_tmp2_ = ((RygelSearchExpression*) self)->operand1;
		_tmp3_ = rygel_search_expression_to_string ((RygelSearchExpression*) _tmp2_);
		_g_free0 (_tmp0_);
		_tmp0_ = _tmp3_;
	} else {
		gchar* _tmp4_;
		_tmp4_ = g_strdup ("none");
		_g_free0 (_tmp0_);
		_tmp0_ = _tmp4_;
	}
	_tmp5_ = g_strdup (_tmp0_);
	operand1 = _tmp5_;
	_tmp7_ = ((RygelSearchExpression*) self)->operand2;
	if (((RygelSearchExpression*) _tmp7_) != NULL) {
		gconstpointer _tmp8_;
		gchar* _tmp9_;
		_tmp8_ = ((RygelSearchExpression*) self)->operand2;
		_tmp9_ = rygel_search_expression_to_string ((RygelSearchExpression*) _tmp8_);
		_g_free0 (_tmp6_);
		_tmp6_ = _tmp9_;
	} else {
		gchar* _tmp10_;
		_tmp10_ = g_strdup ("none");
		_g_free0 (_tmp6_);
		_tmp6_ = _tmp10_;
	}
	_tmp11_ = g_strdup (_tmp6_);
	operand2 = _tmp11_;
	_tmp12_ = operand1;
	_tmp13_ = ((RygelSearchExpression*) self)->op;
	_tmp14_ = g_strdup_printf ("(%s %d %s)", _tmp12_, (gint) ((RygelLogicalOperator) ((gintptr) _tmp13_)), operand2);
	result = _tmp14_;
	_g_free0 (operand2);
	_g_free0 (_tmp6_);
	_g_free0 (operand1);
	_g_free0 (_tmp0_);
	return result;
}

RygelLogicalExpression*
rygel_logical_expression_construct (GType object_type)
{
	RygelLogicalExpression* self = NULL;
	self = (RygelLogicalExpression*) rygel_search_expression_construct (object_type, RYGEL_TYPE_LOGICAL_OPERATOR, NULL, NULL, RYGEL_TYPE_SEARCH_EXPRESSION, (GBoxedCopyFunc) rygel_search_expression_ref, (GDestroyNotify) rygel_search_expression_unref, RYGEL_TYPE_SEARCH_EXPRESSION, (GBoxedCopyFunc) rygel_search_expression_ref, (GDestroyNotify) rygel_search_expression_unref);
	return self;
}

RygelLogicalExpression*
rygel_logical_expression_new (void)
{
	return rygel_logical_expression_construct (RYGEL_TYPE_LOGICAL_EXPRESSION);
}

static void
rygel_logical_expression_class_init (RygelLogicalExpressionClass * klass,
                                     gpointer klass_data)
{
	rygel_logical_expression_parent_class = g_type_class_peek_parent (klass);
	((RygelSearchExpressionClass *) klass)->satisfied_by = (gboolean (*) (RygelSearchExpression*, RygelMediaObject*)) rygel_logical_expression_real_satisfied_by;
	((RygelSearchExpressionClass *) klass)->to_string = (gchar* (*) (RygelSearchExpression*)) rygel_logical_expression_real_to_string;
}

static void
rygel_logical_expression_instance_init (RygelLogicalExpression * self,
                                        gpointer klass)
{
}

/**
 * This is a parsed UPnP search expression consisting of two other search expressions
 * joined by a boolean operator such as AND or OR.
 */
static GType
rygel_logical_expression_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (RygelLogicalExpressionClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) rygel_logical_expression_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (RygelLogicalExpression), 0, (GInstanceInitFunc) rygel_logical_expression_instance_init, NULL };
	GType rygel_logical_expression_type_id;
	rygel_logical_expression_type_id = g_type_register_static (RYGEL_TYPE_SEARCH_EXPRESSION, "RygelLogicalExpression", &g_define_type_info, 0);
	return rygel_logical_expression_type_id;
}

GType
rygel_logical_expression_get_type (void)
{
	static volatile gsize rygel_logical_expression_type_id__volatile = 0;
	if (g_once_init_enter (&rygel_logical_expression_type_id__volatile)) {
		GType rygel_logical_expression_type_id;
		rygel_logical_expression_type_id = rygel_logical_expression_get_type_once ();
		g_once_init_leave (&rygel_logical_expression_type_id__volatile, rygel_logical_expression_type_id);
	}
	return rygel_logical_expression_type_id__volatile;
}

