/* The GIMP -- an image manipulation program
 * Copyright (C) 1995-1998 Spencer Kimball and Peter Mattis
 *
 * Time-stamp: <2001/02/03 18:40:07 narazaki@gimp.org>
 *
 * guash-f.h -- This file is a part of guash.
 *
 * 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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

static void	query ();
static void	run (char *, int , GimpParam *, int *, GimpParam **);
static guchar *indexed_to_rgb (guchar, guchar *);

static void	guash_build_thumbnail_colormap ();
static void	guash_build_inhibit_suffix_table (GCHAR *);
static gint	guash_change_current_directory (GCHAR *, Thumbnail *);
static gint	guash_confirm_operation (GCHAR *);
static gint	guash_discard_events ();
static GCHAR *	guash_generate_unix_command (GCHAR *, GCHAR *, GCHAR *);
static GCHAR *	guash_get_image_filename (gint);
static Thumbnail *	guash_build_thumbnail_from_gimage (gint32, GCHAR *);
static Thumbnail *guash_get_image_from_file (GCHAR *, gint);
static directory_cache *guash_lookup_directory_cache (GCHAR *);
static void	guash_parse_gimprc ();
static void	guash_purge_subdirectory_information (GCHAR *);
static void	guash_set_fileselector_last_value (GCHAR *);
/* for directory_cache_set_to_cwd() ( FALSE, TRUE, GC ) */
#define RESCAN		(1 << 0)
#define REDRAW		(1 << 1)
#define	GC		(1 << 2)
static directory_cache *	guash_update_cwd_cache (gint);
static gint	guash_add_entry (GCHAR *, Thumbnail *);
static gboolean	guash_copy_image_file (GCHAR *, GCHAR *);
static gboolean	guash_delete_image_file (GCHAR *);
static gboolean	guash_move_image_file (GCHAR *, GCHAR *);
static gint	guash_open_image_file (GCHAR *);
static gint	guash_validate_src_file (GCHAR *);

static gint	selection_add (gint);
static gint	selection_add_and_show (gint);
static gint	selection_delete (gint);
static gint	selection_is_active ();
static gint	selection_length ();
static gint	selection_member_p (gint);
static void	selection_open_files ();
static gint	selection_reset ();
static gint	selection_reverse_member (gint);
static gint	selection_validate_image ();
#define SELECTION_ORDER_DEFAULT   0
#define SELECTION_ORDER_INDEX     0
#define SELECTION_ORDER_TIMESTAMP 1
static selection_iterator *selection_make_iterator (gint);
static gint	selection_iterator_compare_timestamp (void *, void *);
static selection_iterator_entry *selection_iterator_get_next_entry (selection_iterator *);
static Thumbnail *selection_iterator_get_next_thumbnail (selection_iterator *);
static void	selection_map_script ();
static void	selection_map_unix_command ();
static void	selection_map_jpeg_thumbnail ();
static void	selection_dump_as_html ();
static void	selection_dump_as_html_listing ();
static void	selection_dump_as_html_guash_table ();
static void	selection_open_files ();
static void	selection_copy_files_to (GCHAR *);
static void	selection_delete_files ();
static void	selection_move_files_to (GCHAR *);
#ifdef GIMP_VERSION
static void	thumbnail_panel_initialize_banner ();
static void	thumbnail_panel_reinitialize_banner ();
#endif
static void	thumbnail_panel_show_banner_step1 ();
static void	thumbnail_panel_show_banner_step2 ();
static void	thumbnail_panel_show_banner_step3 ();
static void	thumbnail_panel_clear_rectangle (gint, gint, gint, gint);
static void	thumbnail_panel_clear ();
static void	thumbnail_panel_draw_rgb (gint, gint, gint, gint, guchar *);
static void	thumbnail_panel_draw_image_buffer (image_buffer *, gint, gint, gint);
static void	thumbnail_panel_draw_string (GCHAR *, gint, gint, guchar *, gint, gint);
static gint	thumbnail_panel_draw_thumbnail (Thumbnail *);
static void	thumbnail_panel_set_directory_info ();
static void	thumbnail_panel_set_info (GCHAR *);
static void	thumbnail_panel_set_info_default ();
static void	thumbnail_panel_draw_frame (gint, gint);
static void	thumbnail_panel_draw_selection_frame (gint);
static void	thumbnail_panel_finalize_update ();
static void	thumbnail_panel_size_request (GtkWidget *,
					      GtkRequisition *);
static gint	thumbnail_panel_size_allocate (GtkWidget *, gpointer);
static gint	thumbnail_panel_update_rectangle (gint, gint, gint, gint);
static gint	thumbnail_panel_update ();
static void	thumbnail_panel_update_rubber_band (gint, gint);
static void	thumbnail_panel_finalize_rubber_band (gint);
static gint	thumbnail_panel_update_delayed (GtkWidget *);
static gint	thumbnail_panel_update_partially (gint);
static void	thumbnail_panel_update_sensitive_menu ();
static void	thumbnail_panel_update_selection_buttons ();
static void	thumbnail_panel_update_scroller ();
static void	thumbnail_panel_create_menu_for (GtkWidget *,
						 image_command_table *,
						 gint,
						 GtkAccelGroup *);
static GtkWidget*	_menu_create (image_command_table *, gint, GtkAccelGroup *);
static void	thumbnail_panel_create_menu ();
static gint	thumbnail_panel_move_focus (gint);
static void	directory_cache_initialize (directory_cache *);
static directory_cache *	directory_cache_new (GCHAR *);
static void	directory_cache_auto_shrink (directory_cache *, gint);
static gint	directory_cache_garbage_collect (directory_cache *);
static Thumbnail *	directory_cache_get_image (directory_cache *, GCHAR *);
static gint	directory_cache_add_directory (directory_cache *, GCHAR *, gint);
static gint	directory_cache_add_image (directory_cache *, GCHAR *, Thumbnail *, gint);
static gint	directory_cache_num_entry (directory_cache *);
static gint	directory_cache_valid_index (directory_cache *, gint);
static gint	directory_cache_valid_subdirectory_index (directory_cache *, gint);
static gint	directory_cache_valid_image_index (directory_cache *, gint);
static directory_cache *	directory_cache_of (GCHAR *);
static void	directory_cache_reorder (directory_cache *);
static void	directory_cache_table_aging (gpointer, gpointer, gpointer);
static void	directory_cache_table_purge_subdirectory (gpointer, gpointer, gpointer);
static void	directory_cache_table_recycler (gpointer, gpointer, gpointer);
static Thumbnail *	directory_cache_get_nth (directory_cache *, gint);
static Thumbnail *	directory_cache_lookup (directory_cache *, GCHAR *);
static gint	directory_cache_make_thumbnail_directory (directory_cache *);
static gint	directory_cache_save_thumbnail_to (directory_cache *, Thumbnail *);
static gint	directory_cache_delete_invalid_cache_files (directory_cache *, gint);
static GtkWidget *	directory_cache_create_parents_menu ();
static void	directory_cache_create_history_menu_foreach (gpointer, gpointer, gpointer);
static GtkWidget *	directory_cache_create_history_menu ();
static gint	directory_cache_update_selection (directory_cache *, gint, gint);
static gint	directory_cache_update_thumbnail_for (directory_cache *, GCHAR *, Thumbnail *);

static gint	cwd_cache_jump_to_subdirectory_index (gint);
static gint	cwd_cache_npage ();
#define SELECTION_ADD	 1
#define SELECTION_DELETE 2
#define SELECTION_DISORDER 3
static gint	cwd_cache_validate ();
static gint	cwd_cache_update ();
static gint	cwd_cache_update_after_file_operation (gint, GCHAR *, GCHAR *, GCHAR *);
static void	display_request_initialize ();
static void	display_request_set_handler ();
static void	display_request_redraw ();
static void	display_request_redraw_rect (gint, gint, gint, gint);
static void	display_request_finalize ();
static gint	display_request_handler ();

static image_buffer *	image_buffer_new (gint, gint, gint);
static void	image_buffer_resize (image_buffer *, gint, gint, gint);
static void	image_buffer_free (image_buffer *);
static image_buffer *	image_buffer_new_with_header (gchar *, gint, gint);
static image_buffer *	image_buffer_set_from_header (image_buffer *, gchar *, gint, gint);
static void	image_buffer_copy (image_buffer *, image_buffer *);
#ifdef DEFINE_OLD
static void	image_buffer_copy_from_drawable (image_buffer *, gint32);
#endif
static void	image_buffer_copy_to_drawable (image_buffer *, gint32);
static void	thumbnail_initialize (Thumbnail *);
static gint	thumbnail_compare_name (Thumbnail *, Thumbnail *);
static void	thumbnail_copy_data (Thumbnail *, Thumbnail *, gint);
static void	thumbnail_free_image (Thumbnail *);
static gint	thumbnail_save_as_jpeg_thumbnail (Thumbnail *, GCHAR *);
static GCHAR *	pathname_build_thumbnail_dirname (GCHAR *);
static GCHAR *	pathname_build_thumbnail_filename (GCHAR *);
static GCHAR *	pathname_build_jpeg_thumbnail_filename (GCHAR *);
static GCHAR *	pathname_get_canonical_name (GCHAR *);
static gint	pathname_get_last_period_index (GCHAR *);
static gint	pathname_get_last_separator_index (GCHAR *);
static GCHAR *	pathname_get_directoryname (GCHAR *);
static GCHAR *	pathname_get_vaild_directoryname (GCHAR *);
static GCHAR *	pathname_get_basename (GCHAR *);
static gint	pathname_is_valid_thumbnail_filename (GCHAR *);
static gint	pathname_match_inhibit_suffix (GCHAR *);

static gint	os_file_change_current_directory (GCHAR *);
static void	os_file_get_current_directory (GCHAR *);
static gdouble	os_file_get_modify_timestamp (GCHAR *);
static gint	os_file_alphasort (GCHAR **, GCHAR **);
static gint	os_file_mtimesort (GCHAR **, GCHAR **);
typedef int	(*scandir_selector_function) (GCHAR *);
static gint	os_scandir_selector (GCHAR *);
static gint	os_scandir (GCHAR *, GCHAR ***, scandir_selector_function, gint);
typedef	int	(*sort_compare_function)(const void *, const void *);
static gint	os_copy_file (GCHAR *, GCHAR *);
static gint	os_delete_file (GCHAR *);
static gint	os_file_is_writable (GCHAR *);
static gint	os_file_kind (GCHAR *, gint);
static gint	os_file_size (GCHAR *);
static gint	os_mkdir (GCHAR *);
static gint	os_make_directory (GCHAR *, gint);
static gint	os_rename_file (GCHAR *, GCHAR *);
static gint	DIALOG ();
static gint	timer_initialize_guash (gpointer);
static gint	timer_start_guash (gpointer);
static gint	timer_directory_monitor ();
static gint	about_dialog ();
static void	menu_change_directory_callback (GtkWidget *, gpointer);
static void	directory_jump_callback (GtkWidget *, gpointer);
static void	parent_directory_callback (GtkWidget *, gpointer);
static void	forward_callback (GtkWidget *, gpointer);
static void	select_and_forward_callback (GtkWidget *, gpointer);
static void	backward_callback (GtkWidget *, gpointer);
static void	next_callback (GtkWidget *, gpointer);
static void	prev_callback (GtkWidget *, gpointer);
static void	next_page_callback (GtkWidget *, gpointer);
static void	prev_page_callback (GtkWidget *, gpointer);
static void	first_page_callback (GtkWidget *, gpointer);
static void	last_page_callback (GtkWidget *, gpointer);
static void	show_comment_callback (GtkWidget *, gpointer);
static void	open_callback (GtkWidget *, gpointer);
static void	redraw_callback (GtkWidget *, gpointer);
static void	update_callback (GtkWidget *, gpointer);
static void	toggle_display_mode_callback (GtkWidget *, gpointer);
static void	toggle_save_mode_callback (GtkWidget *, gpointer);
static void	toggle_sort_mode_callback (GtkWidget *, gpointer);
static void	purge_selected_thumbnail_file_callback (GtkWidget *, gpointer);
static void	purge_thumbnail_file_callback (GtkWidget *, gpointer);
#ifdef UNDER_DEVELOPMENT
static void	unimplement_callback (GtkWidget *, gpointer);
#endif
static void	help_callback (GtkWidget *, gpointer);
static void	fileselector_for_copy_callback (GtkWidget *, gpointer);
static void	fileselector_for_move_callback (GtkWidget *, gpointer);
static void	fileselector_for_move_directory_callback (GtkWidget *, gpointer);
static void	fileselector_for_chdir_callback (GtkWidget *, gpointer);
static void	fileselector_for_mkdir_callback (GtkWidget *, gpointer);
static void	copy_callback (GtkWidget *, gpointer);
static void	move_callback (GtkWidget *, gpointer);
static void	move_directory_callback (GtkWidget *, gpointer);
static void	delete_callback (GtkWidget *, gpointer);
static void	delete_directory_callback (GtkWidget *, gpointer);
static void	select_all_callback (GtkWidget *, gpointer);
#ifdef VISIBLE_HTML_THUMBNAIL_NAME
static void	select_all_jpeg_thumbnail_callback (GtkWidget *, gpointer);
#endif
static void	select_none_callback (GtkWidget *, gpointer);
static void	chdir_callback (GtkWidget *, gpointer);
static void	mkdir_callback (GtkWidget *, gpointer);
static void	mount_callback (GtkWidget *, gpointer);
static void	unmount_callback (GtkWidget *, gpointer);
static void	selection_map_script_callback (GtkWidget *, gpointer);
static void	selection_map_unix_command_callback (GtkWidget *, gpointer);
static void	selection_dump_as_html_callback (GtkWidget *, gpointer);
static void	selection_dump_as_html_listing_callback (GtkWidget *, gpointer);
static void	selection_dump_as_html_guash_table_callback (GtkWidget *, gpointer);
static void	jump_to_subdir1_callback (GtkWidget *, gpointer);
static void	jump_to_subdir2_callback (GtkWidget *, gpointer);
static void	jump_to_subdir3_callback (GtkWidget *, gpointer);
static void	jump_to_subdir4_callback (GtkWidget *, gpointer);
static void	jump_to_subdir5_callback (GtkWidget *, gpointer);
static void	jump_to_subdir6_callback (GtkWidget *, gpointer);
static void	jump_to_subdir7_callback (GtkWidget *, gpointer);
static void	jump_to_subdir8_callback (GtkWidget *, gpointer);
static void	jump_to_subdir9_callback (GtkWidget *, gpointer);
static gint	thumbnail_panel_event_handler (GtkWidget *, GdkEvent *);
static gint	cursor_event_handler (GtkWidget *, GdkEventKey *);
static void	dnd_drag_button_callback (GtkWidget *, GdkEvent *);
static void	dnd_drag_begin_callback (GtkWidget *, GdkDragContext *);
static void	dnd_drag_request_callback (GtkWidget *, GdkDragContext *, GtkSelectionData *, guint, guint, gpointer);
static void	dnd_drag_motion_callback (GtkWidget *, GdkDragContext *, gint, gint, guint);
static gint	dnd_drag_motion_timeout ();
static void	dnd_source_delete_data (GtkWidget *, GdkDragContext *, gpointer);
static void	dnd_data_received (GtkWidget *, GdkDragContext *, gint, gint, GtkSelectionData *, guint, guint);
static gboolean	dnd_drop_callback (GtkWidget *, GdkDragContext *, gint, gint, guint);
static gint	dnd_copy_files_to (GCHAR *, GCHAR *, GCHAR *, gint, gint);
static gint	save_thumbnail_as_xvpict_image (char *, Thumbnail *);
static Thumbnail *	load_xvpict_image (char *);
