/*
 *  Copyright (C) 2002  Ricardo Fernández Pascual
 *
 *  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 2, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "bookmarks.h"
#include "xbel.h"
#include "bookmarks-editor.h"
#include "bookmarks-iterator.h"
#include <glib.h>
#include <string.h>

#include <gtk/gtkwindow.h>
#include <gtk/gtkbutton.h>
#include <gtk/gtkvbox.h>
#include <gtk/gtkmain.h>
#include <libgnome/gnome-program.h>
#include <libgnomeui/gnome-ui-init.h>


static void
url_modified_cb (GbSite *b, const gchar *new_url)
{
	g_print ("url modified: %s, %s, %s\n", GB_BOOKMARK (b)->name, 
		 b->url, new_url);
}

static void
name_modified_cb (GbBookmark *b, const gchar *new_name)
{
	g_print ("name modified: %s, %s\n", GB_BOOKMARK (b)->name, new_name);
}

static void
modified_cb (GbBookmark *b)
{
	g_print ("modified: %s\n", b->name);
}

static void
child_added_cb (GbFolder *f, GbBookmark *c, gint pos)
{
	g_print ("child added: %s, %s, %d\n", GB_BOOKMARK (f)->name,
		 c->name, pos);
}

static void
child_removed_cb (GbFolder *f, GbBookmark *c)
{
	g_print ("child removed: %s, %s\n", GB_BOOKMARK (f)->name, c->name);
}

static void
child_moved_cb (GbFolder *f, GbBookmark *c, gint pos, gint oldpos)
{
	g_print ("child moved: %s, %s, %d, %d\n", GB_BOOKMARK (f)->name,
		 c->name, pos, oldpos);
}

static GbBookmarkSet * 
test_load (const gchar *filename)
{
	GbXBEL *io = gb_xbel_new ();
	GbBookmarkSet *set;

	g_print ("trying to load %s\n", filename);

	set = gb_io_load_from_file (GB_IO (io), filename);
		
	return set;
}

static void 
test_save (GbBookmarkSet *set, const gchar *filename)
{
	GbXBEL *io = gb_xbel_new ();
	g_print ("trying to save %s\n", filename);
	gb_io_save_to_file (GB_IO (io), set, filename);
}

static gboolean
close_editor (GtkWidget *widget,
	      GdkEvent *event,
	      gpointer user_data)
{
	GbEditor *e = GB_EDITOR (user_data);
	g_object_unref (G_OBJECT (e));
	return FALSE;
}

static void
show_new_editor (GtkButton *b, GbBookmarkSet *set)
{
	GbTreeModel *tm;
	GbEditor *e;
	GtkWidget *mw;
	GSList *l = g_slist_prepend (NULL, set->root);
	tm = gb_tree_model_new (l);
	e = gb_editor_new (tm);
	gtk_widget_show (gb_editor_get_main_widget (e));
	g_object_unref (tm);
	mw = gb_editor_get_main_widget (e);
	g_signal_connect (mw, "delete-event", G_CALLBACK (close_editor), e);
	
}

static void
quit_cb (GtkButton *b, GbBookmarkSet *set)
{
	g_object_unref (G_OBJECT (set));

	gtk_main_quit ();
}

int 
main (int argc, char *argv[])
{
	gchar *filename = argc == 2 ? argv[1] 
		: g_strconcat (g_get_home_dir (),
			       "/.galeon/bookmarks.xbel", NULL);
	GbBookmarkSet *set;
	GbFolder *folder1, *folder2, *r;
	GbSite *site1, *site2;
	GbBookmark *alias;

	gnome_program_init (PACKAGE, VERSION,
			    LIBGNOMEUI_MODULE, argc, argv,
			    GNOME_PARAM_HUMAN_READABLE_NAME, "Bookmarks Tester",
			    NULL);
	
	set = gb_bookmark_set_new ();
	folder1 = gb_folder_new (set, "Folder 1");
	site1 = gb_site_new (set, "Site 1", "http://www.gnome.org");
	
	g_signal_connect (site1, "url-modified", G_CALLBACK (url_modified_cb), NULL);
	g_signal_connect (site1, "name-modified", G_CALLBACK (name_modified_cb), NULL);
	g_signal_connect (site1, "modified", G_CALLBACK (modified_cb), NULL);

	g_signal_connect (folder1, "name-modified", G_CALLBACK (name_modified_cb), NULL);
	g_signal_connect (folder1, "modified", G_CALLBACK (modified_cb), NULL);
	g_signal_connect (folder1, "child-added", G_CALLBACK (child_added_cb), NULL);
	g_signal_connect (folder1, "child-removed", G_CALLBACK (child_removed_cb), NULL);
	g_signal_connect (folder1, "child-moved", G_CALLBACK (child_moved_cb), NULL);

	gb_site_set_url (site1, "http://galeon.sourceforge.net");
	gb_bookmark_set_name (GB_BOOKMARK (site1), "Same site");

	gb_bookmark_set_name (GB_BOOKMARK (folder1), "Folder1");

	gb_folder_add_child (folder1, GB_BOOKMARK (site1), -1);
	g_object_unref (G_OBJECT (site1));

	folder2 = gb_folder_new (set, "folder2");
	g_signal_connect (folder2, "child-added", G_CALLBACK (child_added_cb), NULL);
	g_signal_connect (folder2, "child-removed", G_CALLBACK (child_removed_cb), NULL);
	site2 = gb_site_new (set, "site2", "http://developer.gnome.org");
	gb_folder_add_child (folder2, GB_BOOKMARK (site2), -1);
	g_object_unref (G_OBJECT (site2));

	/* will remove site1 from folder1 */
	gb_folder_add_child (folder2, GB_BOOKMARK (site1), -1);

	alias = gb_bookmark_alias_create (GB_BOOKMARK (folder2), NULL);
	gb_folder_add_child (folder2, alias, 1);
	g_object_unref (G_OBJECT (alias));

	gb_bookmark_set_pixmap (alias, "xxx.png");
	g_assert (alias->pixmap_file == ((GbBookmark *) folder2)->pixmap_file);
	g_assert (!strcmp (alias->pixmap_file, "xxx.png"));

	r = gb_folder_new (set, "root folder");
	gb_bookmark_set_set_root (set, r);
	g_object_unref (G_OBJECT (r));

	gb_folder_add_child (r, GB_BOOKMARK (folder1), 0);
	gb_folder_add_child (r, GB_BOOKMARK (folder2), 1);
	test_save (set, "test_save1.xbel");

	g_object_unref (G_OBJECT (folder1));
	g_object_unref (G_OBJECT (folder2));
	
	g_object_unref (G_OBJECT (set));


	set = test_load (filename);

	{
		GbIterator *i = gb_iterator_new (set);
		GbBookmark *bi;
		while ((bi = gb_iterator_next (i)))
		{
			g_print ("iterating: %s\n", bi->name);
		}
		g_object_unref (G_OBJECT (i));
	}

	/* no recursion, just one level */
	{
		GbIterator *i = gb_iterator_new_folder (set->root, FALSE);
		GbBookmark *bi;
		while ((bi = gb_iterator_next (i)))
		{
			g_print ("iterating: %s\n", bi->name);
			if (GB_IS_FOLDER (bi))
			{
				/* you may want to iterate recursively this folder */
				/* you can do it here, if it's an alias if will have no childs */
				GbIterator *j = gb_iterator_new_folder (GB_FOLDER (bi), FALSE);
				int c = 0;
				while (gb_iterator_next (j))
				{
					++c;
				}
				g_print ("\tfound %d children\n", c);
				g_object_unref (G_OBJECT (j));
			}
		}
		g_object_unref (G_OBJECT (i));
	}

	test_save (set, "test_save.xbel");

	{
		GtkWidget *w;
		GtkWidget *b;
		GtkWidget *vbox;
		w = gtk_window_new (GTK_WINDOW_TOPLEVEL);
		vbox = gtk_vbox_new (FALSE, 0);
		gtk_container_add (GTK_CONTAINER (w), vbox);
		gtk_widget_show (vbox);
		b = gtk_button_new_with_label ("edit");
		gtk_container_add (GTK_CONTAINER (vbox), b);
		gtk_widget_show (b);
		g_signal_connect (b, "clicked", G_CALLBACK (show_new_editor), set);
		b = gtk_button_new_with_label ("quit");
		gtk_container_add (GTK_CONTAINER (vbox), b);
		gtk_widget_show (b);
		g_signal_connect (b, "clicked", G_CALLBACK (quit_cb), set);
		gtk_widget_show (w);
		gtk_main ();
	}

	g_free (filename);

	return 0;
}

