/*
 * Mail Notification
 * Copyright (C) 2003-2008 Jean-Yves Lefort <jylefort@brutele.be>
 *
 * 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, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

%headertop{
#include <gtk/gtk.h>
%}

%{
#include <glib/gi18n.h>
#if WITH_SASL
#include <sasl/sasl.h>
#include "mn-sasl.h"
#endif /* WITH_SASL */
#include "mn-util.h"

enum
{
  COLUMN_MECHANISM,
  COLUMN_LABEL,
  N_COLUMNS
};
%}

class MN:Auth:Combo:Box from Gtk:Combo:Box
{
  property STRING active_mechanism (export)
    set
    {
      const char *mechanism = g_value_get_string(VAL);
      GtkTreeModel *model;
      GtkTreeIter iter;
      gboolean valid;

      model = gtk_combo_box_get_model(GTK_COMBO_BOX(self));

      MN_TREE_MODEL_FOREACH(valid, &iter, model)
	{
	  char *this_mech;
	  gboolean found;

	  gtk_tree_model_get(model, &iter, COLUMN_MECHANISM, &this_mech, -1);
	  found = (! this_mech && ! mechanism)
	    || (this_mech && mechanism && ! strcmp(this_mech, mechanism));
	  g_free(this_mech);

	  if (found)
	    {
	      gtk_combo_box_set_active_iter(GTK_COMBO_BOX(self), &iter);
	      break;
	    }
	}
    }
    get
    {
      char *mechanism = NULL;
      GtkTreeIter iter;

      if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(self), &iter))
	{
	  GtkTreeModel *model = gtk_combo_box_get_model(GTK_COMBO_BOX(self));
	  gtk_tree_model_get(model, &iter, COLUMN_MECHANISM, &mechanism, -1);
	}

      g_value_take_string(VAL, mechanism);
    };

  init (self)
  {
    GtkListStore *store;
    GtkCellRenderer *renderer;

    store = gtk_list_store_new(N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING);
    gtk_combo_box_set_model(GTK_COMBO_BOX(self), GTK_TREE_MODEL(store));
    g_object_unref(store);

    renderer = gtk_cell_renderer_text_new();
    gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(self), renderer, TRUE);
    gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(self), renderer,
				   "text", COLUMN_LABEL,
				   NULL);

    self_append(self, NULL, _("Autodetect"));
#if WITH_SASL
    if (mn_sasl_init(NULL))
      {
        const char **mechanisms;

	mechanisms = sasl_global_listmech();
	if (mechanisms)
	  {
	    int i;
	    for (i = 0; mechanisms[i]; i++)
	      self_append(self, mechanisms[i], mechanisms[i]);
	  }
      }
#endif /* WITH_SASL */

    gtk_tree_sortable_set_default_sort_func(GTK_TREE_SORTABLE(store), self_sort_cb, NULL, NULL);
    gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_ASCENDING);

    self_set_active_mechanism(self, NULL);
  }

  private int
    sort_cb (GtkTreeModel *model,
	     GtkTreeIter *a,
	     GtkTreeIter *b,
	     gpointer user_data)
  {
    char *mechanism_a;
    char *label_a;
    char *mechanism_b;
    char *label_b;
    int coll;

    gtk_tree_model_get(model, a,
		       COLUMN_MECHANISM, &mechanism_a,
		       COLUMN_LABEL, &label_a,
		       -1);
    gtk_tree_model_get(model, b,
		       COLUMN_MECHANISM, &mechanism_b,
		       COLUMN_LABEL, &label_b,
		       -1);

    /* put "autodetect" (NULL mechanism) on top of the list */
    if (mechanism_a && mechanism_b)
      coll = g_utf8_collate(label_a, label_b);
    else if (mechanism_a || mechanism_b)
      coll = mechanism_a ? 1 : -1;
    else
      coll = 0;

    g_free(mechanism_a);
    g_free(mechanism_b);

    return coll;
  }

  public void
    append (self, const char *mechanism, const char *label (check null))
  {
    GtkTreeModel *model;
    GtkTreeIter iter;

    model = gtk_combo_box_get_model(GTK_COMBO_BOX(self));

    gtk_list_store_append(GTK_LIST_STORE(model), &iter);
    gtk_list_store_set(GTK_LIST_STORE(model), &iter,
		       COLUMN_MECHANISM, mechanism,
		       COLUMN_LABEL, label,
		       -1);
  }

  public GtkWidget *
    new (void)
  {
    return GTK_WIDGET(GET_NEW);
  }
}
