/* GIMP - The GNU Image Manipulation Program
 * Copyright (C) 1995-2003 Spencer Kimball and Peter Mattis
 *
 * 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 <https://www.gnu.org/licenses/>.
 */

/* NOTE: This file is auto-generated by pdbgen.pl. */

#include "config.h"

#include <cairo.h>
#include <string.h>

#include <gegl.h>

#include <gdk-pixbuf/gdk-pixbuf.h>

#include "libgimpcolor/gimpcolor.h"

#include "libgimpbase/gimpbase.h"

#include "pdb-types.h"

#include "core/gimp.h"
#include "core/gimpcontext.h"
#include "core/gimpdatafactory.h"
#include "core/gimpgradient.h"
#include "core/gimpparamspecs.h"

#include "gimppdb.h"
#include "gimppdb-utils.h"
#include "gimpprocedure.h"
#include "internal-procs.h"


static GimpGradient *
gradient_get (Gimp                 *gimp,
              const gchar          *name,
              GimpPDBDataAccess     access,
              gint                  segment,
              GimpGradientSegment **seg,
              GError              **error)
{
  GimpGradient *gradient = gimp_pdb_get_gradient (gimp, name, access, error);

  *seg = NULL;

  if (gradient)
    *seg = gimp_gradient_segment_get_nth (gradient->segments, segment);

  return gradient;
}

static GimpGradient *
gradient_get_range (Gimp                 *gimp,
                    const gchar          *name,
                    gint                  start_segment,
                    gint                  end_segment,
                    GimpGradientSegment **start_seg,
                    GimpGradientSegment **end_seg,
                    GError              **error)
{
  GimpGradient *gradient = gimp_pdb_get_gradient (gimp, name, GIMP_PDB_DATA_ACCESS_WRITE, error);

  *start_seg = NULL;
  *end_seg   = NULL;

  if (end_segment >= 0 && end_segment < start_segment)
    return NULL;

  if (gradient)
    {
      *start_seg = gimp_gradient_segment_get_nth (gradient->segments,
                                                  start_segment);

      if (*start_seg && end_segment >= 0)
        *end_seg = gimp_gradient_segment_get_nth (*start_seg,
                                                  end_segment -
                                                  start_segment);
    }

  return gradient;
}

static GimpValueArray *
gradient_new_invoker (GimpProcedure         *procedure,
                      Gimp                  *gimp,
                      GimpContext           *context,
                      GimpProgress          *progress,
                      const GimpValueArray  *args,
                      GError               **error)
{
  gboolean success = TRUE;
  GimpValueArray *return_vals;
  const gchar *name;
  gchar *actual_name = NULL;

  name = g_value_get_string (gimp_value_array_index (args, 0));

  if (success)
    {
      GimpData *data = gimp_data_factory_data_new (gimp->gradient_factory,
                                                   context, name);

      if (data)
        actual_name = g_strdup (gimp_object_get_name (data));
      else
        success = FALSE;
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    g_value_take_string (gimp_value_array_index (return_vals, 1), actual_name);

  return return_vals;
}

static GimpValueArray *
gradient_duplicate_invoker (GimpProcedure         *procedure,
                            Gimp                  *gimp,
                            GimpContext           *context,
                            GimpProgress          *progress,
                            const GimpValueArray  *args,
                            GError               **error)
{
  gboolean success = TRUE;
  GimpValueArray *return_vals;
  const gchar *name;
  gchar *copy_name = NULL;

  name = g_value_get_string (gimp_value_array_index (args, 0));

  if (success)
    {
      GimpGradient *gradient = gimp_pdb_get_gradient (gimp, name, GIMP_PDB_DATA_ACCESS_READ, error);

      if (gradient)
        {
          GimpGradient *gradient_copy = (GimpGradient *)
            gimp_data_factory_data_duplicate (gimp->gradient_factory,
                                              GIMP_DATA (gradient));

          if (gradient_copy)
            copy_name = g_strdup (gimp_object_get_name (gradient_copy));
          else
            success = FALSE;
        }
      else
        success = FALSE;
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    g_value_take_string (gimp_value_array_index (return_vals, 1), copy_name);

  return return_vals;
}

static GimpValueArray *
gradient_is_editable_invoker (GimpProcedure         *procedure,
                              Gimp                  *gimp,
                              GimpContext           *context,
                              GimpProgress          *progress,
                              const GimpValueArray  *args,
                              GError               **error)
{
  gboolean success = TRUE;
  GimpValueArray *return_vals;
  const gchar *name;
  gboolean editable = FALSE;

  name = g_value_get_string (gimp_value_array_index (args, 0));

  if (success)
    {
      GimpGradient *gradient = gimp_pdb_get_gradient (gimp, name, GIMP_PDB_DATA_ACCESS_READ, error);

      if (gradient)
        editable = gimp_data_is_writable (GIMP_DATA (gradient));
      else
        success = FALSE;
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    g_value_set_boolean (gimp_value_array_index (return_vals, 1), editable);

  return return_vals;
}

static GimpValueArray *
gradient_rename_invoker (GimpProcedure         *procedure,
                         Gimp                  *gimp,
                         GimpContext           *context,
                         GimpProgress          *progress,
                         const GimpValueArray  *args,
                         GError               **error)
{
  gboolean success = TRUE;
  GimpValueArray *return_vals;
  const gchar *name;
  const gchar *new_name;
  gchar *actual_name = NULL;

  name = g_value_get_string (gimp_value_array_index (args, 0));
  new_name = g_value_get_string (gimp_value_array_index (args, 1));

  if (success)
    {
      GimpGradient *gradient = gimp_pdb_get_gradient (gimp, name, GIMP_PDB_DATA_ACCESS_RENAME, error);

      if (gradient)
        {
          gimp_object_set_name (GIMP_OBJECT (gradient), new_name);
          actual_name = g_strdup (gimp_object_get_name (gradient));
        }
      else
        success = FALSE;
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    g_value_take_string (gimp_value_array_index (return_vals, 1), actual_name);

  return return_vals;
}

static GimpValueArray *
gradient_delete_invoker (GimpProcedure         *procedure,
                         Gimp                  *gimp,
                         GimpContext           *context,
                         GimpProgress          *progress,
                         const GimpValueArray  *args,
                         GError               **error)
{
  gboolean success = TRUE;
  const gchar *name;

  name = g_value_get_string (gimp_value_array_index (args, 0));

  if (success)
    {
      GimpGradient *gradient = gimp_pdb_get_gradient (gimp, name, GIMP_PDB_DATA_ACCESS_READ, error);

      if (gradient && gimp_data_is_deletable (GIMP_DATA (gradient)))
        success = gimp_data_factory_data_delete (gimp->gradient_factory,
                                                 GIMP_DATA (gradient),
                                                 TRUE, error);
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
gradient_get_number_of_segments_invoker (GimpProcedure         *procedure,
                                         Gimp                  *gimp,
                                         GimpContext           *context,
                                         GimpProgress          *progress,
                                         const GimpValueArray  *args,
                                         GError               **error)
{
  gboolean success = TRUE;
  GimpValueArray *return_vals;
  const gchar *name;
  gint32 num_segments = 0;

  name = g_value_get_string (gimp_value_array_index (args, 0));

  if (success)
    {
      GimpGradient        *gradient;
      GimpGradientSegment *seg;

      gradient = gimp_pdb_get_gradient (gimp, name, GIMP_PDB_DATA_ACCESS_READ, error);

      if (gradient)
        {
          for (seg = gradient->segments; seg; seg = seg->next)
            num_segments++;
        }
      else
        success = FALSE;
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    g_value_set_int (gimp_value_array_index (return_vals, 1), num_segments);

  return return_vals;
}

static GimpValueArray *
gradient_get_uniform_samples_invoker (GimpProcedure         *procedure,
                                      Gimp                  *gimp,
                                      GimpContext           *context,
                                      GimpProgress          *progress,
                                      const GimpValueArray  *args,
                                      GError               **error)
{
  gboolean success = TRUE;
  GimpValueArray *return_vals;
  const gchar *name;
  gint32 num_samples;
  gboolean reverse;
  gint32 num_color_samples = 0;
  gdouble *color_samples = NULL;

  name = g_value_get_string (gimp_value_array_index (args, 0));
  num_samples = g_value_get_int (gimp_value_array_index (args, 1));
  reverse = g_value_get_boolean (gimp_value_array_index (args, 2));

  if (success)
    {
      GimpGradient *gradient = gimp_pdb_get_gradient (gimp, name,
                                                      GIMP_PDB_DATA_ACCESS_READ,
                                                      error);

      if (gradient)
        {
          GimpGradientSegment *seg   = NULL;
          gdouble              pos   = 0.0;
          gdouble              delta = 1.0 / (num_samples - 1);
          gdouble             *sample;

          num_color_samples = num_samples * 4;

          sample = color_samples = g_new (gdouble, num_color_samples);

          while (num_samples--)
            {
              GimpRGB color;

              seg = gimp_gradient_get_color_at (gradient, context, seg,
                                                pos, reverse,
                                                GIMP_GRADIENT_BLEND_RGB_PERCEPTUAL,
                                                &color);

              *sample++ = color.r;
              *sample++ = color.g;
              *sample++ = color.b;
              *sample++ = color.a;

              pos += delta;
            }
        }
      else
        success = FALSE;
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    {
      g_value_set_int (gimp_value_array_index (return_vals, 1), num_color_samples);
      gimp_value_take_floatarray (gimp_value_array_index (return_vals, 2), color_samples, num_color_samples);
    }

  return return_vals;
}

static GimpValueArray *
gradient_get_custom_samples_invoker (GimpProcedure         *procedure,
                                     Gimp                  *gimp,
                                     GimpContext           *context,
                                     GimpProgress          *progress,
                                     const GimpValueArray  *args,
                                     GError               **error)
{
  gboolean success = TRUE;
  GimpValueArray *return_vals;
  const gchar *name;
  gint32 num_samples;
  const gdouble *positions;
  gboolean reverse;
  gint32 num_color_samples = 0;
  gdouble *color_samples = NULL;

  name = g_value_get_string (gimp_value_array_index (args, 0));
  num_samples = g_value_get_int (gimp_value_array_index (args, 1));
  positions = gimp_value_get_floatarray (gimp_value_array_index (args, 2));
  reverse = g_value_get_boolean (gimp_value_array_index (args, 3));

  if (success)
    {
      GimpGradient *gradient = gimp_pdb_get_gradient (gimp, name,
                                                      GIMP_PDB_DATA_ACCESS_READ,
                                                      error);

      if (gradient)
        {
          GimpGradientSegment *seg = NULL;
          gdouble             *sample;

          num_color_samples = num_samples * 4;

          sample = color_samples = g_new (gdouble, num_color_samples);

          while (num_samples--)
            {
              GimpRGB color;

              seg = gimp_gradient_get_color_at (gradient, context,
                                                seg, *positions,
                                                reverse,
                                                GIMP_GRADIENT_BLEND_RGB_PERCEPTUAL,
                                                &color);

              *sample++ = color.r;
              *sample++ = color.g;
              *sample++ = color.b;
              *sample++ = color.a;

              positions++;
            }
        }
      else
        success = FALSE;
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    {
      g_value_set_int (gimp_value_array_index (return_vals, 1), num_color_samples);
      gimp_value_take_floatarray (gimp_value_array_index (return_vals, 2), color_samples, num_color_samples);
    }

  return return_vals;
}

static GimpValueArray *
gradient_segment_get_left_color_invoker (GimpProcedure         *procedure,
                                         Gimp                  *gimp,
                                         GimpContext           *context,
                                         GimpProgress          *progress,
                                         const GimpValueArray  *args,
                                         GError               **error)
{
  gboolean success = TRUE;
  GimpValueArray *return_vals;
  const gchar *name;
  gint32 segment;
  GimpRGB color = { 0.0, 0.0, 0.0, 1.0 };
  gdouble opacity = 0.0;

  name = g_value_get_string (gimp_value_array_index (args, 0));
  segment = g_value_get_int (gimp_value_array_index (args, 1));

  if (success)
    {
      GimpGradient        *gradient;
      GimpGradientSegment *seg;

      gradient = gradient_get (gimp, name, GIMP_PDB_DATA_ACCESS_READ, segment,
                               &seg, error);

      if (seg)
        {
          gimp_gradient_segment_get_left_color (gradient, seg, &color);
          opacity = color.a * 100.0;
        }
      else
        success = FALSE;
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    {
      gimp_value_set_rgb (gimp_value_array_index (return_vals, 1), &color);
      g_value_set_double (gimp_value_array_index (return_vals, 2), opacity);
    }

  return return_vals;
}

static GimpValueArray *
gradient_segment_set_left_color_invoker (GimpProcedure         *procedure,
                                         Gimp                  *gimp,
                                         GimpContext           *context,
                                         GimpProgress          *progress,
                                         const GimpValueArray  *args,
                                         GError               **error)
{
  gboolean success = TRUE;
  const gchar *name;
  gint32 segment;
  GimpRGB color;
  gdouble opacity;

  name = g_value_get_string (gimp_value_array_index (args, 0));
  segment = g_value_get_int (gimp_value_array_index (args, 1));
  gimp_value_get_rgb (gimp_value_array_index (args, 2), &color);
  opacity = g_value_get_double (gimp_value_array_index (args, 3));

  if (success)
    {
      GimpGradient        *gradient;
      GimpGradientSegment *seg;

      gradient = gradient_get (gimp, name, GIMP_PDB_DATA_ACCESS_WRITE, segment,
                               &seg, error);

      if (seg)
        {
          color.a = opacity / 100.0;
          gimp_gradient_segment_set_left_color (gradient, seg, &color);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
gradient_segment_get_right_color_invoker (GimpProcedure         *procedure,
                                          Gimp                  *gimp,
                                          GimpContext           *context,
                                          GimpProgress          *progress,
                                          const GimpValueArray  *args,
                                          GError               **error)
{
  gboolean success = TRUE;
  GimpValueArray *return_vals;
  const gchar *name;
  gint32 segment;
  GimpRGB color = { 0.0, 0.0, 0.0, 1.0 };
  gdouble opacity = 0.0;

  name = g_value_get_string (gimp_value_array_index (args, 0));
  segment = g_value_get_int (gimp_value_array_index (args, 1));

  if (success)
    {
      GimpGradient        *gradient;
      GimpGradientSegment *seg;

      gradient = gradient_get (gimp, name, GIMP_PDB_DATA_ACCESS_READ, segment,
                               &seg, error);

      if (seg)
        {
          gimp_gradient_segment_get_right_color (gradient, seg, &color);
          opacity = color.a * 100.0;
        }
      else
        success = FALSE;
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    {
      gimp_value_set_rgb (gimp_value_array_index (return_vals, 1), &color);
      g_value_set_double (gimp_value_array_index (return_vals, 2), opacity);
    }

  return return_vals;
}

static GimpValueArray *
gradient_segment_set_right_color_invoker (GimpProcedure         *procedure,
                                          Gimp                  *gimp,
                                          GimpContext           *context,
                                          GimpProgress          *progress,
                                          const GimpValueArray  *args,
                                          GError               **error)
{
  gboolean success = TRUE;
  const gchar *name;
  gint32 segment;
  GimpRGB color;
  gdouble opacity;

  name = g_value_get_string (gimp_value_array_index (args, 0));
  segment = g_value_get_int (gimp_value_array_index (args, 1));
  gimp_value_get_rgb (gimp_value_array_index (args, 2), &color);
  opacity = g_value_get_double (gimp_value_array_index (args, 3));

  if (success)
    {
      GimpGradient        *gradient;
      GimpGradientSegment *seg;

      gradient = gradient_get (gimp, name, GIMP_PDB_DATA_ACCESS_WRITE, segment,
                               &seg, error);

      if (seg)
        {
          color.a = opacity / 100.0;
          gimp_gradient_segment_set_right_color (gradient, seg, &color);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
gradient_segment_get_left_pos_invoker (GimpProcedure         *procedure,
                                       Gimp                  *gimp,
                                       GimpContext           *context,
                                       GimpProgress          *progress,
                                       const GimpValueArray  *args,
                                       GError               **error)
{
  gboolean success = TRUE;
  GimpValueArray *return_vals;
  const gchar *name;
  gint32 segment;
  gdouble pos = 0.0;

  name = g_value_get_string (gimp_value_array_index (args, 0));
  segment = g_value_get_int (gimp_value_array_index (args, 1));

  if (success)
    {
      GimpGradient        *gradient;
      GimpGradientSegment *seg;

      gradient = gradient_get (gimp, name, GIMP_PDB_DATA_ACCESS_READ, segment,
                               &seg, error);

      if (seg)
        {
          pos = gimp_gradient_segment_get_left_pos (gradient, seg);
        }
      else
        success = FALSE;
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    g_value_set_double (gimp_value_array_index (return_vals, 1), pos);

  return return_vals;
}

static GimpValueArray *
gradient_segment_set_left_pos_invoker (GimpProcedure         *procedure,
                                       Gimp                  *gimp,
                                       GimpContext           *context,
                                       GimpProgress          *progress,
                                       const GimpValueArray  *args,
                                       GError               **error)
{
  gboolean success = TRUE;
  GimpValueArray *return_vals;
  const gchar *name;
  gint32 segment;
  gdouble pos;
  gdouble final_pos = 0.0;

  name = g_value_get_string (gimp_value_array_index (args, 0));
  segment = g_value_get_int (gimp_value_array_index (args, 1));
  pos = g_value_get_double (gimp_value_array_index (args, 2));

  if (success)
    {
      GimpGradient        *gradient;
      GimpGradientSegment *seg;

      gradient = gradient_get (gimp, name, GIMP_PDB_DATA_ACCESS_WRITE, segment,
                               &seg, error);

      if (seg)
        {
          final_pos = gimp_gradient_segment_set_left_pos (gradient, seg, pos);
        }
      else
        success = FALSE;
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    g_value_set_double (gimp_value_array_index (return_vals, 1), final_pos);

  return return_vals;
}

static GimpValueArray *
gradient_segment_get_middle_pos_invoker (GimpProcedure         *procedure,
                                         Gimp                  *gimp,
                                         GimpContext           *context,
                                         GimpProgress          *progress,
                                         const GimpValueArray  *args,
                                         GError               **error)
{
  gboolean success = TRUE;
  GimpValueArray *return_vals;
  const gchar *name;
  gint32 segment;
  gdouble pos = 0.0;

  name = g_value_get_string (gimp_value_array_index (args, 0));
  segment = g_value_get_int (gimp_value_array_index (args, 1));

  if (success)
    {
      GimpGradient        *gradient;
      GimpGradientSegment *seg;

      gradient = gradient_get (gimp, name, GIMP_PDB_DATA_ACCESS_READ, segment,
                               &seg, error);

      if (seg)
        {
          pos = gimp_gradient_segment_get_middle_pos (gradient, seg);
        }
      else
        success = FALSE;
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    g_value_set_double (gimp_value_array_index (return_vals, 1), pos);

  return return_vals;
}

static GimpValueArray *
gradient_segment_set_middle_pos_invoker (GimpProcedure         *procedure,
                                         Gimp                  *gimp,
                                         GimpContext           *context,
                                         GimpProgress          *progress,
                                         const GimpValueArray  *args,
                                         GError               **error)
{
  gboolean success = TRUE;
  GimpValueArray *return_vals;
  const gchar *name;
  gint32 segment;
  gdouble pos;
  gdouble final_pos = 0.0;

  name = g_value_get_string (gimp_value_array_index (args, 0));
  segment = g_value_get_int (gimp_value_array_index (args, 1));
  pos = g_value_get_double (gimp_value_array_index (args, 2));

  if (success)
    {
      GimpGradient        *gradient;
      GimpGradientSegment *seg;

      gradient = gradient_get (gimp, name, GIMP_PDB_DATA_ACCESS_WRITE, segment,
                               &seg, error);

      if (seg)
        {
          final_pos =
            gimp_gradient_segment_set_middle_pos (gradient, seg, pos);
        }
      else
        success = FALSE;
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    g_value_set_double (gimp_value_array_index (return_vals, 1), final_pos);

  return return_vals;
}

static GimpValueArray *
gradient_segment_get_right_pos_invoker (GimpProcedure         *procedure,
                                        Gimp                  *gimp,
                                        GimpContext           *context,
                                        GimpProgress          *progress,
                                        const GimpValueArray  *args,
                                        GError               **error)
{
  gboolean success = TRUE;
  GimpValueArray *return_vals;
  const gchar *name;
  gint32 segment;
  gdouble pos = 0.0;

  name = g_value_get_string (gimp_value_array_index (args, 0));
  segment = g_value_get_int (gimp_value_array_index (args, 1));

  if (success)
    {
      GimpGradient        *gradient;
      GimpGradientSegment *seg;

      gradient = gradient_get (gimp, name, GIMP_PDB_DATA_ACCESS_READ, segment,
                               &seg, error);

      if (seg)
        {
          pos = gimp_gradient_segment_get_right_pos (gradient, seg);
        }
      else
        success = FALSE;
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    g_value_set_double (gimp_value_array_index (return_vals, 1), pos);

  return return_vals;
}

static GimpValueArray *
gradient_segment_set_right_pos_invoker (GimpProcedure         *procedure,
                                        Gimp                  *gimp,
                                        GimpContext           *context,
                                        GimpProgress          *progress,
                                        const GimpValueArray  *args,
                                        GError               **error)
{
  gboolean success = TRUE;
  GimpValueArray *return_vals;
  const gchar *name;
  gint32 segment;
  gdouble pos;
  gdouble final_pos = 0.0;

  name = g_value_get_string (gimp_value_array_index (args, 0));
  segment = g_value_get_int (gimp_value_array_index (args, 1));
  pos = g_value_get_double (gimp_value_array_index (args, 2));

  if (success)
    {
      GimpGradient        *gradient;
      GimpGradientSegment *seg;

      gradient = gradient_get (gimp, name, GIMP_PDB_DATA_ACCESS_WRITE, segment,
                               &seg, error);

      if (seg)
        {
          final_pos =
            gimp_gradient_segment_set_right_pos (gradient, seg, pos);
        }
      else
        success = FALSE;
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    g_value_set_double (gimp_value_array_index (return_vals, 1), final_pos);

  return return_vals;
}

static GimpValueArray *
gradient_segment_get_blending_function_invoker (GimpProcedure         *procedure,
                                                Gimp                  *gimp,
                                                GimpContext           *context,
                                                GimpProgress          *progress,
                                                const GimpValueArray  *args,
                                                GError               **error)
{
  gboolean success = TRUE;
  GimpValueArray *return_vals;
  const gchar *name;
  gint32 segment;
  gint32 blend_func = 0;

  name = g_value_get_string (gimp_value_array_index (args, 0));
  segment = g_value_get_int (gimp_value_array_index (args, 1));

  if (success)
    {
      GimpGradient        *gradient;
      GimpGradientSegment *seg;

      gradient = gradient_get (gimp, name, GIMP_PDB_DATA_ACCESS_READ, segment,
                               &seg, error);

      if (seg)
        {
          blend_func = gimp_gradient_segment_get_blending_function (gradient, seg);
        }
      else
        success = FALSE;
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    g_value_set_enum (gimp_value_array_index (return_vals, 1), blend_func);

  return return_vals;
}

static GimpValueArray *
gradient_segment_get_coloring_type_invoker (GimpProcedure         *procedure,
                                            Gimp                  *gimp,
                                            GimpContext           *context,
                                            GimpProgress          *progress,
                                            const GimpValueArray  *args,
                                            GError               **error)
{
  gboolean success = TRUE;
  GimpValueArray *return_vals;
  const gchar *name;
  gint32 segment;
  gint32 coloring_type = 0;

  name = g_value_get_string (gimp_value_array_index (args, 0));
  segment = g_value_get_int (gimp_value_array_index (args, 1));

  if (success)
    {
      GimpGradient        *gradient;
      GimpGradientSegment *seg;

      gradient = gradient_get (gimp, name, GIMP_PDB_DATA_ACCESS_READ, segment,
                               &seg, error);

      if (seg)
        {
          coloring_type = gimp_gradient_segment_get_coloring_type (gradient, seg);
        }
      else
        success = FALSE;
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    g_value_set_enum (gimp_value_array_index (return_vals, 1), coloring_type);

  return return_vals;
}

static GimpValueArray *
gradient_segment_range_set_blending_function_invoker (GimpProcedure         *procedure,
                                                      Gimp                  *gimp,
                                                      GimpContext           *context,
                                                      GimpProgress          *progress,
                                                      const GimpValueArray  *args,
                                                      GError               **error)
{
  gboolean success = TRUE;
  const gchar *name;
  gint32 start_segment;
  gint32 end_segment;
  gint32 blending_function;

  name = g_value_get_string (gimp_value_array_index (args, 0));
  start_segment = g_value_get_int (gimp_value_array_index (args, 1));
  end_segment = g_value_get_int (gimp_value_array_index (args, 2));
  blending_function = g_value_get_enum (gimp_value_array_index (args, 3));

  if (success)
    {
      GimpGradient        *gradient;
      GimpGradientSegment *start_seg;
      GimpGradientSegment *end_seg;

      gradient = gradient_get_range (gimp, name, start_segment, end_segment,
                                     &start_seg, &end_seg, error);

      if (start_seg)
        {
          gimp_gradient_segment_range_set_blending_function (gradient,
                                                             start_seg, end_seg,
                                                             blending_function);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
gradient_segment_range_set_coloring_type_invoker (GimpProcedure         *procedure,
                                                  Gimp                  *gimp,
                                                  GimpContext           *context,
                                                  GimpProgress          *progress,
                                                  const GimpValueArray  *args,
                                                  GError               **error)
{
  gboolean success = TRUE;
  const gchar *name;
  gint32 start_segment;
  gint32 end_segment;
  gint32 coloring_type;

  name = g_value_get_string (gimp_value_array_index (args, 0));
  start_segment = g_value_get_int (gimp_value_array_index (args, 1));
  end_segment = g_value_get_int (gimp_value_array_index (args, 2));
  coloring_type = g_value_get_enum (gimp_value_array_index (args, 3));

  if (success)
    {
      GimpGradient        *gradient;
      GimpGradientSegment *start_seg;
      GimpGradientSegment *end_seg;

      gradient = gradient_get_range (gimp, name, start_segment, end_segment,
                                     &start_seg, &end_seg, error);

      if (start_seg)
        {
          gimp_gradient_segment_range_set_coloring_type (gradient,
                                                         start_seg, end_seg,
                                                         coloring_type);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
gradient_segment_range_flip_invoker (GimpProcedure         *procedure,
                                     Gimp                  *gimp,
                                     GimpContext           *context,
                                     GimpProgress          *progress,
                                     const GimpValueArray  *args,
                                     GError               **error)
{
  gboolean success = TRUE;
  const gchar *name;
  gint32 start_segment;
  gint32 end_segment;

  name = g_value_get_string (gimp_value_array_index (args, 0));
  start_segment = g_value_get_int (gimp_value_array_index (args, 1));
  end_segment = g_value_get_int (gimp_value_array_index (args, 2));

  if (success)
    {
      GimpGradient        *gradient;
      GimpGradientSegment *start_seg;
      GimpGradientSegment *end_seg;

      gradient = gradient_get_range (gimp, name, start_segment, end_segment,
                                     &start_seg, &end_seg, error);

      if (start_seg)
        {
          gimp_gradient_segment_range_flip (gradient,
                                            start_seg, end_seg,
                                            NULL, NULL);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
gradient_segment_range_replicate_invoker (GimpProcedure         *procedure,
                                          Gimp                  *gimp,
                                          GimpContext           *context,
                                          GimpProgress          *progress,
                                          const GimpValueArray  *args,
                                          GError               **error)
{
  gboolean success = TRUE;
  const gchar *name;
  gint32 start_segment;
  gint32 end_segment;
  gint32 replicate_times;

  name = g_value_get_string (gimp_value_array_index (args, 0));
  start_segment = g_value_get_int (gimp_value_array_index (args, 1));
  end_segment = g_value_get_int (gimp_value_array_index (args, 2));
  replicate_times = g_value_get_int (gimp_value_array_index (args, 3));

  if (success)
    {
      GimpGradient        *gradient;
      GimpGradientSegment *start_seg;
      GimpGradientSegment *end_seg;

      gradient = gradient_get_range (gimp, name, start_segment, end_segment,
                                     &start_seg, &end_seg, error);

      if (start_seg && gimp_data_is_writable (GIMP_DATA (gradient)))
        {
          gimp_gradient_segment_range_replicate (gradient,
                                                 start_seg, end_seg,
                                                 replicate_times,
                                                 NULL, NULL);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
gradient_segment_range_split_midpoint_invoker (GimpProcedure         *procedure,
                                               Gimp                  *gimp,
                                               GimpContext           *context,
                                               GimpProgress          *progress,
                                               const GimpValueArray  *args,
                                               GError               **error)
{
  gboolean success = TRUE;
  const gchar *name;
  gint32 start_segment;
  gint32 end_segment;

  name = g_value_get_string (gimp_value_array_index (args, 0));
  start_segment = g_value_get_int (gimp_value_array_index (args, 1));
  end_segment = g_value_get_int (gimp_value_array_index (args, 2));

  if (success)
    {
      GimpGradient        *gradient;
      GimpGradientSegment *start_seg;
      GimpGradientSegment *end_seg;

      gradient = gradient_get_range (gimp, name, start_segment, end_segment,
                                     &start_seg, &end_seg, error);

      if (start_seg)
        {
          gimp_gradient_segment_range_split_midpoint (gradient, context,
                                                      start_seg, end_seg,
                                                      GIMP_GRADIENT_BLEND_RGB_PERCEPTUAL,
                                                      NULL, NULL);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
gradient_segment_range_split_uniform_invoker (GimpProcedure         *procedure,
                                              Gimp                  *gimp,
                                              GimpContext           *context,
                                              GimpProgress          *progress,
                                              const GimpValueArray  *args,
                                              GError               **error)
{
  gboolean success = TRUE;
  const gchar *name;
  gint32 start_segment;
  gint32 end_segment;
  gint32 split_parts;

  name = g_value_get_string (gimp_value_array_index (args, 0));
  start_segment = g_value_get_int (gimp_value_array_index (args, 1));
  end_segment = g_value_get_int (gimp_value_array_index (args, 2));
  split_parts = g_value_get_int (gimp_value_array_index (args, 3));

  if (success)
    {
      GimpGradient        *gradient;
      GimpGradientSegment *start_seg;
      GimpGradientSegment *end_seg;

      gradient = gradient_get_range (gimp, name, start_segment, end_segment,
                                     &start_seg, &end_seg, error);

      if (start_seg)
        {
          gimp_gradient_segment_range_split_uniform (gradient, context,
                                                     start_seg, end_seg,
                                                     split_parts,
                                                     GIMP_GRADIENT_BLEND_RGB_PERCEPTUAL,
                                                     NULL, NULL);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
gradient_segment_range_delete_invoker (GimpProcedure         *procedure,
                                       Gimp                  *gimp,
                                       GimpContext           *context,
                                       GimpProgress          *progress,
                                       const GimpValueArray  *args,
                                       GError               **error)
{
  gboolean success = TRUE;
  const gchar *name;
  gint32 start_segment;
  gint32 end_segment;

  name = g_value_get_string (gimp_value_array_index (args, 0));
  start_segment = g_value_get_int (gimp_value_array_index (args, 1));
  end_segment = g_value_get_int (gimp_value_array_index (args, 2));

  if (success)
    {
      GimpGradient        *gradient;
      GimpGradientSegment *start_seg;
      GimpGradientSegment *end_seg;

      gradient = gradient_get_range (gimp, name, start_segment, end_segment,
                                     &start_seg, &end_seg, error);

      if (start_seg)
        {
          gimp_gradient_segment_range_delete (gradient,
                                              start_seg, end_seg,
                                              NULL, NULL);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
gradient_segment_range_redistribute_handles_invoker (GimpProcedure         *procedure,
                                                     Gimp                  *gimp,
                                                     GimpContext           *context,
                                                     GimpProgress          *progress,
                                                     const GimpValueArray  *args,
                                                     GError               **error)
{
  gboolean success = TRUE;
  const gchar *name;
  gint32 start_segment;
  gint32 end_segment;

  name = g_value_get_string (gimp_value_array_index (args, 0));
  start_segment = g_value_get_int (gimp_value_array_index (args, 1));
  end_segment = g_value_get_int (gimp_value_array_index (args, 2));

  if (success)
    {
      GimpGradient        *gradient;
      GimpGradientSegment *start_seg;
      GimpGradientSegment *end_seg;

      gradient = gradient_get_range (gimp, name, start_segment, end_segment,
                                     &start_seg, &end_seg, error);

      if (start_seg)
        {
          gimp_gradient_segment_range_redistribute_handles (gradient,
                                                            start_seg, end_seg);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
gradient_segment_range_blend_colors_invoker (GimpProcedure         *procedure,
                                             Gimp                  *gimp,
                                             GimpContext           *context,
                                             GimpProgress          *progress,
                                             const GimpValueArray  *args,
                                             GError               **error)
{
  gboolean success = TRUE;
  const gchar *name;
  gint32 start_segment;
  gint32 end_segment;

  name = g_value_get_string (gimp_value_array_index (args, 0));
  start_segment = g_value_get_int (gimp_value_array_index (args, 1));
  end_segment = g_value_get_int (gimp_value_array_index (args, 2));

  if (success)
    {
      GimpGradient        *gradient;
      GimpGradientSegment *start_seg;
      GimpGradientSegment *end_seg;

      gradient = gradient_get_range (gimp, name, start_segment, end_segment,
                                     &start_seg, &end_seg, error);

      if (start_seg)
        {
          if (!end_seg)
            end_seg = gimp_gradient_segment_get_last (start_seg);

          gimp_gradient_segment_range_blend (gradient,
                                             start_seg, end_seg,
                                             &start_seg->left_color,
                                             &end_seg->right_color,
                                             TRUE, FALSE);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
gradient_segment_range_blend_opacity_invoker (GimpProcedure         *procedure,
                                              Gimp                  *gimp,
                                              GimpContext           *context,
                                              GimpProgress          *progress,
                                              const GimpValueArray  *args,
                                              GError               **error)
{
  gboolean success = TRUE;
  const gchar *name;
  gint32 start_segment;
  gint32 end_segment;

  name = g_value_get_string (gimp_value_array_index (args, 0));
  start_segment = g_value_get_int (gimp_value_array_index (args, 1));
  end_segment = g_value_get_int (gimp_value_array_index (args, 2));

  if (success)
    {
      GimpGradient        *gradient;
      GimpGradientSegment *start_seg;
      GimpGradientSegment *end_seg;

      gradient = gradient_get_range (gimp, name, start_segment, end_segment,
                                     &start_seg, &end_seg, error);

      if (start_seg)
        {
          if (!end_seg)
            end_seg = gimp_gradient_segment_get_last (start_seg);

          gimp_gradient_segment_range_blend (gradient,
                                             start_seg, end_seg,
                                             &start_seg->left_color,
                                             &end_seg->right_color,
                                             FALSE, TRUE);
        }
      else
        success = FALSE;
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}

static GimpValueArray *
gradient_segment_range_move_invoker (GimpProcedure         *procedure,
                                     Gimp                  *gimp,
                                     GimpContext           *context,
                                     GimpProgress          *progress,
                                     const GimpValueArray  *args,
                                     GError               **error)
{
  gboolean success = TRUE;
  GimpValueArray *return_vals;
  const gchar *name;
  gint32 start_segment;
  gint32 end_segment;
  gdouble delta;
  gboolean control_compress;
  gdouble final_delta = 0.0;

  name = g_value_get_string (gimp_value_array_index (args, 0));
  start_segment = g_value_get_int (gimp_value_array_index (args, 1));
  end_segment = g_value_get_int (gimp_value_array_index (args, 2));
  delta = g_value_get_double (gimp_value_array_index (args, 3));
  control_compress = g_value_get_boolean (gimp_value_array_index (args, 4));

  if (success)
    {
      GimpGradient        *gradient;
      GimpGradientSegment *start_seg;
      GimpGradientSegment *end_seg;

      gradient = gradient_get_range (gimp, name, start_segment, end_segment,
                                     &start_seg, &end_seg, error);

      if (start_seg)
        {
          final_delta = gimp_gradient_segment_range_move (gradient,
                                                          start_seg, end_seg,
                                                          delta,
                                                          control_compress);
        }
      else
        success = FALSE;
    }

  return_vals = gimp_procedure_get_return_values (procedure, success,
                                                  error ? *error : NULL);

  if (success)
    g_value_set_double (gimp_value_array_index (return_vals, 1), final_delta);

  return return_vals;
}

void
register_gradient_procs (GimpPDB *pdb)
{
  GimpProcedure *procedure;

  /*
   * gimp-gradient-new
   */
  procedure = gimp_procedure_new (gradient_new_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-new");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-new",
                                     "Creates a new gradient",
                                     "This procedure creates a new, uninitialized gradient",
                                     "Shlomi Fish <shlomif@iglu.org.il>",
                                     "Shlomi Fish",
                                     "2003",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The requested name of the new gradient",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   gimp_param_spec_string ("actual-name",
                                                           "actual name",
                                                           "The actual new gradient name",
                                                           FALSE, FALSE, FALSE,
                                                           NULL,
                                                           GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-duplicate
   */
  procedure = gimp_procedure_new (gradient_duplicate_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-duplicate");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-duplicate",
                                     "Duplicates a gradient",
                                     "This procedure creates an identical gradient by a different name",
                                     "Shlomi Fish <shlomif@iglu.org.il>",
                                     "Shlomi Fish",
                                     "2003",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   gimp_param_spec_string ("copy-name",
                                                           "copy name",
                                                           "The name of the gradient's copy",
                                                           FALSE, FALSE, FALSE,
                                                           NULL,
                                                           GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-is-editable
   */
  procedure = gimp_procedure_new (gradient_is_editable_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-is-editable");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-is-editable",
                                     "Tests if gradient can be edited",
                                     "Returns TRUE if you have permission to change the gradient",
                                     "Bill Skaggs <weskaggs@primate.ucdavis.edu>",
                                     "Bill Skaggs",
                                     "2004",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   g_param_spec_boolean ("editable",
                                                         "editable",
                                                         "TRUE if the gradient can be edited",
                                                         FALSE,
                                                         GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-rename
   */
  procedure = gimp_procedure_new (gradient_rename_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-rename");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-rename",
                                     "Rename a gradient",
                                     "This procedure renames a gradient",
                                     "Shlomi Fish <shlomif@iglu.org.il>",
                                     "Shlomi Fish",
                                     "2003",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("new-name",
                                                       "new name",
                                                       "The new name of the gradient",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   gimp_param_spec_string ("actual-name",
                                                           "actual name",
                                                           "The actual new name of the gradient",
                                                           FALSE, FALSE, FALSE,
                                                           NULL,
                                                           GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-delete
   */
  procedure = gimp_procedure_new (gradient_delete_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-delete");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-delete",
                                     "Deletes a gradient",
                                     "This procedure deletes a gradient",
                                     "Shlomi Fish <shlomif@iglu.org.il>",
                                     "Shlomi Fish",
                                     "2003",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-get-number-of-segments
   */
  procedure = gimp_procedure_new (gradient_get_number_of_segments_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-get-number-of-segments");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-get-number-of-segments",
                                     "Returns the number of segments of the specified gradient",
                                     "This procedure returns the number of segments of the specified gradient.",
                                     "Lars-Peter Clausen <lars@metafoo.de>",
                                     "Lars-Peter Clausen",
                                     "2008",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   gimp_param_spec_int32 ("num-segments",
                                                          "num segments",
                                                          "Number of segments",
                                                          G_MININT32, G_MAXINT32, 0,
                                                          GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-get-uniform-samples
   */
  procedure = gimp_procedure_new (gradient_get_uniform_samples_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-get-uniform-samples");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-get-uniform-samples",
                                     "Sample the specified in uniform parts.",
                                     "This procedure samples the active gradient in the specified number of uniform parts. It returns a list of floating-point values which correspond to the RGBA values for each sample. The minimum number of samples to take is 2, in which case the returned colors will correspond to the { 0.0, 1.0 } positions in the gradient. For example, if the number of samples is 3, the procedure will return the colors at positions { 0.0, 0.5, 1.0 }.",
                                     "Federico Mena Quintero",
                                     "Federico Mena Quintero",
                                     "1997",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("num-samples",
                                                      "num samples",
                                                      "The number of samples to take",
                                                      2, G_MAXINT32, 2,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("reverse",
                                                     "reverse",
                                                     "Use the reverse gradient",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   gimp_param_spec_int32 ("num-color-samples",
                                                          "num color samples",
                                                          "Length of the color_samples array (4 * num_samples)",
                                                          0, G_MAXINT32, 0,
                                                          GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   gimp_param_spec_float_array ("color-samples",
                                                                "color samples",
                                                                "Color samples: { R1, G1, B1, A1, ..., Rn, Gn, Bn, An }",
                                                                GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-get-custom-samples
   */
  procedure = gimp_procedure_new (gradient_get_custom_samples_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-get-custom-samples");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-get-custom-samples",
                                     "Sample the specified gradient in custom positions.",
                                     "This procedure samples the active gradient in the specified number of points. The procedure will sample the gradient in the specified positions from the list. The left endpoint of the gradient corresponds to position 0.0, and the right endpoint corresponds to 1.0. The procedure returns a list of floating-point values which correspond to the RGBA values for each sample.",
                                     "Federico Mena Quintero",
                                     "Federico Mena Quintero",
                                     "1997",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("num-samples",
                                                      "num samples",
                                                      "The number of samples to take",
                                                      1, G_MAXINT32, 1,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_float_array ("positions",
                                                            "positions",
                                                            "The list of positions to sample along the gradient",
                                                            GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("reverse",
                                                     "reverse",
                                                     "Use the reverse gradient",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   gimp_param_spec_int32 ("num-color-samples",
                                                          "num color samples",
                                                          "Length of the color_samples array (4 * num_samples)",
                                                          0, G_MAXINT32, 0,
                                                          GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   gimp_param_spec_float_array ("color-samples",
                                                                "color samples",
                                                                "Color samples: { R1, G1, B1, A1, ..., Rn, Gn, Bn, An }",
                                                                GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-segment-get-left-color
   */
  procedure = gimp_procedure_new (gradient_segment_get_left_color_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-segment-get-left-color");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-segment-get-left-color",
                                     "Retrieves the left endpoint color of the specified segment",
                                     "This procedure retrieves the left endpoint color of the specified segment of the specified gradient.",
                                     "Shlomi Fish <shlomif@iglu.org.il>",
                                     "Shlomi Fish",
                                     "2003",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("segment",
                                                      "segment",
                                                      "The index of the segment within the gradient",
                                                      0, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   gimp_param_spec_rgb ("color",
                                                        "color",
                                                        "The return color",
                                                        FALSE,
                                                        NULL,
                                                        GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   g_param_spec_double ("opacity",
                                                        "opacity",
                                                        "The opacity of the endpoint",
                                                        -G_MAXDOUBLE, G_MAXDOUBLE, 0,
                                                        GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-segment-set-left-color
   */
  procedure = gimp_procedure_new (gradient_segment_set_left_color_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-segment-set-left-color");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-segment-set-left-color",
                                     "Sets the left endpoint color of the specified segment",
                                     "This procedure sets the left endpoint color of the specified segment of the specified gradient.",
                                     "Shlomi Fish <shlomif@iglu.org.il>",
                                     "Shlomi Fish",
                                     "2003",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("segment",
                                                      "segment",
                                                      "The index of the segment within the gradient",
                                                      0, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_rgb ("color",
                                                    "color",
                                                    "The color to set",
                                                    FALSE,
                                                    NULL,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("opacity",
                                                    "opacity",
                                                    "The opacity to set for the endpoint",
                                                    0, 100.0, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-segment-get-right-color
   */
  procedure = gimp_procedure_new (gradient_segment_get_right_color_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-segment-get-right-color");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-segment-get-right-color",
                                     "Retrieves the right endpoint color of the specified segment",
                                     "This procedure retrieves the right endpoint color of the specified segment of the specified gradient.",
                                     "Shlomi Fish <shlomif@iglu.org.il>",
                                     "Shlomi Fish",
                                     "2003",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("segment",
                                                      "segment",
                                                      "The index of the segment within the gradient",
                                                      0, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   gimp_param_spec_rgb ("color",
                                                        "color",
                                                        "The return color",
                                                        FALSE,
                                                        NULL,
                                                        GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   g_param_spec_double ("opacity",
                                                        "opacity",
                                                        "The opacity of the endpoint",
                                                        -G_MAXDOUBLE, G_MAXDOUBLE, 0,
                                                        GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-segment-set-right-color
   */
  procedure = gimp_procedure_new (gradient_segment_set_right_color_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-segment-set-right-color");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-segment-set-right-color",
                                     "Sets the right endpoint color of the specified segment",
                                     "This procedure sets the right endpoint color of the specified segment of the specified gradient.",
                                     "Shlomi Fish <shlomif@iglu.org.il>",
                                     "Shlomi Fish",
                                     "2003",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("segment",
                                                      "segment",
                                                      "The index of the segment within the gradient",
                                                      0, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_rgb ("color",
                                                    "color",
                                                    "The color to set",
                                                    FALSE,
                                                    NULL,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("opacity",
                                                    "opacity",
                                                    "The opacity to set for the endpoint",
                                                    0, 100.0, 0,
                                                    GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-segment-get-left-pos
   */
  procedure = gimp_procedure_new (gradient_segment_get_left_pos_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-segment-get-left-pos");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-segment-get-left-pos",
                                     "Retrieves the left endpoint position of the specified segment",
                                     "This procedure retrieves the left endpoint position of the specified segment of the specified gradient.",
                                     "Shlomi Fish <shlomif@iglu.org.il>",
                                     "Shlomi Fish",
                                     "2003",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("segment",
                                                      "segment",
                                                      "The index of the segment within the gradient",
                                                      0, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   g_param_spec_double ("pos",
                                                        "pos",
                                                        "The return position",
                                                        -G_MAXDOUBLE, G_MAXDOUBLE, 0,
                                                        GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-segment-set-left-pos
   */
  procedure = gimp_procedure_new (gradient_segment_set_left_pos_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-segment-set-left-pos");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-segment-set-left-pos",
                                     "Sets the left endpoint position of the specified segment",
                                     "This procedure sets the left endpoint position of the specified segment of the specified gradient. The final position will be between the position of the middle point to the left to the middle point of the current segment.\n"
                                     "This procedure returns the final position.",
                                     "Shlomi Fish <shlomif@iglu.org.il>",
                                     "Shlomi Fish",
                                     "2003",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("segment",
                                                      "segment",
                                                      "The index of the segment within the gradient",
                                                      0, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("pos",
                                                    "pos",
                                                    "The position to set the guidepoint to",
                                                    0.0, 1.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   g_param_spec_double ("final-pos",
                                                        "final pos",
                                                        "The return position",
                                                        -G_MAXDOUBLE, G_MAXDOUBLE, 0,
                                                        GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-segment-get-middle-pos
   */
  procedure = gimp_procedure_new (gradient_segment_get_middle_pos_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-segment-get-middle-pos");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-segment-get-middle-pos",
                                     "Retrieves the middle point position of the specified segment",
                                     "This procedure retrieves the middle point position of the specified segment of the specified gradient.",
                                     "Shlomi Fish <shlomif@iglu.org.il>",
                                     "Shlomi Fish",
                                     "2003",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("segment",
                                                      "segment",
                                                      "The index of the segment within the gradient",
                                                      0, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   g_param_spec_double ("pos",
                                                        "pos",
                                                        "The return position",
                                                        -G_MAXDOUBLE, G_MAXDOUBLE, 0,
                                                        GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-segment-set-middle-pos
   */
  procedure = gimp_procedure_new (gradient_segment_set_middle_pos_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-segment-set-middle-pos");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-segment-set-middle-pos",
                                     "Sets the middle point position of the specified segment",
                                     "This procedure sets the middle point position of the specified segment of the specified gradient. The final position will be between the two endpoints of the segment.\n"
                                     "This procedure returns the final position.",
                                     "Shlomi Fish <shlomif@iglu.org.il>",
                                     "Shlomi Fish",
                                     "2003",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("segment",
                                                      "segment",
                                                      "The index of the segment within the gradient",
                                                      0, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("pos",
                                                    "pos",
                                                    "The position to set the guidepoint to",
                                                    0.0, 1.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   g_param_spec_double ("final-pos",
                                                        "final pos",
                                                        "The return position",
                                                        -G_MAXDOUBLE, G_MAXDOUBLE, 0,
                                                        GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-segment-get-right-pos
   */
  procedure = gimp_procedure_new (gradient_segment_get_right_pos_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-segment-get-right-pos");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-segment-get-right-pos",
                                     "Retrieves the right endpoint position of the specified segment",
                                     "This procedure retrieves the right endpoint position of the specified segment of the specified gradient.",
                                     "Shlomi Fish <shlomif@iglu.org.il>",
                                     "Shlomi Fish",
                                     "2003",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("segment",
                                                      "segment",
                                                      "The index of the segment within the gradient",
                                                      0, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   g_param_spec_double ("pos",
                                                        "pos",
                                                        "The return position",
                                                        -G_MAXDOUBLE, G_MAXDOUBLE, 0,
                                                        GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-segment-set-right-pos
   */
  procedure = gimp_procedure_new (gradient_segment_set_right_pos_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-segment-set-right-pos");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-segment-set-right-pos",
                                     "Sets the right endpoint position of the specified segment",
                                     "This procedure sets the right endpoint position of the specified segment of the specified gradient. The final position will be between the position of the middle point of the current segment and the middle point of the segment to the right.\n"
                                     "This procedure returns the final position.",
                                     "Shlomi Fish <shlomif@iglu.org.il>",
                                     "Shlomi Fish",
                                     "2003",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("segment",
                                                      "segment",
                                                      "The index of the segment within the gradient",
                                                      0, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("pos",
                                                    "pos",
                                                    "The position to set the guidepoint to",
                                                    0.0, 1.0, 0.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   g_param_spec_double ("final-pos",
                                                        "final pos",
                                                        "The return position",
                                                        -G_MAXDOUBLE, G_MAXDOUBLE, 0,
                                                        GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-segment-get-blending-function
   */
  procedure = gimp_procedure_new (gradient_segment_get_blending_function_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-segment-get-blending-function");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-segment-get-blending-function",
                                     "Retrieves the gradient segment's blending function",
                                     "This procedure retrieves the blending function of the segment at the specified gradient name and segment index.",
                                     "Shlomi Fish <shlomif@iglu.org.il>",
                                     "Shlomi Fish",
                                     "2003",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("segment",
                                                      "segment",
                                                      "The index of the segment within the gradient",
                                                      0, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   g_param_spec_enum ("blend-func",
                                                      "blend func",
                                                      "The blending function of the segment",
                                                      GIMP_TYPE_GRADIENT_SEGMENT_TYPE,
                                                      GIMP_GRADIENT_SEGMENT_LINEAR,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-segment-get-coloring-type
   */
  procedure = gimp_procedure_new (gradient_segment_get_coloring_type_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-segment-get-coloring-type");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-segment-get-coloring-type",
                                     "Retrieves the gradient segment's coloring type",
                                     "This procedure retrieves the coloring type of the segment at the specified gradient name and segment index.",
                                     "Shlomi Fish <shlomif@iglu.org.il>",
                                     "Shlomi Fish",
                                     "2003",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("segment",
                                                      "segment",
                                                      "The index of the segment within the gradient",
                                                      0, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   g_param_spec_enum ("coloring-type",
                                                      "coloring type",
                                                      "The coloring type of the segment",
                                                      GIMP_TYPE_GRADIENT_SEGMENT_COLOR,
                                                      GIMP_GRADIENT_SEGMENT_RGB,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-segment-range-set-blending-function
   */
  procedure = gimp_procedure_new (gradient_segment_range_set_blending_function_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-segment-range-set-blending-function");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-segment-range-set-blending-function",
                                     "Change the blending function of a segments range",
                                     "This function changes the blending function of a segment range to the specified blending function.",
                                     "Shlomi Fish <shlomif@iglu.org.il>",
                                     "Shlomi Fish",
                                     "2003",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("start-segment",
                                                      "start segment",
                                                      "The index of the first segment to operate on",
                                                      0, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("end-segment",
                                                      "end segment",
                                                      "The index of the last segment to operate on. If negative, the selection will extend to the end of the string.",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("blending-function",
                                                  "blending function",
                                                  "The blending function",
                                                  GIMP_TYPE_GRADIENT_SEGMENT_TYPE,
                                                  GIMP_GRADIENT_SEGMENT_LINEAR,
                                                  GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-segment-range-set-coloring-type
   */
  procedure = gimp_procedure_new (gradient_segment_range_set_coloring_type_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-segment-range-set-coloring-type");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-segment-range-set-coloring-type",
                                     "Change the coloring type of a segments range",
                                     "This function changes the coloring type of a segment range to the specified coloring type.",
                                     "Shlomi Fish <shlomif@iglu.org.il>",
                                     "Shlomi Fish",
                                     "2003",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("start-segment",
                                                      "start segment",
                                                      "The index of the first segment to operate on",
                                                      0, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("end-segment",
                                                      "end segment",
                                                      "The index of the last segment to operate on. If negative, the selection will extend to the end of the string.",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_enum ("coloring-type",
                                                  "coloring type",
                                                  "The coloring type",
                                                  GIMP_TYPE_GRADIENT_SEGMENT_COLOR,
                                                  GIMP_GRADIENT_SEGMENT_RGB,
                                                  GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-segment-range-flip
   */
  procedure = gimp_procedure_new (gradient_segment_range_flip_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-segment-range-flip");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-segment-range-flip",
                                     "Flip the segment range",
                                     "This function flips a segment range.",
                                     "Shlomi Fish <shlomif@iglu.org.il>",
                                     "Shlomi Fish",
                                     "2003",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("start-segment",
                                                      "start segment",
                                                      "The index of the first segment to operate on",
                                                      0, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("end-segment",
                                                      "end segment",
                                                      "The index of the last segment to operate on. If negative, the selection will extend to the end of the string.",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-segment-range-replicate
   */
  procedure = gimp_procedure_new (gradient_segment_range_replicate_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-segment-range-replicate");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-segment-range-replicate",
                                     "Replicate the segment range",
                                     "This function replicates a segment range a given number of times. Instead of the original segment range, several smaller scaled copies of it will appear in equal widths.",
                                     "Shlomi Fish <shlomif@iglu.org.il>",
                                     "Shlomi Fish",
                                     "2003",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("start-segment",
                                                      "start segment",
                                                      "The index of the first segment to operate on",
                                                      0, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("end-segment",
                                                      "end segment",
                                                      "The index of the last segment to operate on. If negative, the selection will extend to the end of the string.",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("replicate-times",
                                                      "replicate times",
                                                      "The number of times to replicate",
                                                      2, 20, 2,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-segment-range-split-midpoint
   */
  procedure = gimp_procedure_new (gradient_segment_range_split_midpoint_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-segment-range-split-midpoint");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-segment-range-split-midpoint",
                                     "Splits each segment in the segment range at midpoint",
                                     "This function splits each segment in the segment range at its midpoint.",
                                     "Shlomi Fish <shlomif@iglu.org.il>",
                                     "Shlomi Fish",
                                     "2003",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("start-segment",
                                                      "start segment",
                                                      "The index of the first segment to operate on",
                                                      0, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("end-segment",
                                                      "end segment",
                                                      "The index of the last segment to operate on. If negative, the selection will extend to the end of the string.",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-segment-range-split-uniform
   */
  procedure = gimp_procedure_new (gradient_segment_range_split_uniform_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-segment-range-split-uniform");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-segment-range-split-uniform",
                                     "Splits each segment in the segment range uniformly",
                                     "This function splits each segment in the segment range uniformly according to the number of times specified by the parameter.",
                                     "Shlomi Fish <shlomif@iglu.org.il>",
                                     "Shlomi Fish",
                                     "2003",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("start-segment",
                                                      "start segment",
                                                      "The index of the first segment to operate on",
                                                      0, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("end-segment",
                                                      "end segment",
                                                      "The index of the last segment to operate on. If negative, the selection will extend to the end of the string.",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("split-parts",
                                                      "split parts",
                                                      "The number of uniform divisions to split each segment to",
                                                      2, 1024, 2,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-segment-range-delete
   */
  procedure = gimp_procedure_new (gradient_segment_range_delete_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-segment-range-delete");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-segment-range-delete",
                                     "Delete the segment range",
                                     "This function deletes a segment range.",
                                     "Shlomi Fish <shlomif@iglu.org.il>",
                                     "Shlomi Fish",
                                     "2003",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("start-segment",
                                                      "start segment",
                                                      "The index of the first segment to operate on",
                                                      0, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("end-segment",
                                                      "end segment",
                                                      "The index of the last segment to operate on. If negative, the selection will extend to the end of the string.",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-segment-range-redistribute-handles
   */
  procedure = gimp_procedure_new (gradient_segment_range_redistribute_handles_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-segment-range-redistribute-handles");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-segment-range-redistribute-handles",
                                     "Uniformly redistribute the segment range's handles",
                                     "This function redistributes the handles of the specified segment range of the specified gradient, so they'll be evenly spaced.",
                                     "Shlomi Fish <shlomif@iglu.org.il>",
                                     "Shlomi Fish",
                                     "2003",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("start-segment",
                                                      "start segment",
                                                      "The index of the first segment to operate on",
                                                      0, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("end-segment",
                                                      "end segment",
                                                      "The index of the last segment to operate on. If negative, the selection will extend to the end of the string.",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-segment-range-blend-colors
   */
  procedure = gimp_procedure_new (gradient_segment_range_blend_colors_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-segment-range-blend-colors");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-segment-range-blend-colors",
                                     "Blend the colors of the segment range.",
                                     "This function blends the colors (but not the opacity) of the segments' range of the gradient. Using it, the colors' transition will be uniform across the range.",
                                     "Shlomi Fish <shlomif@iglu.org.il>",
                                     "Shlomi Fish",
                                     "2003",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("start-segment",
                                                      "start segment",
                                                      "The index of the first segment to operate on",
                                                      0, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("end-segment",
                                                      "end segment",
                                                      "The index of the last segment to operate on. If negative, the selection will extend to the end of the string.",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-segment-range-blend-opacity
   */
  procedure = gimp_procedure_new (gradient_segment_range_blend_opacity_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-segment-range-blend-opacity");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-segment-range-blend-opacity",
                                     "Blend the opacity of the segment range.",
                                     "This function blends the opacity (but not the colors) of the segments' range of the gradient. Using it, the opacity's transition will be uniform across the range.",
                                     "Shlomi Fish <shlomif@iglu.org.il>",
                                     "Shlomi Fish",
                                     "2003",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("start-segment",
                                                      "start segment",
                                                      "The index of the first segment to operate on",
                                                      0, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("end-segment",
                                                      "end segment",
                                                      "The index of the last segment to operate on. If negative, the selection will extend to the end of the string.",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);

  /*
   * gimp-gradient-segment-range-move
   */
  procedure = gimp_procedure_new (gradient_segment_range_move_invoker);
  gimp_object_set_static_name (GIMP_OBJECT (procedure),
                               "gimp-gradient-segment-range-move");
  gimp_procedure_set_static_strings (procedure,
                                     "gimp-gradient-segment-range-move",
                                     "Move the position of an entire segment range by a delta.",
                                     "This function moves the position of an entire segment range by a delta. The actual delta (which is returned) will be limited by the control points of the neighboring segments.",
                                     "Shlomi Fish <shlomif@iglu.org.il>",
                                     "Shlomi Fish",
                                     "2003",
                                     NULL);
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_string ("name",
                                                       "name",
                                                       "The gradient name",
                                                       FALSE, FALSE, TRUE,
                                                       NULL,
                                                       GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("start-segment",
                                                      "start segment",
                                                      "The index of the first segment to operate on",
                                                      0, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               gimp_param_spec_int32 ("end-segment",
                                                      "end segment",
                                                      "The index of the last segment to operate on. If negative, the selection will extend to the end of the string.",
                                                      G_MININT32, G_MAXINT32, 0,
                                                      GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_double ("delta",
                                                    "delta",
                                                    "The delta to move the segment range",
                                                    -1.0, 1.0, -1.0,
                                                    GIMP_PARAM_READWRITE));
  gimp_procedure_add_argument (procedure,
                               g_param_spec_boolean ("control-compress",
                                                     "control compress",
                                                     "Whether or not to compress the neighboring segments",
                                                     FALSE,
                                                     GIMP_PARAM_READWRITE));
  gimp_procedure_add_return_value (procedure,
                                   g_param_spec_double ("final-delta",
                                                        "final delta",
                                                        "The final delta by which the range moved",
                                                        -G_MAXDOUBLE, G_MAXDOUBLE, 0,
                                                        GIMP_PARAM_READWRITE));
  gimp_pdb_register_procedure (pdb, procedure);
  g_object_unref (procedure);
}
