/* PIKA - Photo and Image Kooker Application
 * a rebranding of The GNU Image Manipulation Program (created with heckimp)
 * A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
 *
 * Original copyright, applying to most contents (license remains unchanged): 
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
 * pikaprocedure.h
 * Copyright (C) 2019 Michael Natterer <mitch@gimp.org>
 *
 * This library is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see
 * <https://www.gnu.org/licenses/>.
 */

#if !defined (__PIKA_H_INSIDE__) && !defined (PIKA_COMPILATION)
#error "Only <libpika/pika.h> can be included directly."
#endif

#ifndef __PIKA_PROCEDURE_H__
#define __PIKA_PROCEDURE_H__

G_BEGIN_DECLS

/* For information look into the C source or the html documentation */


/**
 * PikaRunFunc:
 * @procedure: the #PikaProcedure that runs.
 * @config:    the @procedure's arguments in a config object.
 * @run_data: (closure): the run_data given in pika_procedure_new().
 *
 * The run function is run during the lifetime of the PIKA session,
 * each time a plug-in procedure is called.
 *
 * Returns: (transfer full): the @procedure's return values.
 *
 * Since: 3.0
 **/
typedef PikaValueArray * (* PikaRunFunc) (PikaProcedure       *procedure,
                                          PikaProcedureConfig *config,
                                          gpointer             run_data);


/**
 * PikaArgumentSync:
 * @PIKA_ARGUMENT_SYNC_NONE:     Don't sync this argument
 * @PIKA_ARGUMENT_SYNC_PARASITE: Sync this argument with an image parasite
 *
 * Methods of syncing procedure arguments.
 *
 * Since: 3.0
 **/
typedef enum
{
  PIKA_ARGUMENT_SYNC_NONE,
  PIKA_ARGUMENT_SYNC_PARASITE
} PikaArgumentSync;


#define PIKA_TYPE_PROCEDURE            (pika_procedure_get_type ())
#define PIKA_PROCEDURE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), PIKA_TYPE_PROCEDURE, PikaProcedure))
#define PIKA_PROCEDURE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), PIKA_TYPE_PROCEDURE, PikaProcedureClass))
#define PIKA_IS_PROCEDURE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PIKA_TYPE_PROCEDURE))
#define PIKA_IS_PROCEDURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PIKA_TYPE_PROCEDURE))
#define PIKA_PROCEDURE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), PIKA_TYPE_PROCEDURE, PikaProcedureClass))

G_DEFINE_AUTOPTR_CLEANUP_FUNC (PikaProcedure, g_object_unref);

typedef struct _PikaProcedureClass   PikaProcedureClass;
typedef struct _PikaProcedurePrivate PikaProcedurePrivate;

struct _PikaProcedure
{
  GObject               parent_instance;

  PikaProcedurePrivate *priv;
};

/**
 * PikaProcedureClass:
 * @install: called to install the procedure with the main PIKA
 *   application. This is an implementation detail and must never
 *   be called by any plug-in code.
 * @uninstall: called to uninstall the procedure from the main PIKA
 *   application. This is an implementation detail and must never
 *   be called by any plug-in code.
 * @run: called when the procedure is executed via pika_procedure_run().
 *   the default implementation simply calls the procedure's #PikaRunFunc,
 *   #PikaProcedure subclasses are free to modify the passed @args and
 *   call their own, subclass-specific run functions.
 * @create_config: called when a #PikaConfig object is created using
 *   pika_procedure_create_config().
 *
 * Since: 3.0
 **/
struct _PikaProcedureClass
{
  GObjectClass parent_class;

  void                  (* install)         (PikaProcedure         *procedure);
  void                  (* uninstall)       (PikaProcedure         *procedure);

  PikaValueArray      * (* run)             (PikaProcedure         *procedure,
                                             const PikaValueArray  *args);

  PikaProcedureConfig * (* create_config)   (PikaProcedure         *procedure,
                                             GParamSpec           **args,
                                             gint                   n_args);

  gboolean              (* set_sensitivity) (PikaProcedure         *procedure,
                                             gint                   sensitivity_mask);

  /* Padding for future expansion */
  /*< private >*/
  void (*_pika_reserved1) (void);
  void (*_pika_reserved2) (void);
  void (*_pika_reserved3) (void);
  void (*_pika_reserved4) (void);
  void (*_pika_reserved5) (void);
  void (*_pika_reserved6) (void);
  void (*_pika_reserved7) (void);
  void (*_pika_reserved8) (void);
};


GType            pika_procedure_get_type           (void) G_GNUC_CONST;

PikaProcedure  * pika_procedure_new                (PikaPlugIn           *plug_in,
                                                    const gchar          *name,
                                                    PikaPDBProcType       proc_type,
                                                    PikaRunFunc           run_func,
                                                    gpointer              run_data,
                                                    GDestroyNotify        run_data_destroy);

PikaPlugIn     * pika_procedure_get_plug_in        (PikaProcedure        *procedure);
const gchar    * pika_procedure_get_name           (PikaProcedure        *procedure);
PikaPDBProcType  pika_procedure_get_proc_type      (PikaProcedure        *procedure);

void             pika_procedure_set_image_types    (PikaProcedure        *procedure,
                                                    const gchar          *image_types);
const gchar    * pika_procedure_get_image_types    (PikaProcedure        *procedure);

void           pika_procedure_set_sensitivity_mask (PikaProcedure        *procedure,
                                                    gint                  sensitivity_mask);
gint           pika_procedure_get_sensitivity_mask (PikaProcedure        *procedure);


void             pika_procedure_set_menu_label     (PikaProcedure        *procedure,
                                                    const gchar          *menu_label);
const gchar    * pika_procedure_get_menu_label     (PikaProcedure        *procedure);

void             pika_procedure_add_menu_path      (PikaProcedure        *procedure,
                                                    const gchar          *menu_path);
GList          * pika_procedure_get_menu_paths     (PikaProcedure        *procedure);

void             pika_procedure_set_icon_name      (PikaProcedure        *procedure,
                                                    const gchar          *icon_name);
void             pika_procedure_set_icon_file      (PikaProcedure        *procedure,
                                                    GFile                *file);
void             pika_procedure_set_icon_pixbuf    (PikaProcedure        *procedure,
                                                    GdkPixbuf            *pixbuf);

PikaIconType     pika_procedure_get_icon_type      (PikaProcedure        *procedure);
const gchar    * pika_procedure_get_icon_name      (PikaProcedure        *procedure);
GFile          * pika_procedure_get_icon_file      (PikaProcedure        *procedure);
GdkPixbuf      * pika_procedure_get_icon_pixbuf    (PikaProcedure        *procedure);

void             pika_procedure_set_documentation  (PikaProcedure        *procedure,
                                                    const gchar          *blurb,
                                                    const gchar          *help,
                                                    const gchar          *help_id);
const gchar    * pika_procedure_get_blurb          (PikaProcedure        *procedure);
const gchar    * pika_procedure_get_help           (PikaProcedure        *procedure);
const gchar    * pika_procedure_get_help_id        (PikaProcedure        *procedure);

void             pika_procedure_set_attribution    (PikaProcedure        *procedure,
                                                    const gchar          *authors,
                                                    const gchar          *copyright,
                                                    const gchar          *date);
const gchar    * pika_procedure_get_authors        (PikaProcedure        *procedure);
const gchar    * pika_procedure_get_copyright      (PikaProcedure        *procedure);
const gchar    * pika_procedure_get_date           (PikaProcedure        *procedure);

GParamSpec     * pika_procedure_add_argument       (PikaProcedure        *procedure,
                                                    GParamSpec           *pspec);
GParamSpec     * pika_procedure_add_argument_from_property
                                                   (PikaProcedure        *procedure,
                                                    GObject              *config,
                                                    const gchar          *prop_name);

GParamSpec     * pika_procedure_add_aux_argument   (PikaProcedure        *procedure,
                                                    GParamSpec           *pspec);
GParamSpec     * pika_procedure_add_aux_argument_from_property
                                                   (PikaProcedure        *procedure,
                                                    GObject              *config,
                                                    const gchar          *prop_name);

GParamSpec     * pika_procedure_add_return_value   (PikaProcedure        *procedure,
                                                    GParamSpec           *pspec);
GParamSpec     * pika_procedure_add_return_value_from_property
                                                   (PikaProcedure        *procedure,
                                                    GObject              *config,
                                                    const gchar          *prop_name);

GParamSpec     * pika_procedure_find_argument      (PikaProcedure        *procedure,
                                                    const gchar          *name);
GParamSpec     * pika_procedure_find_aux_argument  (PikaProcedure        *procedure,
                                                    const gchar          *name);
GParamSpec     * pika_procedure_find_return_value  (PikaProcedure        *procedure,
                                                    const gchar          *name);

GParamSpec    ** pika_procedure_get_arguments      (PikaProcedure        *procedure,
                                                    gint                 *n_arguments);
GParamSpec    ** pika_procedure_get_aux_arguments  (PikaProcedure        *procedure,
                                                    gint                 *n_arguments);
GParamSpec    ** pika_procedure_get_return_values  (PikaProcedure        *procedure,
                                                    gint                 *n_return_values);

void             pika_procedure_set_argument_sync  (PikaProcedure        *procedure,
                                                    const gchar          *arg_name,
                                                    PikaArgumentSync      sync);
PikaArgumentSync pika_procedure_get_argument_sync  (PikaProcedure        *procedure,
                                                    const gchar          *arg_name);

PikaValueArray * pika_procedure_new_return_values  (PikaProcedure        *procedure,
                                                    PikaPDBStatusType     status,
                                                    GError               *error);

PikaValueArray * pika_procedure_run                (PikaProcedure        *procedure,
                                                    const gchar          *first_arg_name,
                                                    ...) G_GNUC_NULL_TERMINATED;
PikaValueArray * pika_procedure_run_valist         (PikaProcedure        *procedure,
                                                    const gchar          *first_arg_name,
                                                    va_list               args);
PikaValueArray * pika_procedure_run_config         (PikaProcedure        *procedure,
                                                    PikaProcedureConfig  *config);

void             pika_procedure_extension_ready    (PikaProcedure        *procedure);

PikaProcedureConfig *
                 pika_procedure_create_config      (PikaProcedure        *procedure);


/* Internal use */

G_GNUC_INTERNAL PikaValueArray * _pika_procedure_run_array (PikaProcedure  *procedure,
                                                            PikaValueArray *args);


G_END_DECLS

#endif  /*  __PIKA_PROCEDURE_H__  */
