/*
				  ImgView
 */

#ifndef IMGVIEW_H
#define IMGVIEW_H

#include <gtk/gtk.h>


/*
 *	Drag Modes:
 */
typedef enum {
	IMGVIEW_DRAG_MODE_NONE,
	IMGVIEW_DRAG_MODE_TRANSLATE,
	IMGVIEW_DRAG_MODE_ZOOM,
	IMGVIEW_DRAG_MODE_ZOOM_RECTANGLE,
	IMGVIEW_DRAG_MODE_CROP_RECTANGLE,
	IMGVIEW_DRAG_MODE_COLOR_PROBE
} imgview_drag_mode;

/*
 *	Image Data Formats:
 */
typedef enum {
	IMGVIEW_FORMAT_GREYSCALE8		= 10,	/* 1 bpp */
	IMGVIEW_FORMAT_GREYSCALE16		= 11,	/* 2 bpp */
	IMGVIEW_FORMAT_GREYSCALE32		= 12,	/* 4 bpp */
	IMGVIEW_FORMAT_GREYSCALEA32		= 13,	/* 4 bpp */
	IMGVIEW_FORMAT_RGB			= 20,	/* 3 bpp */
	IMGVIEW_FORMAT_RGBA			= 21	/* 4 bpp */
} imgview_format;

/*
 *	Alpha Channel Flags:
 */
typedef enum {

	/* Alpha channel is defined and is not uniform */
	IMGVIEW_ALPHA_DEFINED			= (1 << 0),

	/* Use thresholding instead of blending the alpha value */
	IMGVIEW_ALPHA_THRESHOLD			= (1 << 1),

	/* Alpha values are inverted (0xff = transparent and 0x00
	 * means solid) */
	IMGVIEW_ALPHA_INVERTED			= (1 << 2)

} imgview_alpha_flags;        


/*
 *	Crop Flags:
 */
typedef enum {

	/* Crop is allowed */
	IMGVIEW_CROP_ALLOWED			= (1 << 0),

	/* Crop rectangle defined (or is being defined) by user in the
	 * middle of a drag crop rectangle */
	IMGVIEW_CROP_DEFINED			= (1 << 1),

	/* Crop rectangle defined and finalized */
	IMGVIEW_CROP_FINALIZED			= (1 << 2)

} imgview_crop_flags;


typedef struct _imgview_struct		imgview_struct;
typedef struct _imgview_image_struct	imgview_image_struct;
typedef struct _imgview_cropdlg_struct	imgview_cropdlg_struct;


/*
 *	ImgView Image:
 */
struct _imgview_image_struct {

	gint		visual_depth;	/* Depth in bits per pixel of the
					 * associated GdkDrawable
					 */

	gint		bpp;		/* Allocated bytes per pixel */
	gint		bpl;		/* Allocated bytes per line */

	gint		width,		/* Size in pixels */
			height;

	guint8		*mem;		/* Image data buffer, allocated to
					 * the size of bpl * height bytes
					 */
};
#define IMGVIEW_IMAGE(p)	((imgview_image_struct *)(p))

/*
 *	ImgView Crop Dialog:
 */
struct _imgview_cropdlg_struct {

	GtkWidget	*toplevel;
	GtkAccelGroup	*accelgrp;
	imgview_struct	*imgview;

	GtkWidget	*val_label,
			*val2_label,
			*crop_btn,
			*cancel_btn;

	GdkRectangle	rect;		/* Crop Geometry */

};
#define IMGVIEW_CROPDLG(p)	((imgview_cropdlg_struct *)(p))

/*
 *	ImgView:
 */
struct _imgview_struct {

        GtkWidget	*toplevel;
	GtkAccelGroup	*accelgrp;
	gboolean	map_state;
	gint		freeze_count,
			busy_count;

	/* If this is a stand alone viewer window, then this will be
	 * set to true, indicating toplevel is a GtkWindow (otherwise
	 * toplevel will be a GtkVBox)
	 */
	gboolean	toplevel_is_window;

	/* Specifies if geometry, zoom, zoom rectangular, etc values
	 * should be drawn (including the geometry on the info_label)
	 */
	gboolean	show_values;

	/* Specifies if a resized version of the image should be drawn
	 * on to the WM icon when ImgViewLoad() is called
	 */
	gboolean	show_image_on_wm_icon;

	/* Quality, from 0 to 2
	 *
	 *	0	poor/fastest
	 *	1	standard
	 *	2	best/slowest
	 */
	gint		quality;

	/* Alpha channel flags */
	imgview_alpha_flags	alpha_flags;

	/* Alpha threshold (used IMGVIEW_ALPHA_THRESHOLD is set) */
	guint8		alpha_threshold;

	/* Current pointer drag mode */
	imgview_drag_mode	drag_mode;

	/* Last drag positions (in window coordinates) */
	gint		drag_last_x,
			drag_last_y;

	/* Zoom Rectangular (in window coordinates) */
	gint		drag_zoom_rectangle_start_x,
			drag_zoom_rectangle_start_y,
			drag_zoom_rectangle_cur_x,
			drag_zoom_rectangle_cur_y;

	/* Crop Rectangle (in image data coordinates) */
	imgview_crop_flags	crop_flags;
	gint		crop_rectangle_start_x,
			crop_rectangle_start_y,
			crop_rectangle_cur_x,
			crop_rectangle_cur_y;
	imgview_cropdlg_struct	*crop_dialog;

	/* Color Probe */
	gint		color_probe_x,
			color_probe_y;

	/* Graphic context for drawing selection graphics on the view */
	GdkGC		*view_selection_gc;
	/* Bitmaps for drawing selection icons on the view */
	GdkBitmap	*scissor_bm;

	GdkCursor	*busy_cur,
			*translate_cur,
			*zoom_cur,
			*zoom_rectangle_cur,
			*crop_cur,
			*color_probe_cur;

	/* Main vbox parent (this is NULL if toplevel_is_window is FALSE) */
	GtkWidget	*main_vbox;

	/* Window manager icon pixmap/mask pair */
	GdkPixmap	*wm_icon_pixmap;
	GdkBitmap	*wm_icon_mask;

	/* Tool Bar */
	gboolean	toolbar_map_state;
	GtkWidget	*toolbar_toplevel,	/* GtkContainer */
			*info_label,		/* GtkDrawingArea */
			*zoom_in_btn,
			*zoom_out_btn,
			*zoom_tofit_btn,
			*zoom_onetoone_btn;

	/* Scrollbars */
	GtkWidget	*hscrollbar,
			*vscrollbar;

	/* Status Bar */
	gboolean	statusbar_map_state;
	GtkWidget	*statusbar_toplevel,	/* GtkContainer */
			*progress_bar;

	/* Right-click menu */
	GtkWidget	*menu,
			*zoom_in_mi,
			*zoom_out_mi,
			*zoom_tofit_mi,
			*zoom_onetoone_mi,
			*rotate_transform_submenu_mi,
			*show_submenu_mi,
			*quality_submenu_mi;

	/* Rotate/Transform submenu */
	GtkWidget	*rotate_transform_menu,
			*rotate_cw_90_mi,
			*rotate_ccw_90_mi,
			*rotate_cw_180_mi,
			*mirror_horizontal_mi,
			*mirror_vertical_mi;

	/* Show submenut */
 	GtkWidget	*show_menu,
			*show_toolbar_micheck,
			*show_values_micheck,
			*show_statusbar_micheck;
 
	/* Quality submenu */
	GtkWidget	*quality_menu,
			*quality_poor_mi,
			*quality_optimal_mi,
			*quality_best_mi;

	/* View translate and zoom values */
	/* Translation to upper left corner from upper left corner in
	 * window coordinates
	 */
	GtkAdjustment	*view_x_adj,
			*view_y_adj;

	gfloat		last_view_x,
			last_view_y;

	/* Zoom, original image geometry values are to be divided by
	 * this value
	 *
	 * Example, if the zoom was 2.0, then orig_x / 2.0
	 */
	gfloat		view_zoom,
			last_view_zoom;

	guint		view_zoom_toid,		/* View zoom timeout id */
			view_draw_idle_id,	/* View draw idle id */
			view_send_idle_id;	/* View send idle id */

	/* View drawing area */
	GtkWidget	*view_da;

	/* View image, used as the view_da's image buffer */
	imgview_image_struct	*view_img;

	/* Original image, used to hold the original image data */
	imgview_image_struct	*orig_img;

	/* Changed callback */
	void	(*changed_cb)(
		imgview_struct *,		/* ImgView */
		imgview_image_struct *,		/* Changed Image */
		gpointer			/* Data */
	);
	gpointer	changed_data;

};
#define IMGVIEW(p)	((imgview_struct *)(p))


/* Image IO */
extern imgview_image_struct *ImgViewImageNew(
	gint width, gint height, gint depth
);
extern imgview_image_struct *ImgViewImageCopy(
	const imgview_image_struct *img
);
extern void ImgViewImageClear(
	imgview_image_struct *img, guint32 v
);
extern void ImgViewImageSendRectangle(
	imgview_image_struct *image, GdkDrawable *d, GdkGC *gc, gint quality,
	const GdkRectangle *rect
);
extern void ImgViewImageSend(
	imgview_image_struct *image, GdkDrawable *d, GdkGC *gc, gint quality
);
extern void ImgViewImageDelete(imgview_image_struct *image);

/* ImgView utilities */
extern GtkAccelGroup *ImgViewGetAccelGroup(imgview_struct *iv);
extern gboolean ImgViewToplevelIsWindow(imgview_struct *iv);
extern GtkWidget *ImgViewGetToplevelWidget(imgview_struct *iv);
extern GtkDrawingArea *ImgViewGetViewWidget(imgview_struct *iv);
extern GtkMenu *ImgViewGetMenuWidget(imgview_struct *iv);
extern gboolean ImgViewIsLoaded(imgview_struct *iv);
extern imgview_image_struct *ImgViewGetImage(imgview_struct *iv);
extern guint8 *ImgViewGetImageData(
	imgview_struct *iv,
	gint *width, gint *height, gint *bpl, gint *bpp,
	imgview_format *format
);

/* ImgView front ends */
extern void ImgViewClear(imgview_struct *iv);
extern gint ImgViewSetImage(
	imgview_struct *iv,
	imgview_image_struct *img	/* Transfered */
);
extern gint ImgViewSetImageToFit(
	imgview_struct *iv,
	imgview_image_struct *img	/* Transfered */
);
extern gint ImgViewLoad(
	imgview_struct *iv,
	gint width, gint height,
	gint bytes_per_line,	/* Can be 0 to auto calculate */
	imgview_format format,	/* One of IMGVIEW_FORMAT_* */
	const guint8 *data
);
extern gint ImgViewLoadToFit(
	imgview_struct *iv,
	gint width, gint height,
	gint bytes_per_line,    /* Can be 0 to auto calculate */
	imgview_format format,	/* One of IMGVIEW_FORMAT_* */
	const guint8 *data
);

extern imgview_struct *ImgViewNew(
	gboolean show_toolbar,
	gboolean show_values,
	gboolean show_statusbar,
	gboolean show_image_on_wm_icon,	/* Only if toplevel_is_window is TRUE */
	gint quality,		/* 0 to 2 (2 being best/slowest) */
	gboolean toplevel_is_window,
	GtkWidget **toplevel_rtn
);
extern void ImgViewSetChangedCB(
	imgview_struct *iv,
	void (*changed_cb)(
		imgview_struct *,
		imgview_image_struct *,
		gpointer
	),
	gpointer data
);
extern void ImgViewReset(imgview_struct *iv, gboolean need_unmap);
extern void ImgViewQueueDrawView(imgview_struct *iv);
extern void ImgViewQueueSendView(imgview_struct *iv);
extern void ImgViewDraw(imgview_struct *iv);
extern void ImgViewUpdateMenus(imgview_struct *iv);

extern void ImgViewShowToolBar(imgview_struct *iv, gboolean show);
extern void ImgViewShowStatusBar(imgview_struct *iv, gboolean show);

extern void ImgViewSetViewBG(
	imgview_struct *iv,
	GdkColor *c		/* 5 colors */
);

extern void ImgViewZoomIn(imgview_struct *iv);
extern void ImgViewZoomOut(imgview_struct *iv);
extern void ImgViewZoomOneToOne(imgview_struct *iv);
extern void ImgViewZoomToFit(imgview_struct *iv);
extern void ImgViewZoomPrev(imgview_struct *iv);

extern void ImgViewAllowCrop(imgview_struct *iv, gboolean allow_crop);
extern void ImgViewSetBusy(imgview_struct *iv, gboolean is_busy);
extern void ImgViewProgressUpdate(
	imgview_struct *iv, gfloat position, gboolean allow_gtk_iteration
);
extern void ImgViewMap(imgview_struct *iv);
extern void ImgViewUnmap(imgview_struct *iv);
extern void ImgViewDelete(imgview_struct *iv);


#endif	/* IMGVOEW_H */
