/* 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
 *
 * 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/>.
 */

#ifndef __PIKA_PROCEDURE_H__
#define __PIKA_PROCEDURE_H__


#include "core/pikaviewable.h"


typedef PikaValueArray * (* PikaMarshalFunc) (PikaProcedure         *procedure,
                                              Pika                  *pika,
                                              PikaContext           *context,
                                              PikaProgress          *progress,
                                              const PikaValueArray  *args,
                                              GError               **error);


#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))


typedef struct _PikaProcedureClass PikaProcedureClass;

struct _PikaProcedure
{
  PikaViewable      parent_instance;

  PikaPDBProcType   proc_type;      /* Type of procedure              */

  gboolean          static_help;    /* Are the strings allocated?     */
  gchar            *blurb;          /* Short procedure description    */
  gchar            *help;           /* Detailed help instructions     */
  gchar            *help_id;        /* Help ID                        */

  gboolean          static_attribution;
  gchar            *authors;        /* Authors field                  */
  gchar            *copyright;      /* Copyright field                */
  gchar            *date;           /* Date field                     */

  gchar            *deprecated;     /* Replacement if deprecated      */

  gchar            *label;          /* Cached label string            */

  gint32            num_args;       /* Number of procedure arguments  */
  GParamSpec      **args;           /* Array of procedure arguments   */

  gint32            num_values;     /* Number of return values        */
  GParamSpec      **values;         /* Array of return values         */

  PikaMarshalFunc   marshal_func;   /* Marshaller for internal procs  */
};

struct _PikaProcedureClass
{
  PikaViewableClass parent_class;

  const gchar    * (* get_label)      (PikaProcedure   *procedure);
  const gchar    * (* get_menu_label) (PikaProcedure   *procedure);
  const gchar    * (* get_blurb)      (PikaProcedure   *procedure);
  const gchar    * (* get_help_id)    (PikaProcedure   *procedure);
  gboolean         (* get_sensitive)  (PikaProcedure   *procedure,
                                       PikaObject      *object,
                                       const gchar    **reason);

  PikaValueArray * (* execute)        (PikaProcedure   *procedure,
                                       Pika            *pika,
                                       PikaContext     *context,
                                       PikaProgress    *progress,
                                       PikaValueArray  *args,
                                       GError         **error);
  void             (* execute_async)  (PikaProcedure   *procedure,
                                       Pika            *pika,
                                       PikaContext     *context,
                                       PikaProgress    *progress,
                                       PikaValueArray  *args,
                                       PikaDisplay     *display);
};


GType            pika_procedure_get_type           (void) G_GNUC_CONST;

PikaProcedure  * pika_procedure_new                (PikaMarshalFunc   marshal_func);

void             pika_procedure_set_help           (PikaProcedure    *procedure,
                                                    const gchar      *blurb,
                                                    const gchar      *help,
                                                    const gchar      *help_id);
void             pika_procedure_set_static_help    (PikaProcedure    *procedure,
                                                    const gchar      *blurb,
                                                    const gchar      *help,
                                                    const gchar      *help_id);
void             pika_procedure_take_help          (PikaProcedure    *procedure,
                                                    gchar            *blurb,
                                                    gchar            *help,
                                                    gchar            *help_id);

void             pika_procedure_set_attribution    (PikaProcedure    *procedure,
                                                    const gchar      *authors,
                                                    const gchar      *copyright,
                                                    const gchar      *date);
void             pika_procedure_set_static_attribution
                                                   (PikaProcedure    *procedure,
                                                    const gchar      *authors,
                                                    const gchar      *copyright,
                                                    const gchar      *date);
void             pika_procedure_take_attribution   (PikaProcedure    *procedure,
                                                    gchar            *authors,
                                                    gchar            *copyright,
                                                    gchar            *date);

void             pika_procedure_set_deprecated     (PikaProcedure    *procedure,
                                                    const gchar      *deprecated);

const gchar    * pika_procedure_get_label          (PikaProcedure    *procedure);
const gchar    * pika_procedure_get_menu_label     (PikaProcedure    *procedure);
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);
gboolean         pika_procedure_get_sensitive      (PikaProcedure    *procedure,
                                                    PikaObject       *object,
                                                    const gchar     **reason);

void             pika_procedure_add_argument       (PikaProcedure    *procedure,
                                                    GParamSpec       *pspec);
void             pika_procedure_add_return_value   (PikaProcedure    *procedure,
                                                    GParamSpec       *pspec);

PikaValueArray * pika_procedure_get_arguments      (PikaProcedure    *procedure);
PikaValueArray * pika_procedure_get_return_values  (PikaProcedure    *procedure,
                                                    gboolean          success,
                                                    const GError     *error);

PikaProcedure  * pika_procedure_create_override    (PikaProcedure    *procedure,
                                                    PikaMarshalFunc   new_marshal_func);

PikaValueArray * pika_procedure_execute            (PikaProcedure    *procedure,
                                                    Pika             *pika,
                                                    PikaContext      *context,
                                                    PikaProgress     *progress,
                                                    PikaValueArray   *args,
                                                    GError          **error);
void             pika_procedure_execute_async      (PikaProcedure    *procedure,
                                                    Pika             *pika,
                                                    PikaContext      *context,
                                                    PikaProgress     *progress,
                                                    PikaValueArray   *args,
                                                    PikaDisplay      *display,
                                                    GError          **error);

gint             pika_procedure_name_compare       (PikaProcedure    *proc1,
                                                    PikaProcedure    *proc2);



#endif  /*  __PIKA_PROCEDURE_H__  */
