### ----------------------------------------------------
### -- Gnome::Glib
### -- Licenses: Artistic-2.0
### -- Authors: Marcel Timmerman
### -- File: lib/Gnome/Glib/List.rakumod
### ----------------------------------------------------
### -- Chunk 2 of 2
:1:position:
=begin pod
=head2 position

Gets the position of the given element in the B<Gnome::Glib::List> (starting from 0).

Returns: the position of the element in the B<Gnome::Glib::List>, or -1 if the element is not found

  method position ( N-GList $llink --> Int )

=item N-GList $llink; an element in the B<Gnome::Glib::List>
=end pod

method position ( $llink is copy --> Int ) {
  $llink .= _get-native-object-no-reffing unless $llink ~~ N-GList;
  g_list_position( self._get-native-object-no-reffing, $llink)
}

sub g_list_position (
  N-GList $list, N-GList $llink --> gint
) is native(&glib-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:1:prepend:
=begin pod
=head2 prepend

Prepends a new element on to the start of the list.

Note that the return value is the new start of the list, which will have changed, so make sure you store the new value. Do not use this function to prepend a new element to a different element than the start of the list. (Note; probably the list before insertion point gets cut off and then there is a memory leak). Use C<g-list-insert-before()> instead.

Returns: a pointer to the newly prepended element, which is the new start of the B<Gnome::Glib::List>

  method prepend ( Pointer $data --> Gnome::Glib::List )

=item Pointer $data; the data for the new element

=head3 Example

  my Gnome::Glib::List $list .= new;

  $list .= prepend(CArray[Str].new("last"));
  $list .= prepend(CArray[Str].new("first"));

=end pod

method prepend ( Pointer $data --> Gnome::Glib::List ) {
  Gnome::Glib::List.new(
    :native-object(g_list_prepend( self._get-native-object-no-reffing, $data))
  )
}

sub g_list_prepend (
  N-GList $list, gpointer $data --> N-GList
) is native(&glib-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:1:previous:
=begin pod
=head2 previous

Gets the previous element in a B<Gnome::Glib::List>, or C<invalif> if the B<Gnome::Glib::List> is at the beginning of the list.

  method previous ( --> Gnome::Glib::List )

=end pod

method previous ( --> Gnome::Glib::List ) {
  Gnome::Glib::List.new(
    :native-object(self._get-native-object-no-reffing.prev // N-GList)
  );
}

#-------------------------------------------------------------------------------
#TM:1:remove:
=begin pod
=head2 remove

Removes an element from a B<Gnome::Glib::List>. If two elements contain the same data, only the first is removed. If none of the elements contain the data, the B<Gnome::Glib::List> is unchanged.

Returns: the (possibly changed) start of the B<Gnome::Glib::List>

  method remove ( Pointer $data --> Gnome::Glib::List )

=item Pointer $data; the data of the element to remove
=end pod

method remove ( Pointer $data --> Gnome::Glib::List ) {
  Gnome::Glib::List.new(
    :native-object(
      g_list_remove( self._get-native-object-no-reffing, $data) // N-GList
    )
  )
}

sub g_list_remove (
  N-GList $list, gpointer $data --> N-GList
) is native(&glib-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:1:remove-all:
=begin pod
=head2 remove-all

Removes all list nodes with data equal to I<data>. Returns the new head of the list. Contrast with C<remove()> which removes only the first node matching the given data.

Returns: the (possibly changed) start of the B<Gnome::Glib::List>

  method remove-all ( Pointer $data --> Gnome::Glib::List )

=item Pointer $data; data to remove
=end pod

method remove-all ( Pointer $data --> Gnome::Glib::List ) {
  Gnome::Glib::List.new(
    :native-object(
      g_list_remove_all( self._get-native-object-no-reffing, $data) // N-GList
    )
  )
}

sub g_list_remove_all (
  N-GList $list, gpointer $data --> N-GList
) is native(&glib-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:1:remove-link:
=begin pod
=head2 remove-link

Removes an element from a B<Gnome::Glib::List>, without freeing the element. The removed element's prev and next links are set to C<invalid>, so that it becomes a self-contained list with one element.

This function is for example used to move an element in the list (see the example for C<concat()>) or to remove an element in the list before freeing its data.
=begin comment
  list = g-list-remove-link (list, llink);
  free-some-data-that-may-access-the-list-again (llink->data);
  g-list-free (llink);
=end comment

Returns: the (possibly changed) start of the B<Gnome::Glib::List>

  method remove-link ( N-GList $llink --> Gnome::Glib::List )

=item N-GList $llink; an element in the B<Gnome::Glib::List>
=end pod

method remove-link ( $llink is copy --> Gnome::Glib::List ) {
  $llink .= _get-native-object-no-reffing unless $llink ~~ N-GList;

  Gnome::Glib::List.new(
    :native-object(
      g_list_remove_link( self._get-native-object-no-reffing, $llink) // N-GList
    )
  )
}

sub g_list_remove_link (
  N-GList $list, N-GList $llink --> N-GList
) is native(&glib-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:1:reverse:
=begin pod
=head2 reverse

Reverses a B<Gnome::Glib::List>. It simply switches the next and prev pointers of each element.

Returns: the start of the reversed B<Gnome::Glib::List>

  method reverse ( --> Gnome::Glib::List )

=end pod

method reverse ( --> Gnome::Glib::List ) {
  Gnome::Glib::List.new(
    :native-object(
      g_list_reverse(self._get-native-object-no-reffing) // N-GList
    )
  )
}

sub g_list_reverse (
  N-GList $list --> N-GList
) is native(&glib-lib)
  { * }

#-------------------------------------------------------------------------------
#TM:1:sort:
=begin pod
=head2 sort

Sorts a B<Gnome::Glib::List> using the given comparison function. The algorithm used is a stable sort.

Returns: the (possibly changed) start of the B<Gnome::Glib::List>

  method sort (
    Any:D $user-object, Str:D $method
    --> Gnome::Glib::List
  )

=item $user-object is object wherein the compare method is defined.
=item $method is the the comparison function used to sort the B<Gnome::Glib::List>. This function is passed the data from 2 elements of the B<Gnome::Glib::List>  and should return 0 if they are equal, a negative value if the first element comes before the second, or a positive value if the first element comes after the second.

The method must be defined as follows;

  method compare-handler ( Pointer $a, Pointer $b --> int )

The method must return -1 when $a is less than $b, 0 when equal or 1 when $a is greater than $b.

=end pod

method sort (
  Any:D $user-object, Str:D $method, *%user-data
  --> Gnome::Glib::List
) {
  die X::Gnome.new(:message("User object and/or method $method not found"))
    unless $user-object.^can($method);

  Gnome::Glib::List.new(
    :native-object(
      g_list_sort(
        self._get-native-object-no-reffing,
        sub ( gpointer $a, gpointer $b --> gint ) {
          $user-object."$method"( $a, $b)
        }
      )
    )
  )
}

sub g_list_sort (
  N-GList $list, Callable $compare_func ( gpointer $a, gpointer $b --> gint )
  --> N-GList
) is native(&glib-lib)
  { * }


#`{{ No need because of use of *%user-data in g_list_sort()
#-------------------------------------------------------------------------------
# TM:0:sort-with-data:
=begin pod
=head2 sort-with-data

Like C<sort()>, but the comparison function accepts a user data argument.

Returns: the (possibly changed) start of the B<Gnome::Glib::List>

  method sort-with-data ( GCompareDataFunc $compare_func, Pointer $user_data --> N-GList )

=item GCompareDataFunc $compare_func; comparison function
=item Pointer $user_data; user data to pass to comparison function
=end pod

method sort-with-data ( GCompareDataFunc $compare_func, Pointer $user_data --> N-GList ) {

  g_list_sort_with_data(
    self._get-native-object-no-reffing, $compare_func, $user_data
  )
}

sub g_list_sort_with_data (
  N-GList $list, GCompareDataFunc $compare_func, gpointer $user_data --> N-GList
) is native(&glib-lib)
  { * }
}}


