/**************************************************************/
/////////////////////  5.2.10 ///////////////////////////////////
/**************************************************************/

#ifndef __RFM_TYPES_H__
#define __RFM_TYPES_H__
#include <string.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <semaphore.h>
#include <gmodule.h>
#include <glob.h>

/* increment this MACRO whenever any change is done to structures
 * (to avoid incorrect memory accesses by modules)
 * Must be an integer. 
 * */
#define LIBRFM_SERIAL 538
#define  LIBRFM_MODULE \
void *module_sanity(void){ \
    return (GINT_TO_POINTER(LIBRFM_SERIAL)); \
}

#if GLIB_MAJOR_VERSION==2 && GLIB_MINOR_VERSION>=32
# define RfmRecMutex GRecMutex
# define RfmRWLock GRWLock 
# define RFM_RW_LOCK_INIT(X) RfmRWLock X
#else
# define RfmRecMutex GStaticRecMutex
# define RfmRWLock GStaticRWLock
# define RFM_RW_LOCK_INIT(X) RfmRWLock X = G_STATIC_RW_LOCK_INIT
#endif

/**************************************************************/
/////////////////////  record_entry_t //////////////////////////
/**************************************************************/

typedef struct record_entry_t	/* was: record_entry_t */ 
{
    gint type;			
    struct stat *st;
    gchar *mimetype;
    gchar *mimemagic;
    gchar *filetype;
    gchar *encoding;
    gchar *tag;
    gchar *path;
    gchar *pseudo_path;
    const gchar *module;	/* module name, or NULL for local files */
    const gchar *parent_module;	/* module name, or NULL for local files */
}
record_entry_t;

/**************************************************************/
/////////////////////  rfm_global_t /////////////////////////
/**************************************************************/
typedef struct rfm_global_t
{
  gint 		argc; 		/* partial argument list */
  gchar 	**argv; 	/* partial argument list */

  Display 	*Xdisplay;
  Drawable 	root_Xwindow;
  Visual 	*Xvisual;

  // GThread	*self;	
  // In the 3.6 threading paradigm, self is replaced by main_context
  // We now use rfm_get_gtk_thread(), which is set by rfm_init()
  // or later by rfm_set_gtk_thread().

  GtkWidget 	*window; 		// main  window 

  // list of valid views (necessary for tabbed iconview)

  RfmRWLock    setup_lock;

  // A write lock must be obtained to destroy the window:
  RfmRWLock	window_lock;
  GCond		*janitor_signal;
  GCond		*status_signal;
  GMutex	*status_mutex;
  gint		status;
  gint		thread_count;
  GThreadPool	*thread_queue;
  gint          cores;

  void 		*settings_widgets_p;
#if GTK_MAJOR_VERSION==3 
  GdkDevice     *pointer;  
#endif
}
rfm_global_t;







/**************************************************************/
/////////////////////  xfdir_t /////////////////////////////////
/**************************************************************/

typedef struct dir_t
{
    gchar		*pathv;		/* matched pathname.  */
    record_entry_t	 *en;

}
dir_t;


typedef struct xfdir_t
{
    size_t 		pathc;		/* Count of paths matched */
    dir_t 		*gl;
    void 		*data;
    off_t 		tama;
    guint		monitor_id;
    guint		view_id;
    //flags
    gboolean		reload;
    gboolean		invalidate_icons;
    gint		preferences;
    gint		sort_column;
    struct view_t	*view_p;
    GThread 		*thread;
    void		*control_p;
    record_entry_t	*en;

}
xfdir_t;

/**************************************************************/
/////////////////////   population_t ///////////////////////////
/**************************************************************/


typedef struct population_t {
    record_entry_t 	*en;
    gchar		*icon_id;
    gchar		*label;
    GdkPixbuf 		*pixbuf; // extra reference in pixbuf hash
    GdkPixbuf		*thumbnail; // extra reference in pixbuf hash
    GdkPixbuf 		*preview_pixbuf;  // referenced: for tooltip and properties preview
    PangoLayout 	*layout;
    PangoLayout 	*layout2;
    PangoLayout 	*layout_full;

    PangoRectangle 	logical_rect;
    PangoRectangle 	logical_rect2;
    PangoRectangle 	logical_rect_full;
    
    struct view_t	*view_p;
    gint 		population_serial;
    const gchar 	*module;	
    gboolean		content_icon;

    gint 		icon_size; // current icon size 
    gint 		icon_size_id; // This allows id == 0 for details view 
    gint		flags;
// normal_tip: preview was tried but not accomplished
			// normal_tip	POPULATION_NORMAL_TIP
			// preview_done	POPULATION_PREVIEW_DONE
 // preview_busy: for tooltip and properties preview
			// preview_busy	POPULATION_PREVIEW_BUSY
			// selected	POPULATION_SELECTED
			// saturated	POPULATION_SATURATED
			// thumbnailed	POPULATION_THUMBNAILED
			// cut		POPULATION_CUT
			// copied	POPULATION_COPIED
			// short_icon	POPULATION_SHORT_ICON
    
    gint 		row;   
    gint 		column;
    
    //PangoLayout 	*extension;
    //PangoRectangle 	extension_rect;
} population_t;


/**************************************************************/
/////////////////////  widgets_t ///////////////////////////////
/**************************************************************/

typedef struct widgets_t { 
    struct view_t	*view_p;		// view_t * parent
    gchar		*workdir;		// current workdir

    void 		*data;			// Available to plugins

    GtkWidget 		*paper; 		// drawing area
    GtkWidget 		*diagnostics;		// diagnostics text area
    GtkWidget 		*diagnostics_window;	// window to place diagnostics
    GtkWidget 		*status;		// status text area
    GtkWidget 		*rename;		// rename entry box
    GtkWidget 		*button_space;		// little button space
    GtkWidget 		*clear_button;		// clear text area button
#if 0
    // notebook is only for gridview
    GtkScrolledWindow 	*scrolled_window;	// viewport for drawing area
    GtkWidget 		*vpane;			// drawing/diagnostics pane
    GtkWidget 		**notebook; 		// notebook
    GtkWidget 		*page_child; 		// notebook page
    GtkWidget 		*page_icon; 		// notebook tab icon
    GtkWidget 		*page_label; 		// notebook tab label
    GtkWidget 		*page_button; 		// notebook remove button
    GtkWidget 		*page_menu_label_box; 	// notebook menu box
    GtkWidget 		*size_scale;		// 
#endif
} widgets_t;



/**************************************************************/
/////////////////////   eyecandy_t  ////////////////////////////
/**************************************************************/

typedef struct eyecandy_t {
    cairo_surface_t	*bg_surface;
    gchar		*desktop_bg_file;
    gchar		*desktop_color;
    gchar		*iconview_color;
}eyecandy_t;

/**************************************************************/
/////////////////////   mouse_event_t  /////////////////////////
/**************************************************************/

typedef struct mouse_event_t {
    // mouse events
    guint32 		eventtime;  	/* eventtime for module popup menu */  
    gboolean		rubberbanding;
    gint 		single_click_mode_state;
    GdkDragAction 	drag_action;
    GdkEventDND 	drag_event;
    GdkPixbuf 		*dnd_pixbuf;
    GtkTargetList	*target_list;
    gint 		current_mouseX;	//
    gint 		current_mouseY;	//
    gint 		old_X;		//
    gint 		old_Y;		//
    gint 		boxX;		//
    gint 		boxY;		//
    gdouble 		initial_x;
    gdouble 		mouseX;
    gdouble 		initial_y;
    gdouble 		mouseY;
    gdouble 		offset_x;
    gdouble 		offset_y;
    const population_t 	*selected_p;
    const population_t 	*doing_drag_p;
    const population_t 	*saturated_p;
    const population_t 	*label_p;	
    gboolean 		dragstate;
} mouse_event_t;

/**************************************************************/
/////////////////////   view_layout_t  ///////////////////////
/**************************************************************/

typedef struct view_layout_t {
    gint 		tripwire; // set if value is set

    gint 		max_elements;	
    gint 		cellwidth;	
    gint 		cellheight;	
    gint 		grid_rows;
    gint 		grid_columns;   
    gint 		grid_area;	
    GtkAllocation 	vpane_allocation;	// only for gridview

    gint 		icon_size;
    gint 		paperX;			// configuration parameter
    gint 		paperY;			// configuration parameter
    gint 		window_width;		// configuration parameter
    gint 		window_height;		// configuration parameter
    gint		margin_top;
    gint		margin_bottom;
    gint		margin_left;
    gint		margin_right;

    gint 		text_height;	//
    gint 		column_width;	//
    gint 		root_w;
    gint 		root_h;
    gint 		root_d;
    gint		name_width;
    gint		details_width;
} view_layout_t;

/**************************************************************/
/////////////////////   mutexes_t   ////////////////////////////
/**************************************************************/

typedef struct mutexes_t {
    GMutex		*reload_mutex;
    GMutex		*status_mutex;

    GMutex		*population_serial;
    GMutex		*monitor_control; 
    GMutex		*monitor_run_mutex; 
    GCond		*monitor_signal;
    GCond		*monitor_run_signal;
    RfmRWLock		population_rwlock;
    RfmRWLock		view_lock;
    RfmRWLock		monitor_lock;

} mutexes_t;

/**************************************************************/
/////////////////////   flags_t     ////////////////////////////
/**************************************************************/

typedef struct flags_t {
    gboolean		refresh;

    gboolean 		enable_buffer_surface;   
    // redraw deskview buffer pixbuf
    gboolean 		monitor_enabled;
    gboolean 		thumbnailer_active;
    gboolean 		thumbnailer_exit;
    gboolean		monitor_go;
    gboolean		active_monitor;
    gint 		preferences;	//
    gint 		serial;
    gint 		type;		// iconview type:
    gint 		sortcolumn;	//
    gint 		count; 		// to monitor load progress
    gint 		status;
    gint 		monitor_id;
    gint		pasteboard_serial;
    gint		bookmark_serial;
    gint		population_serial;   
    gint		saturation_serial;   
    gint		thread_count;

} flags_t;

/**************************************************************/
/////////////////////   view_t /////////////////////////////////
/**************************************************************/

typedef struct view_t {
    record_entry_t 	*en;			// folder entry
    gchar 		*desktop_dir;		// used by deskview
    gchar 		*lp_command;
    gchar 		*xbuffer; 
    gchar 		*deepest_dir; 

    GSList 		*selection_list;
    GSList 		*reselect_list;
    GList 		*go_list;
    GSList 		*f_list;
    GList 		*sh_command;
    GdkPixbuf		*bg_pixbuf;

    widgets_t 		widgets;

    view_layout_t	view_layout;
    mouse_event_t	mouse_event;
    eyecandy_t		eyecandy;
    mutexes_t		mutexes;
    flags_t		flags;

    gboolean            expose_hold;
    gboolean            monitor_running;
    gint 		sh_command_counter;
    
    

    gulong		signal_handlers[1];

    population_t 	**population_pp;
    GHashTable          *population_hash;

    const gchar 	*module;
    /* constructor functions: */
    struct view_t	*(*constructor)(record_entry_t *en); 		
    void 		(*child_constructor)(struct widgets_t *widgets_p, 
				    gchar *path);
    void 		(*tab_constructor)(struct widgets_t *widgets_p, 
				    const gchar *path);
    void 		(*tab_destructor)(struct view_t *view_p);
    void		*user_data;

} view_t;
    

#endif
