/* $Id$ */
/* vim:set ts=2 sw=2 et ai syntax=c cindent: */
/*-
 * Copyright (c) 2005 os-cillation e.K.
 *
 * Written by Benedikt Meurer <benny@xfce.org>.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

%%
headers
#include <Python.h>
#include <pygtk/pygtk.h>
#include "pyexo.h"

/* mark internal symbols with G_GNUC_INTERNAL */
void exo_add_constants    (PyObject    *module,
                           const gchar *strip_prefix) G_GNUC_INTERNAL;
void exo_register_classes (PyObject    *d) G_GNUC_INTERNAL;

%%
modulename exo

%%
import gobject.GObject as PyGObject_Type
import gtk.gdk.Window as PyGdkWindow_Type
import gtk.CellLayout as PyGtkCellLayout_Type
import gtk.CellRenderer as PyGtkCellRenderer_Type
import gtk.CellRendererText as PyGtkCellRendererText_Type
import gtk.Container as PyGtkContainer_Type
import gtk.Dialog as PyGtkDialog_Type
import gtk.Label as PyGtkLabel_Type
import gtk.IconTheme as PyGtkIconTheme_Type
import gtk.RadioAction as PyGtkRadioAction_Type
import gtk.TreeModel as PyGtkTreeModel_Type
import gtk.TreeView as PyGtkTreeView_Type
import gtk.UIManager as PyGtkUIManager_Type
import gtk.VBox as PyGtkVBox_Type
import gtk.gdk.Pixbuf as PyGdkPixbuf_Type
import gtk.gdk.Screen as PyGdkScreen_Type

%%
ignore-glob
  *_get_type

%%
ignore
  exo_execute_preferred_application_on_screen
  exo_execute_terminal_shell_on_screen
  exo_icon_bar_new
  exo_icon_view_new
  exo_icon_view_selected_foreach
  exo_toolbars_editor_new
  exo_toolbars_view_new
  exo_url_show_on_screen

%%
override exo_execute_preferred_application kwargs
static PyObject*
_wrap_exo_execute_preferred_application (PyObject *self,
                                         PyObject *args,
                                         PyObject *kwargs)
{
  static gchar *kwlist[] = { "category", "parameter", "working_directory", "environment", "screen", NULL };
  const gchar  *working_directory = NULL;
  const gchar  *parameter = NULL;
  const gchar  *category;
  GdkScreen    *screen;
  PyObject     *sequence = Py_None;
  PyObject     *item = Py_None;
  GError       *error = NULL;
  gchar       **envp = NULL;
  gint          n;

  if (!PyArg_ParseTupleAndKeywords (args, kwargs, "s|ssOO:execute_preferred_application",
                                    kwlist, &category, &parameter, &working_directory, &sequence, &item))
    return NULL;

  /* validate parameters */
  if (sequence != Py_None && !PySequence_Check (sequence))
    {
      PyErr_SetString (PyExc_TypeError, "environment must be a sequence or None");
      return NULL;
    }
  else if (item != Py_None && !pygobject_check (item, &PyGdkScreen_Type))
    {
      PyErr_SetString (PyExc_TypeError, "screen must be a gtk.gdk.Screen or None");
      return NULL;
    }

  if (working_directory != NULL && *working_directory == '\0')
    working_directory = NULL;

  if (parameter != NULL && *parameter == '\0')
    parameter = NULL;

  /* determine the screen */
  screen = (item != Py_None) ? GDK_SCREEN (pygobject_get (item)) : gdk_screen_get_default ();

  if (G_UNLIKELY (sequence != Py_None))
    {
      envp = g_new0 (gchar *, PySequence_Length (sequence) + 1);
      for (n = 0; n < PySequence_Length (sequence); ++n)
        {
          item = PySequence_GetItem (sequence, n);
          Py_DECREF (item);

          if (!PyString_Check (item) && !PyUnicode_Check (item))
            {
              PyErr_SetString (PyExc_TypeError, "sequence item not a string or unicode object");
              g_strfreev (envp);
              return NULL;
            }

          envp[n] = g_strdup (PyString_AsString (item));
        }
    }

  /* try to execute the preferred application */
  exo_execute_preferred_application_on_screen (category, parameter, working_directory, envp, screen, &error);

  /* release the environment */
  g_strfreev (envp);

  /* check for errors */
  if (pyg_error_check (&error))
    return NULL;

  Py_INCREF (Py_None);
  return Py_None;
}

%%
override exo_execute_terminal_shell kwargs
static PyObject*
_wrap_exo_execute_terminal_shell (PyObject *self,
                                  PyObject *args,
                                  PyObject *kwargs)
{
  static gchar *kwlist[] = { "command_line", "working_directory", "environment", "screen", NULL };
  const gchar  *working_directory = NULL;
  const gchar  *command_line;
  GdkScreen    *screen;
  PyObject     *sequence = Py_None;
  PyObject     *item = Py_None;
  GError       *error = NULL;
  gchar       **envp = NULL;
  gint          n;

  if (!PyArg_ParseTupleAndKeywords (args, kwargs, "s|sOO:execute_terminal_shell",
                                    kwlist, &command_line, &working_directory, &sequence, &item))
    return NULL;

  /* validate parameters */
  if (sequence != Py_None && !PySequence_Check (sequence))
    {
      PyErr_SetString (PyExc_TypeError, "environment must be a sequence or None");
      return NULL;
    }
  else if (item != Py_None && !pygobject_check (item, &PyGdkScreen_Type))
    {
      PyErr_SetString (PyExc_TypeError, "screen must be a gtk.gdk.Screen or None");
      return NULL;
    }

  if (working_directory != NULL && *working_directory == '\0')
    working_directory = NULL;

  /* determine the screen */
  screen = (item != Py_None) ? GDK_SCREEN (pygobject_get (item)) : gdk_screen_get_default ();

  if (G_UNLIKELY (sequence != Py_None))
    {
      envp = g_new0 (gchar *, PySequence_Length (sequence) + 1);
      for (n = 0; n < PySequence_Length (sequence); ++n)
        {
          item = PySequence_GetItem (sequence, n);
          Py_DECREF (item);

          if (!PyString_Check (item) && !PyUnicode_Check (item))
            {
              PyErr_SetString (PyExc_TypeError, "sequence item not a string or unicode object");
              g_strfreev (envp);
              return NULL;
            }

          envp[n] = g_strdup (PyString_AsString (item));
        }
    }

  /* try to execute the terminal shell */
  exo_execute_terminal_shell_on_screen (command_line, working_directory, envp, screen, &error);

  /* release the environment */
  g_strfreev (envp);

  /* check for errors */
  if (pyg_error_check (&error))
    return NULL;

  Py_INCREF (Py_None);
  return Py_None;
}

%%
override exo_icon_view_get_selected_items kwargs
static PyObject*
_wrap_exo_icon_view_get_selected_items (PyGObject *self,
                                        PyObject  *args,
                                        PyObject  *kwargs)
{
  PyObject *result;
  PyObject *item;
  GList    *items;
  GList    *lp;

  items = exo_icon_view_get_selected_items (EXO_ICON_VIEW (self->obj));

  result = PyList_New (0);
  if (G_UNLIKELY (result == NULL))
    return NULL;

  for (lp = items; lp != NULL; lp = lp->next)
    {
      item = pygtk_tree_path_to_pyobject (lp->data);
      PyList_Append (result, item);
      Py_DECREF (item);

      gtk_tree_path_free (lp->data);
    }

  g_list_free (items);

  return result;
}

%%
override exo_toolbars_model_get_actions
static PyObject*
_wrap_exo_toolbars_model_get_actions (PyGObject *self)
{
  PyObject *result;
  PyObject *value;
  gchar   **actions;
  guint     n;

  actions = exo_toolbars_model_get_actions (EXO_TOOLBARS_MODEL (self->obj));
  if (G_LIKELY (actions != NULL))
    {
      result = PyList_New (0);
      if (G_UNLIKELY (result == NULL))
        return NULL;

      for (n = 0; actions[n] != NULL; ++n)
        {
          value = Py_BuildValue ("s", actions[n]);
          PyList_Append (result, value);
          Py_DECREF (value);
        }

      g_strfreev (actions);
    }
  else
    {
      Py_INCREF (Py_None);
      result = Py_None;
    }

  return result;
}

%%
override exo_toolbars_model_set_actions kwargs
static PyObject*
_wrap_exo_toolbars_model_set_actions (PyGObject *self,
                                      PyObject  *args,
                                      PyObject  *kwargs)
{
  static char *kwlist[] = { "args", NULL };
  PyObject    *sequence;
  PyObject    *item;
  gchar      **actions;
  guint        n_actions;
  guint        n;

  if (!PyArg_ParseTupleAndKeywords (args, kwargs,
                                    "O:ExoToolbarsModel.set_actions",
                                    kwlist, &sequence))
    return NULL;

  if (!PySequence_Check (sequence))
    {
      PyErr_SetString (PyExc_TypeError, "first argument must be a sequence");
      return NULL;
    }

  n_actions = PySequence_Length (sequence);
  actions = g_new0 (gchar *, n_actions + 1);

  for (n = 0; n < n_actions; ++n)
    {
      item = PySequence_GetItem (sequence, n);
      Py_DECREF (item);

      if (!PyString_Check (item) && !PyUnicode_Check (item))
        {
          PyErr_SetString (PyExc_TypeError, "sequence item "
                           "not a string or unicode object");
          g_strfreev (actions);
          return NULL;
        }

      actions[n] = g_strdup (PyString_AsString (item));
    }

  exo_toolbars_model_set_actions (EXO_TOOLBARS_MODEL (self->obj),
                                  actions, n_actions);
  g_strfreev (actions);

  Py_INCREF (Py_None);
  return Py_None;
}

%%
override exo_toolbars_model_get_item_type kwargs
static PyObject*
_wrap_exo_toolbars_model_get_item_type (PyGObject *self,
                                        PyObject  *args,
                                        PyObject  *kwargs)
{
  static char *kwlist[] = { "dnd_type", NULL };
  PyObject    *object;
  GdkAtom      type;
  gchar       *result;

  if (!PyArg_ParseTupleAndKeywords (args, kwargs,
                                    "O:ExoToolbarsModel.get_item_type",
                                    kwlist, &object))
    return NULL;

  if (G_UNLIKELY (object == NULL))
    type = NULL;
  else if (PyString_Check (object))
    type = gdk_atom_intern (PyString_AsString (object), FALSE);
  else if (PyGdkAtom_Check (object))
    type = PyGdkAtom_Get (object);
  else
    {
      PyErr_SetString (PyExc_TypeError, "unable to convert argument to GdkAtom");
      return NULL;
    }

  result = exo_toolbars_model_get_item_type (EXO_TOOLBARS_MODEL (self->obj), type);
  if (G_LIKELY (result != NULL))
    {
      object = PyString_FromString (result);
      g_free (result);
    }
  else
    {
      object = Py_None;
      Py_INCREF (Py_None);
    }

  return object;
}

%%
override exo_toolbars_model_item_nth kwargs
static PyObject*
_wrap_exo_toolbars_model_item_nth (PyGObject *self,
                                   PyObject  *args,
                                   PyObject  *kwargs)
{
  static char *kwlist[] = { "toolbar_position", "item_position", NULL };
  const gchar *type;
  const gchar *id;
  gboolean     is_separator;
  gint         toolbar_position;
  gint         item_position;
  

  if (!PyArg_ParseTupleAndKeywords (args, kwargs,
                                    "ii:ExoToolbarsModel.item_nth",
                                    kwlist, &toolbar_position, &item_position))
    return NULL;

  exo_toolbars_model_item_nth (EXO_TOOLBARS_MODEL (self->obj),
                               toolbar_position, item_position,
                               &is_separator, &id, &type);

  return Py_BuildValue ("(iss)", is_separator, id, type);
}

%%
override exo_xsession_client_get_restart_command
static PyObject*
_wrap_exo_xsession_client_get_restart_command (PyGObject *self)
{
  PyObject *result;
  PyObject *value;
  gchar   **argv;
  gint      argc;
  gint      n;

  if (exo_xsession_client_get_restart_command (EXO_XSESSION_CLIENT (self->obj),
                                               &argv, &argc))
    {
      result = PyList_New (0);
      if (G_UNLIKELY (result == NULL))
        return NULL;

      for (n = 0; n < argc; ++n)
        {
          value = Py_BuildValue ("s", argv[n]);
          PyList_Append (result, value);
          Py_DECREF (value);
        }

      g_strfreev (argv);
    }
  else
    {
      Py_INCREF (Py_None);
      result = Py_None;
    }

  return result;
}

%%
override exo_xsession_client_set_restart_command kwargs
static PyObject*
_wrap_exo_xsession_client_set_restart_command (PyGObject *self,
                                               PyObject  *args,
                                               PyObject  *kwargs)
{
  static char *kwlist[] = { "args", NULL };
  PyObject    *sequence;
  PyObject    *item;
  gchar      **argv;
  gint         argc;
  gint         n;

  if (!PyArg_ParseTupleAndKeywords (args, kwargs,
                                    "0:ExoXsessionClient.set_restart_command",
                                    kwlist, &sequence))
    return NULL;

  if (!PySequence_Check (sequence))
    {
      PyErr_SetString (PyExc_TypeError, "first argument must be a sequence");
      return NULL;
    }

  argc = PySequence_Length (sequence);
  argv = g_new0 (gchar *, argc + 1);

  for (n = 0; n < argc; ++n)
    {
      item = PySequence_GetItem (sequence, n);
      Py_DECREF (item);

      if (!PyString_Check (item) && !PyUnicode_Check (item))
        {
          PyErr_SetString (PyExc_TypeError, "sequence item "
                           "not a string or unicode object");
          g_strfreev (argv);
          return NULL;
        }

      argv[n] = g_strdup (PyString_AsString (item));
    }

  exo_xsession_client_set_restart_command (EXO_XSESSION_CLIENT (self->obj),
                                           argv, argc);
  g_strfreev (argv);

  Py_INCREF (Py_None);
  return Py_None;
}

%%
override exo_url_show kwargs
static PyObject*
_wrap_exo_url_show (PyObject *self,
                    PyObject *args,
                    PyObject *kwargs)
{
  static gchar *kwlist[] = { "url", "environment", "screen", NULL };
  const gchar  *url;
  GdkScreen    *screen;
  PyObject     *sequence = Py_None;
  PyObject     *item = Py_None;
  GError       *error = NULL;
  gchar       **envp = NULL;
  gint          n;

  if (!PyArg_ParseTupleAndKeywords (args, kwargs, "s|OO:show_url",
                                    kwlist, &url, &sequence, &item))
    return NULL;

  /* validate parameters */
  if (sequence != Py_None && !PySequence_Check (sequence))
    {
      PyErr_SetString (PyExc_TypeError, "environment must be a sequence or None");
      return NULL;
    }
  else if (item != Py_None && !pygobject_check (item, &PyGdkScreen_Type))
    {
      PyErr_SetString (PyExc_TypeError, "screen must be a gtk.gdk.Screen or None");
      return NULL;
    }

  /* determine the screen */
  screen = (item != Py_None) ? GDK_SCREEN (pygobject_get (item)) : gdk_screen_get_default ();

  if (G_UNLIKELY (sequence != Py_None))
    {
      envp = g_new0 (gchar *, PySequence_Length (sequence) + 1);
      for (n = 0; n < PySequence_Length (sequence); ++n)
        {
          item = PySequence_GetItem (sequence, n);
          Py_DECREF (item);

          if (!PyString_Check (item) && !PyUnicode_Check (item))
            {
              PyErr_SetString (PyExc_TypeError, "sequence item not a string or unicode object");
              g_strfreev (envp);
              return NULL;
            }

          envp[n] = g_strdup (PyString_AsString (item));
        }
    }

  /* try to open the specified URL */
  exo_url_show_on_screen (url, envp, screen, &error);

  /* release the environment */
  g_strfreev (envp);

  /* check for errors */
  if (pyg_error_check (&error))
    return NULL;

  Py_INCREF (Py_None);
  return Py_None;
}

