/*
 * Copyright (c) 2002, 2003, 2004 Jean-Yves Lefort
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of Jean-Yves Lefort nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include "sg-util.h"
#include "st-applications-preferences-page.h"
#include "st-action.h"
#include "st-util.h"
#include "st-util-api.h"
#include "st-stock.h"

/*** type definitions ********************************************************/

enum {
  /* invisible columns */
  COLUMN_ID,

  /* visible columns */
  COLUMN_LABEL,
  COLUMN_COMMAND,

  N_COLUMNS
};

/*** function declarations ***************************************************/

static void st_applications_preferences_page_init (STApplicationsPreferencesPage *page);

static void st_applications_preferences_page_cell_edited_h (GtkCellRendererText *cell,
							    const char *path_string,
							    const char *new_text,
							    gpointer user_data);
static gboolean st_applications_preferences_page_search_equal_func (GtkTreeModel *model,
								    int column,
								    const char *key,
								    GtkTreeIter *iter,
								    gpointer search_data);

/*** implementation **********************************************************/

GType
st_applications_preferences_page_get_type (void)
{
  static GType type = 0;
  
  if (! type)
    {
      static const GTypeInfo info = {
	sizeof(STApplicationsPreferencesPageClass),
	NULL,
	NULL,
	NULL,
	NULL,
	NULL,
	sizeof(STApplicationsPreferencesPage),
	0,
	(GInstanceInitFunc) st_applications_preferences_page_init,
      };

      type = g_type_register_static(ST_TYPE_PREFERENCES_PAGE,
				    "STApplicationsPreferencesPage",
				    &info,
				    0);
    }

  return type;
}

static void
st_applications_preferences_page_init (STApplicationsPreferencesPage *page)
{
  STPreferencesPage *ppage = ST_PREFERENCES_PAGE(page);
  GtkListStore *store;
  GSList *actions;
  GSList *l;
  GtkWidget *view;
  GtkTreeViewColumn *column;
  GtkCellRenderer *renderer;
  GtkWidget *scrolled;

  st_preferences_page_set_name(ppage, "applications");
  st_preferences_page_set_stock_id(ppage, ST_STOCK_APPLICATIONS);
  st_preferences_page_set_label(ppage, _("Applications"));
  st_preferences_page_set_help_link_id(ppage, "preferences-applications");

  store = gtk_list_store_new(N_COLUMNS,
			     G_TYPE_STRING,
			     G_TYPE_STRING,
			     G_TYPE_STRING);

  actions = st_action_list();
  SG_LIST_FOREACH(l, actions)
    {
      const char *id = l->data;
      STAction *action;
      GtkTreeIter iter;

      action = st_action_get(id);
      g_return_if_fail(action != NULL);

      if (action->label)
	{
	  gtk_list_store_append(store, &iter);
	  gtk_list_store_set(store, &iter,
			     COLUMN_ID, id,
			     COLUMN_LABEL, action->label,
			     COLUMN_COMMAND, action->command,
			     -1);
	}
    }
  g_slist_free(actions);
  
  view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));

  column = gtk_tree_view_column_new_with_attributes(_("Action"),
						    gtk_cell_renderer_text_new(),
						    "text", COLUMN_LABEL,
						    NULL);
  gtk_tree_view_column_set_sort_column_id(column, COLUMN_LABEL);
  gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);

  renderer = gtk_cell_renderer_text_new();

  g_object_set(renderer, "editable", TRUE, NULL);
  g_signal_connect(renderer, "edited", G_CALLBACK(st_applications_preferences_page_cell_edited_h), store);

  column = gtk_tree_view_column_new_with_attributes(_("Command"),
						    renderer,
						    "text", COLUMN_COMMAND,
						    NULL);
  gtk_tree_view_column_set_sort_column_id(column, COLUMN_COMMAND);
  gtk_tree_view_append_column(GTK_TREE_VIEW(view), column);

  gtk_tree_view_set_enable_search(GTK_TREE_VIEW(view), TRUE);
  gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(view),
				      st_applications_preferences_page_search_equal_func,
				      NULL,
				      NULL);
  
  gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store),
				       COLUMN_LABEL,
				       GTK_SORT_ASCENDING);
  
  scrolled = gtk_scrolled_window_new(NULL, NULL);
  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
				 GTK_POLICY_AUTOMATIC,
				 GTK_POLICY_AUTOMATIC);
  gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);

  gtk_container_add(GTK_CONTAINER(scrolled), view);
  gtk_box_pack_start(GTK_BOX(page), scrolled, TRUE, TRUE, 0);
  gtk_widget_show_all(scrolled);

  g_object_unref(store);
}

static void
st_applications_preferences_page_cell_edited_h (GtkCellRendererText *cell,
						const char *path_string,
						const char *new_text,
						gpointer user_data)
{
  GtkListStore *store = user_data;
  GtkTreePath *path;
  GtkTreeIter iter;
  char *id;
  const char *command = *new_text ? new_text : NULL;
  
  path = gtk_tree_path_new_from_string(path_string);
  gtk_tree_model_get_iter(GTK_TREE_MODEL(store), &iter, path);
  gtk_tree_path_free(path);

  gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, COLUMN_ID, &id, -1);
  gtk_list_store_set(store, &iter, COLUMN_COMMAND, command, -1);
  st_action_associate(id, command);

  g_free(id);
}

static gboolean
st_applications_preferences_page_search_equal_func (GtkTreeModel *model,
						    int column,
						    const char *key,
						    GtkTreeIter *iter,
						    gpointer search_data)
{
  char *label;
  char *command;
  gboolean equal = FALSE;

  gtk_tree_model_get(model, iter,
		     COLUMN_LABEL, &label,
		     COLUMN_COMMAND, &command,
		     -1);

  equal = sg_utf8_strcasecontains(label, key) || sg_utf8_strcasecontains(command, key);

  g_free(label);
  g_free(command);

  return ! equal;
}

STPreferencesPage *
st_applications_preferences_page_new (void)
{
  return g_object_new(ST_TYPE_APPLICATIONS_PREFERENCES_PAGE, NULL);
}
