/* queue.c generated by valac 0.52.0, the Vala compiler
 * generated from queue.vala, do not modify */

/* queue.vala
 *
 * Copyright (C) 2009  Didier Villevalois
 *
 * This library 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.

 * This library 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
 *
 * Author:
 * 	Didier 'Ptitjes Villevalois <ptitjes@free.fr>
 */

#include "gee.h"
#include <glib-object.h>
#include <glib.h>

static gboolean gee_queue_real_offer (GeeQueue* self,
                               gconstpointer element);
static gint gee_queue_real_drain (GeeQueue* self,
                           GeeCollection* recipient,
                           gint amount);
static GType gee_queue_get_type_once (void);

/**
 * Offers the specified element to this queue.
 *
 * @param element the element to offer to the queue
 *
 * @return        ``true`` if the element was added to the queue
 */
static gboolean
gee_queue_real_offer (GeeQueue* self,
                      gconstpointer element)
{
	gboolean result = FALSE;
	result = gee_collection_add ((GeeCollection*) self, element);
	return result;
}

gboolean
gee_queue_offer (GeeQueue* self,
                 gconstpointer element)
{
	GeeQueueIface* _iface_;
	g_return_val_if_fail (self != NULL, FALSE);
	_iface_ = GEE_QUEUE_GET_INTERFACE (self);
	if (_iface_->offer) {
		return _iface_->offer (self, element);
	}
	return FALSE;
}

/**
 * Peeks (retrieves, but not remove) an element from this queue.
 *
 * @return the element peeked from the queue (or ``null`` if none was
 *         available)
 */
gpointer
gee_queue_peek (GeeQueue* self)
{
	GeeQueueIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GEE_QUEUE_GET_INTERFACE (self);
	if (_iface_->peek) {
		return _iface_->peek (self);
	}
	return NULL;
}

/**
 * Polls (retrieves and remove) an element from this queue.
 *
 * @return the element polled from the queue (or ``null`` if none was
 *         available)
 */
gpointer
gee_queue_poll (GeeQueue* self)
{
	GeeQueueIface* _iface_;
	g_return_val_if_fail (self != NULL, NULL);
	_iface_ = GEE_QUEUE_GET_INTERFACE (self);
	if (_iface_->poll) {
		return _iface_->poll (self);
	}
	return NULL;
}

/**
 * Drains the specified amount of elements from this queue in the specified
 * recipient collection.
 *
 * @param recipient the recipient collection to drain the elements to
 * @param amount    the amount of elements to drain
 *
 * @return          the amount of elements that were actually drained
 */
static gint
gee_queue_real_drain (GeeQueue* self,
                      GeeCollection* recipient,
                      gint amount)
{
	gpointer item = NULL;
	gint drained = 0;
	gint result = 0;
	g_return_val_if_fail (recipient != NULL, 0);
	item = NULL;
	drained = 0;
	while (TRUE) {
		gboolean _tmp0_ = FALSE;
		gboolean _tmp1_ = FALSE;
		gconstpointer _tmp5_;
		gint _tmp6_;
		if (amount == -1) {
			_tmp1_ = TRUE;
		} else {
			gint _tmp2_;
			amount = amount - 1;
			_tmp2_ = amount;
			_tmp1_ = _tmp2_ >= 0;
		}
		if (_tmp1_) {
			gpointer _tmp3_;
			gconstpointer _tmp4_;
			_tmp3_ = gee_queue_poll (self);
			((item == NULL) || (GEE_QUEUE_GET_INTERFACE (self)->get_g_destroy_func (self) == NULL)) ? NULL : (item = (GEE_QUEUE_GET_INTERFACE (self)->get_g_destroy_func (self) (item), NULL));
			item = _tmp3_;
			_tmp4_ = item;
			_tmp0_ = _tmp4_ != NULL;
		} else {
			_tmp0_ = FALSE;
		}
		if (!_tmp0_) {
			break;
		}
		_tmp5_ = item;
		gee_collection_add (recipient, _tmp5_);
		_tmp6_ = drained;
		drained = _tmp6_ + 1;
	}
	result = drained;
	((item == NULL) || (GEE_QUEUE_GET_INTERFACE (self)->get_g_destroy_func (self) == NULL)) ? NULL : (item = (GEE_QUEUE_GET_INTERFACE (self)->get_g_destroy_func (self) (item), NULL));
	return result;
}

gint
gee_queue_drain (GeeQueue* self,
                 GeeCollection* recipient,
                 gint amount)
{
	GeeQueueIface* _iface_;
	g_return_val_if_fail (self != NULL, 0);
	_iface_ = GEE_QUEUE_GET_INTERFACE (self);
	if (_iface_->drain) {
		return _iface_->drain (self, recipient, amount);
	}
	return -1;
}

gint
gee_queue_get_capacity (GeeQueue* self)
{
	GeeQueueIface* _iface_;
	g_return_val_if_fail (self != NULL, 0);
	_iface_ = GEE_QUEUE_GET_INTERFACE (self);
	if (_iface_->get_capacity) {
		return _iface_->get_capacity (self);
	}
	return -1;
}

gint
gee_queue_get_remaining_capacity (GeeQueue* self)
{
	GeeQueueIface* _iface_;
	g_return_val_if_fail (self != NULL, 0);
	_iface_ = GEE_QUEUE_GET_INTERFACE (self);
	if (_iface_->get_remaining_capacity) {
		return _iface_->get_remaining_capacity (self);
	}
	return -1;
}

gboolean
gee_queue_get_is_full (GeeQueue* self)
{
	GeeQueueIface* _iface_;
	g_return_val_if_fail (self != NULL, FALSE);
	_iface_ = GEE_QUEUE_GET_INTERFACE (self);
	if (_iface_->get_is_full) {
		return _iface_->get_is_full (self);
	}
	return FALSE;
}

static void
gee_queue_default_init (GeeQueueIface * iface,
                        gpointer iface_data)
{
	/**
	 * The capacity of this queue (or ``UNBOUNDED_CAPACITY`` if capacity is not bound).
	 */
	g_object_interface_install_property (iface, g_param_spec_int ("capacity", "capacity", "capacity", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	/**
	 * The remaining capacity of this queue (or ``UNBOUNDED_CAPACITY`` if capacity is not
	 * bound).
	 */
	g_object_interface_install_property (iface, g_param_spec_int ("remaining-capacity", "remaining-capacity", "remaining-capacity", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	/**
	 * Specifies whether this queue is full.
	 */
	g_object_interface_install_property (iface, g_param_spec_boolean ("is-full", "is-full", "is-full", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	iface->offer = gee_queue_real_offer;
	iface->drain = gee_queue_real_drain;
}

/**
 * A collection designed for holding elements prior to processing.
 *
 * Although all Queue implementations do not limit the amount of elements they
 * can contain, this interface supports for capacity-bounded queues. When
 * capacity is not bound, then the {@link capacity} and
 * {@link remaining_capacity} both return {@link UNBOUNDED_CAPACITY}.
 *
 * This interface defines methods that will never fail whatever the state of
 * the queue is. For capacity-bounded queues, those methods will either return
 * ``false`` or ``null`` to specify that the insert or retrieval did not occur
 * because the queue was full or empty.
 *
 * Queue implementations are not limited to First-In-First-Out behavior and can
 * offer different orderings of their elements. Each Queue implementation must
 * specify how it orders its elements.
 *
 * Queue implementations do not allow insertion of ``null`` elements, although
 * some implementations, such as {@link LinkedList}, do not prohibit insertion
 * of ``null``. Even in the implementations that permit it, ``null`` should not be
 * inserted into a Queue, as ``null`` is also used as a special return value by
 * the poll method to indicate that the queue contains no elements.
 */
static GType
gee_queue_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GeeQueueIface), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gee_queue_default_init, (GClassFinalizeFunc) NULL, NULL, 0, 0, (GInstanceInitFunc) NULL, NULL };
	GType gee_queue_type_id;
	gee_queue_type_id = g_type_register_static (G_TYPE_INTERFACE, "GeeQueue", &g_define_type_info, 0);
	g_type_interface_add_prerequisite (gee_queue_type_id, GEE_TYPE_COLLECTION);
	return gee_queue_type_id;
}

GType
gee_queue_get_type (void)
{
	static volatile gsize gee_queue_type_id__volatile = 0;
	if (g_once_init_enter (&gee_queue_type_id__volatile)) {
		GType gee_queue_type_id;
		gee_queue_type_id = gee_queue_get_type_once ();
		g_once_init_leave (&gee_queue_type_id__volatile, gee_queue_type_id);
	}
	return gee_queue_type_id__volatile;
}

