/* 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-1997 Peter Mattis and Spencer Kimball
 *
 * pikaapp.c
 * Copyright (C) 2022 Lukas Oberhuber <lukaso@gmail.com>
 *
 * 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
 * Library 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/>.
 */

#include <config.h>

#include <gio/gio.h>

#include "libpikabase/pikabase.h"

#include "core/core-types.h"

#include "core/pika.h"

#include "pikacoreapp.h"


#define PIKA_CORE_APP_GET_PRIVATE(obj) (pika_core_app_get_private ((PikaCoreApp *) (obj)))

typedef struct _PikaCoreAppPrivate PikaCoreAppPrivate;

struct _PikaCoreAppPrivate
{
  Pika       *pika;
  gboolean    as_new;
  gchar     **filenames;

  gboolean    quit;
  gchar      *batch_interpreter;
  gchar     **batch_commands;
  gint        exit_status;
};

/*  local function prototypes  */

static PikaCoreAppPrivate * pika_core_app_get_private      (PikaCoreApp        *app);
static void                 pika_core_app_private_finalize (PikaCoreAppPrivate *private);


G_DEFINE_INTERFACE (PikaCoreApp, pika_core_app, G_TYPE_OBJECT)

static void
pika_core_app_default_init (PikaCoreAppInterface *iface)
{
  /* add properties and signals to the interface here */
  g_object_interface_install_property (iface,
                                       g_param_spec_object ("pika",
                                                            "PIKA",
                                                            "PIKA root object",
                                                            PIKA_TYPE_PIKA,
                                                            PIKA_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
  g_object_interface_install_property (iface,
                                       g_param_spec_boxed ("filenames",
                                                           "Files to open at start",
                                                           "Files to open at start",
                                                           G_TYPE_STRV,
                                                           PIKA_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
  g_object_interface_install_property (iface,
                                       g_param_spec_boolean ("as-new",
                                                             "Open images as new",
                                                             "Open images as new",
                                                             FALSE,
                                                             PIKA_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));

  g_object_interface_install_property (iface,
                                       g_param_spec_boolean ("quit",
                                                             "Quit",
                                                             "Quit PIKA immediately after running batch commands",
                                                             FALSE,
                                                             PIKA_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
  g_object_interface_install_property (iface,
                                       g_param_spec_string ("batch-interpreter",
                                                            "The procedure to process batch commands with",
                                                            "The procedure to process batch commands with",
                                                            NULL,
                                                            PIKA_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));

  g_object_interface_install_property (iface,
                                       g_param_spec_boxed ("batch-commands",
                                                           "Batch commands to run",
                                                           "Batch commands to run",
                                                           G_TYPE_STRV,
                                                           PIKA_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
}


/* Protected functions. */

/**
 * pika_container_view_install_properties:
 * @klass: the class structure for a type deriving from #GObject
 *
 * Installs the necessary properties for a class implementing
 * #PikaCoreApp. Please call this function in the *_class_init()
 * function of the child class.
 **/
void
pika_core_app_install_properties (GObjectClass *klass)
{
  g_object_class_override_property (klass, PIKA_CORE_APP_PROP_PIKA, "pika");
  g_object_class_override_property (klass, PIKA_CORE_APP_PROP_FILENAMES, "filenames");
  g_object_class_override_property (klass, PIKA_CORE_APP_PROP_AS_NEW, "as-new");

  g_object_class_override_property (klass, PIKA_CORE_APP_PROP_QUIT, "quit");
  g_object_class_override_property (klass, PIKA_CORE_APP_PROP_BATCH_INTERPRETER, "batch-interpreter");
  g_object_class_override_property (klass, PIKA_CORE_APP_PROP_BATCH_COMMANDS, "batch-commands");
}

void
pika_core_app_set_property (GObject      *object,
                            guint         property_id,
                            const GValue *value,
                            GParamSpec   *pspec)
{
  PikaCoreAppPrivate *private;

  private = PIKA_CORE_APP_GET_PRIVATE (object);

  switch (property_id)
    {
    case PIKA_CORE_APP_PROP_PIKA:
      private->pika = g_value_get_object (value);
      break;
    case PIKA_CORE_APP_PROP_FILENAMES:
      private->filenames = g_value_dup_boxed (value);
      break;
    case PIKA_CORE_APP_PROP_AS_NEW:
      private->as_new = g_value_get_boolean (value);
      break;
    case PIKA_CORE_APP_PROP_QUIT:
      private->quit = g_value_get_boolean (value);
      break;
    case PIKA_CORE_APP_PROP_BATCH_INTERPRETER:
      private->batch_interpreter = g_value_dup_string (value);
      break;
    case PIKA_CORE_APP_PROP_BATCH_COMMANDS:
      private->batch_commands = g_value_dup_boxed (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
    }
}

void
pika_core_app_get_property (GObject    *object,
                            guint       property_id,
                            GValue     *value,
                            GParamSpec *pspec)
{
  PikaCoreAppPrivate *private;

  private = PIKA_CORE_APP_GET_PRIVATE (object);

  switch (property_id)
    {
    case PIKA_CORE_APP_PROP_PIKA:
      g_value_set_object (value, private->pika);
      break;
    case PIKA_CORE_APP_PROP_FILENAMES:
      g_value_set_static_boxed (value, private->filenames);
      break;
    case PIKA_CORE_APP_PROP_AS_NEW:
      g_value_set_boolean (value, private->as_new);
      break;
    case PIKA_CORE_APP_PROP_QUIT:
      g_value_set_boolean (value, private->quit);
      break;
    case PIKA_CORE_APP_PROP_BATCH_INTERPRETER:
      g_value_set_static_string (value, private->batch_interpreter);
      break;
    case PIKA_CORE_APP_PROP_BATCH_COMMANDS:
      g_value_set_static_boxed (value, private->batch_commands);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
    }
}


/* Public functions. */

Pika *
pika_core_app_get_pika (PikaCoreApp *self)
{
  PikaCoreAppPrivate *private;

  g_return_val_if_fail (PIKA_IS_CORE_APP (self), NULL);

  private = PIKA_CORE_APP_GET_PRIVATE (self);

  return private->pika;
}

gboolean
pika_core_app_get_quit (PikaCoreApp *self)
{
  PikaCoreAppPrivate *private;

  g_return_val_if_fail (PIKA_IS_CORE_APP (self), FALSE);

  private = PIKA_CORE_APP_GET_PRIVATE (self);

  return private->quit;
}

gboolean
pika_core_app_get_as_new (PikaCoreApp *self)
{
  PikaCoreAppPrivate *private;

  g_return_val_if_fail (PIKA_IS_CORE_APP (self), FALSE);

  private = PIKA_CORE_APP_GET_PRIVATE (self);

  return private->as_new;
}

const gchar **
pika_core_app_get_filenames (PikaCoreApp *self)
{
  PikaCoreAppPrivate *private;

  g_return_val_if_fail (PIKA_IS_CORE_APP (self), NULL);

  private = PIKA_CORE_APP_GET_PRIVATE (self);

  return (const gchar **) private->filenames;
}

const gchar *
pika_core_app_get_batch_interpreter (PikaCoreApp *self)
{
  PikaCoreAppPrivate *private;

  g_return_val_if_fail (PIKA_IS_CORE_APP (self), NULL);

  private = PIKA_CORE_APP_GET_PRIVATE (self);

  return (const gchar *) private->batch_interpreter;
}

const gchar **
pika_core_app_get_batch_commands (PikaCoreApp *self)
{
  PikaCoreAppPrivate *private;

  g_return_val_if_fail (PIKA_IS_CORE_APP (self), NULL);

  private = PIKA_CORE_APP_GET_PRIVATE (self);

  return (const gchar **) private->batch_commands;
}

void
pika_core_app_set_exit_status (PikaCoreApp *self, gint exit_status)
{
  PikaCoreAppPrivate *private;

  g_return_if_fail (PIKA_IS_CORE_APP (self));

  private = PIKA_CORE_APP_GET_PRIVATE (self);

  private->exit_status = exit_status;
}

gint
pika_core_app_get_exit_status (PikaCoreApp *self)
{
  PikaCoreAppPrivate *private;

  g_return_val_if_fail (PIKA_IS_CORE_APP (self), EXIT_FAILURE);

  private = PIKA_CORE_APP_GET_PRIVATE (self);

  return private->exit_status;
}

/*  Private functions  */

static PikaCoreAppPrivate *
pika_core_app_get_private (PikaCoreApp *app)
{
  PikaCoreAppPrivate *private;

  static GQuark private_key = 0;

  g_return_val_if_fail (PIKA_IS_CORE_APP (app), NULL);

  if (! private_key)
    private_key = g_quark_from_static_string ("pika-core-app-private");

  private = g_object_get_qdata ((GObject *) app, private_key);

  if (! private)
    {
      private = g_slice_new0 (PikaCoreAppPrivate);

      g_object_set_qdata_full ((GObject *) app, private_key, private,
                               (GDestroyNotify) pika_core_app_private_finalize);
    }

  return private;
}

static void
pika_core_app_private_finalize (PikaCoreAppPrivate *private)
{
  g_clear_pointer (&private->filenames, g_strfreev);
  g_clear_pointer (&private->batch_interpreter, g_free);
  g_clear_pointer (&private->batch_commands, g_strfreev);

  g_slice_free (PikaCoreAppPrivate, private);
}
