/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
/*
 *  ianjuta-iterable.c -- Autogenerated from libanjuta.idl
 *
 *  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 2 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 Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

/**
 * SECTION:ianjuta-iterable
 * @title: IAnjutaIterable
 * @short_description: Implemented by objects that can iterate
 * @see_also:
 * @stability: Unstable
 * @include: libanjuta/interfaces/ianjuta-iterable.h
 *
 */

#include "ianjuta-iterable.h"
#include "libanjuta-iface-marshallers.h"

GQuark 
ianjuta_iterable_error_quark (void)
{
	static GQuark quark = 0;
	
	if (quark == 0) {
		quark = g_quark_from_static_string ("ianjuta-iterable-quark");
	}
	
	return quark;
}

/**
* ianjuta_iterable_assign:
* @obj: Self
* @src_iter: Source iter from which to copy the assignment.
* @err: Error propagation and reporting
*
* Assigns the iter position from @src_iter.
*
*/
void
ianjuta_iterable_assign (IAnjutaIterable *obj, IAnjutaIterable *src_iter, GError **err)
{
	g_return_if_fail (IANJUTA_IS_ITERABLE(obj));
	g_return_if_fail ((src_iter == NULL) ||IANJUTA_IS_ITERABLE(src_iter));
	IANJUTA_ITERABLE_GET_IFACE (obj)->assign (obj, src_iter, err);
}

/* Default implementation */
static void
ianjuta_iterable_assign_default (IAnjutaIterable *obj, IAnjutaIterable *src_iter, GError **err)
{
	g_return_if_reached ();
}

/**
 * ianjuta_iterable_clone:
 * @obj: Self
 * @err: Error propagation and reporting
 *
 * Clones the iterable. The returned iterable object must be unreffed
 * when done.
 *
 * Returns: (transfer full): A new instance of this iterable pointing at the same location.
 */
IAnjutaIterable *
ianjuta_iterable_clone (IAnjutaIterable *obj, GError **err)
{
	g_return_val_if_fail (IANJUTA_IS_ITERABLE(obj), NULL);
	return IANJUTA_ITERABLE_GET_IFACE (obj)->clone (obj, err);
}

/* Default implementation */
static IAnjutaIterable *
ianjuta_iterable_clone_default (IAnjutaIterable *obj, GError **err)
{
	g_return_val_if_reached (NULL);
}

/**
* ianjuta_iterable_compare:
* @obj: Self
* @iter2: Second iter to compare.
* @err: Error propagation and reporting
*
* Compares the position of @iter2 with this @obj. Returns -1
* value if this @obj is smaller than @iter2. Returns +1 value
* if this @obj is larger than @iter2. And returns 0 if both are equal.
* If you want difference of the iter positions, use
* #ianjuta_iterable_diff(). This method is meant for fast comparision.
*
* Returns: 0 if equal, -1 if @obj is smaller than @iter2
* or +1 if @obj is larger than @iter2.
*
*/
gint
ianjuta_iterable_compare (IAnjutaIterable *obj, IAnjutaIterable *iter2, GError **err)
{
	g_return_val_if_fail (IANJUTA_IS_ITERABLE(obj), -1);
	g_return_val_if_fail ((iter2 == NULL) ||IANJUTA_IS_ITERABLE(iter2), -1);
	return IANJUTA_ITERABLE_GET_IFACE (obj)->compare (obj, iter2, err);
}

/* Default implementation */
static gint
ianjuta_iterable_compare_default (IAnjutaIterable *obj, IAnjutaIterable *iter2, GError **err)
{
	g_return_val_if_reached (-1);
}

/**
* ianjuta_iterable_diff:
* @obj: Self
* @iter2: Second iter to differenciate.
* @err: Error propagation and reporting
*
* Compares the position of @iter2 with this @obj and returns difference
* in position of the two (@obj - @iter2).
*
* Returns: The position difference of @obj - @iter2
*
*/
gint
ianjuta_iterable_diff (IAnjutaIterable *obj, IAnjutaIterable *iter2, GError **err)
{
	g_return_val_if_fail (IANJUTA_IS_ITERABLE(obj), -1);
	g_return_val_if_fail ((iter2 == NULL) ||IANJUTA_IS_ITERABLE(iter2), -1);
	return IANJUTA_ITERABLE_GET_IFACE (obj)->diff (obj, iter2, err);
}

/* Default implementation */
static gint
ianjuta_iterable_diff_default (IAnjutaIterable *obj, IAnjutaIterable *iter2, GError **err)
{
	g_return_val_if_reached (-1);
}

/**
* ianjuta_iterable_first:
* @obj: Self
* @err: Error propagation and reporting
*
* Set iter to first element position. Returns FALSE if
* there is no element in the iterable (hence does not have first).
* The iter points to the first valid item.
*
* Returns: TRUE if sucessful, other FALSE.
*/
gboolean
ianjuta_iterable_first (IAnjutaIterable *obj, GError **err)
{
	g_return_val_if_fail (IANJUTA_IS_ITERABLE(obj), FALSE);
	return IANJUTA_ITERABLE_GET_IFACE (obj)->first (obj, err);
}

/* Default implementation */
static gboolean
ianjuta_iterable_first_default (IAnjutaIterable *obj, GError **err)
{
	g_return_val_if_reached (FALSE);
}

/**
* ianjuta_iterable_foreach:
* @obj: Self
* @callback: Callback to call for each element.
* @user_data: user data that is passed back to the callback.
* @err: Error propagation and reporting
*
* Call callback for each element in the list. Call back is passed the
* same iter, but with different position set (from first to last). This
* method does not affect current position. i.e. current position is
* restored at the end of this method.
*/
void
ianjuta_iterable_foreach (IAnjutaIterable *obj, GFunc callback,   gpointer user_data, GError **err)
{
	g_return_if_fail (IANJUTA_IS_ITERABLE(obj));
	g_return_if_fail (user_data != NULL);
	IANJUTA_ITERABLE_GET_IFACE (obj)->foreach (obj, callback, user_data, err);
}

/* Default implementation */
static void
ianjuta_iterable_foreach_default (IAnjutaIterable *obj, GFunc callback,   gpointer user_data, GError **err)
{
	g_return_if_reached ();
}

/**
* ianjuta_iterable_get_length:
* @obj: Self
* @err: Error propagation and reporting
*
* Length of the iterable (number of elements indexable by it).
*
* Returns: total length of the list.
*/
gint
ianjuta_iterable_get_length (IAnjutaIterable *obj, GError **err)
{
	g_return_val_if_fail (IANJUTA_IS_ITERABLE(obj), -1);
	return IANJUTA_ITERABLE_GET_IFACE (obj)->get_length (obj, err);
}

/* Default implementation */
static gint
ianjuta_iterable_get_length_default (IAnjutaIterable *obj, GError **err)
{
	g_return_val_if_reached (-1);
}

/**
* ianjuta_iterable_get_position:
* @obj: Self
* @err: Error propagation and reporting
*
* Index of the current iter in the iterable. It will be
* from 0 to length - 1 (ianjuta_iter_get_length()) if iter is pointed
* at valid element. It will return -1 if iter is pointed at end-iter.
*
* Returns: integer index, or -1 for end-iter.
*/
gint
ianjuta_iterable_get_position (IAnjutaIterable *obj, GError **err)
{
	g_return_val_if_fail (IANJUTA_IS_ITERABLE(obj), -1);
	return IANJUTA_ITERABLE_GET_IFACE (obj)->get_position (obj, err);
}

/* Default implementation */
static gint
ianjuta_iterable_get_position_default (IAnjutaIterable *obj, GError **err)
{
	g_return_val_if_reached (-1);
}

/**
* ianjuta_iterable_last:
* @obj: Self
* @err: Error propagation and reporting
*
* Set iter position to end-iter (one past last element) position.
* Returns FALSE if there is no element in the iterable (already
* at end-iter).
*
* Returns: TRUE if sucessful, other FALSE.
*/
gboolean
ianjuta_iterable_last (IAnjutaIterable *obj, GError **err)
{
	g_return_val_if_fail (IANJUTA_IS_ITERABLE(obj), FALSE);
	return IANJUTA_ITERABLE_GET_IFACE (obj)->last (obj, err);
}

/* Default implementation */
static gboolean
ianjuta_iterable_last_default (IAnjutaIterable *obj, GError **err)
{
	g_return_val_if_reached (FALSE);
}

/**
* ianjuta_iterable_next:
* @obj: Self
* @err: Error propagation and reporting
*
* Set the iter position to next element position. Iter can go until one
* item past the last item and lands in end-iter. end-iter does not point
* to any valid item and signifies end of the list. Returns FALSE if iter
* was already at end-iter (iter can not go past it) and remains pointed
* to the end-iter.
*
* Returns: TRUE if sucessful, otherwise FALSE if already at end-iter.
*/
gboolean
ianjuta_iterable_next (IAnjutaIterable *obj, GError **err)
{
	g_return_val_if_fail (IANJUTA_IS_ITERABLE(obj), FALSE);
	return IANJUTA_ITERABLE_GET_IFACE (obj)->next (obj, err);
}

/* Default implementation */
static gboolean
ianjuta_iterable_next_default (IAnjutaIterable *obj, GError **err)
{
	g_return_val_if_reached (FALSE);
}

/**
* ianjuta_iterable_previous:
* @obj: Self
* @err: Error propagation and reporting
*
* Set the iter position to previous element position. Returns FALSE if
* there is no previous element and the iter remains pointed to the first
* element.
*
* Returns: TRUE if sucessful, other FALSE.
*/
gboolean
ianjuta_iterable_previous (IAnjutaIterable *obj, GError **err)
{
	g_return_val_if_fail (IANJUTA_IS_ITERABLE(obj), FALSE);
	return IANJUTA_ITERABLE_GET_IFACE (obj)->previous (obj, err);
}

/* Default implementation */
static gboolean
ianjuta_iterable_previous_default (IAnjutaIterable *obj, GError **err)
{
	g_return_val_if_reached (FALSE);
}

/**
* ianjuta_iterable_set_position:
* @obj: Self
* @position: New position for the iter.
* @err: Error propagation and reporting
*
* Sets the current position of the iter to @position. The given @position
* must be from 0 to length - 1 (#ianjuta_iter_get_length()) to point to
* a valid element. Passing @position < 0 will set it to end-iter. It
* returns TRUE for the above cases. FLASE will be returned, if
* out-of-range @position is passed (@position > length - 1) and iter is
* set to end-iter.
*
* Returns: TRUE if successfully set (i.e. @position is within the range or
* end-iter). otherwise returns FALSE (i.e. @position is out of data range).
*/
gboolean
ianjuta_iterable_set_position (IAnjutaIterable *obj, gint position, GError **err)
{
	g_return_val_if_fail (IANJUTA_IS_ITERABLE(obj), FALSE);
	return IANJUTA_ITERABLE_GET_IFACE (obj)->set_position (obj, position, err);
}

/* Default implementation */
static gboolean
ianjuta_iterable_set_position_default (IAnjutaIterable *obj, gint position, GError **err)
{
	g_return_val_if_reached (FALSE);
}

static void
ianjuta_iterable_base_init (IAnjutaIterableIface* klass)
{
	static gboolean initialized = FALSE;

	klass->assign = ianjuta_iterable_assign_default;
	klass->clone = ianjuta_iterable_clone_default;
	klass->compare = ianjuta_iterable_compare_default;
	klass->diff = ianjuta_iterable_diff_default;
	klass->first = ianjuta_iterable_first_default;
	klass->foreach = ianjuta_iterable_foreach_default;
	klass->get_length = ianjuta_iterable_get_length_default;
	klass->get_position = ianjuta_iterable_get_position_default;
	klass->last = ianjuta_iterable_last_default;
	klass->next = ianjuta_iterable_next_default;
	klass->previous = ianjuta_iterable_previous_default;
	klass->set_position = ianjuta_iterable_set_position_default;
	
	if (!initialized) {

		initialized = TRUE;
	}
}

GType
ianjuta_iterable_get_type (void)
{
	static GType type = 0;
	if (!type) {
		static const GTypeInfo info = {
			sizeof (IAnjutaIterableIface),
			(GBaseInitFunc) ianjuta_iterable_base_init,
			NULL, 
			NULL,
			NULL,
			NULL,
			0,
			0,
			NULL
		};
		type = g_type_register_static (G_TYPE_INTERFACE, "IAnjutaIterable", &info, 0);
		g_type_interface_add_prerequisite (type, G_TYPE_OBJECT);
	}
	return type;			
}
