/*
 * Copyright(c) 1992 Bell Communications Research, Inc. (Bellcore)
 * Copyright(c) 1995-99 Andrew Lister
 * Copyright © 1999, 2000, 2001, 2002, 2003 by the LessTif Developers.
 *
 *                        All rights reserved
 * Permission to use, copy, modify and distribute this material for
 * any purpose and without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all
 * copies, and that the name of Bellcore not be used in advertising
 * or publicity pertaining to this material without the specific,
 * prior written permission of an authorized representative of
 * Bellcore.
 *
 * BELLCORE MAKES NO REPRESENTATIONS AND EXTENDS NO WARRANTIES, EX-
 * PRESS OR IMPLIED, WITH RESPECT TO THE SOFTWARE, INCLUDING, BUT
 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR ANY PARTICULAR PURPOSE, AND THE WARRANTY AGAINST IN-
 * FRINGEMENT OF PATENTS OR OTHER INTELLECTUAL PROPERTY RIGHTS.  THE
 * SOFTWARE IS PROVIDED "AS IS", AND IN NO EVENT SHALL BELLCORE OR
 * ANY OF ITS AFFILIATES BE LIABLE FOR ANY DAMAGES, INCLUDING ANY
 * LOST PROFITS OR OTHER INCIDENTAL OR CONSEQUENTIAL DAMAGES RELAT-
 * ING TO THE SOFTWARE.
 *
 * MatrixWidget Author: Andrew Wason, Bellcore, aw@bae.bellcore.com
 *
 * $Id: MatrixP.h,v 1.40 2004/04/12 05:39:35 dannybackx Exp $
 */

/*
 * MatrixP.h - Private definitions for Matrix widget
 */

#ifndef _Xbae_MatrixP_h
#define _Xbae_MatrixP_h

#include <Xm/ManagerP.h>
#include <Xbae/Matrix.h>

#ifdef __cplusplus
extern "C" {
#endif


/*
 * New types for the class methods
 */

typedef void (*XbaeMatrixSetCellProc)(XbaeMatrixWidget, int, int,
					 const String, Boolean);

typedef String (*XbaeMatrixGetCellProc)(XbaeMatrixWidget, int, int);

typedef void (*XbaeMatrixEditCellProc)(XbaeMatrixWidget, XEvent *,
					  int, int, String *, Cardinal);

typedef void (*XbaeMatrixSelectCellProc)(XbaeMatrixWidget, int, int);

typedef void (*XbaeMatrixSelectRowProc)(XbaeMatrixWidget, int);

typedef void (*AXbaeMatrixShowColumnArrows)(XbaeMatrixWidget, int, Boolean);

typedef void (*XbaeMatrixSelectColumnProc)(XbaeMatrixWidget, int);

typedef void (*XbaeMatrixDeselectAllProc)(XbaeMatrixWidget);

typedef void (*XbaeMatrixSelectAllProc)(XbaeMatrixWidget);

typedef void (*XbaeMatrixDeselectCellProc)(XbaeMatrixWidget, int, int);

typedef void (*XbaeMatrixDeselectRowProc)(XbaeMatrixWidget, int);

typedef void (*XbaeMatrixDeselectColumnProc)(XbaeMatrixWidget, int);

typedef Boolean (*XbaeMatrixCommitEditProc)(XbaeMatrixWidget, XEvent *,
					       Boolean);

typedef void (*XbaeMatrixCancelEditProc)(XbaeMatrixWidget, Boolean);

typedef void (*XbaeMatrixAddRowsProc)(XbaeMatrixWidget, int, String *,
					 String *, Pixel *, Pixel *, int);

typedef void (*XbaeMatrixAddVarRowsProc)(XbaeMatrixWidget, int, String *,
				      String *, short *, int *,
				      unsigned char*, unsigned char *,
				      Pixel *, Pixel *, int);

typedef void (*XbaeMatrixDeleteRowsProc)(XbaeMatrixWidget, int, int);

typedef void (*XbaeMatrixAddColumnsProc)(XbaeMatrixWidget, int, String *,
					    String *, short *, int *,
					    unsigned char*, unsigned char *,
					    Pixel *, Pixel *, int);

typedef void (*XbaeMatrixDeleteColumnsProc)(XbaeMatrixWidget, int, int);

typedef void (*XbaeMatrixSetRowColorsProc)(XbaeMatrixWidget, int, Pixel *,
					      int, Boolean);

typedef void (*XbaeMatrixSetColumnColorsProc)(XbaeMatrixWidget, int,
						 Pixel *, int, Boolean);

typedef void (*XbaeMatrixSetCellColorProc)(XbaeMatrixWidget, int, int,
					      Pixel, Boolean);


/*
 * Different than the traversal directions in Xm.h
 */
#define NOT_TRAVERSING	-1

/*
 * New fields for the Matrix widget class record
 */
typedef struct {
    XbaeMatrixSetCellProc		set_cell;
    XbaeMatrixGetCellProc		get_cell;
    XbaeMatrixEditCellProc		edit_cell;
    XbaeMatrixSelectCellProc		select_cell;
    AXbaeMatrixShowColumnArrows         set_show_column_arrows;
    XbaeMatrixSelectRowProc		select_row;
    XbaeMatrixSelectColumnProc		select_column;
    XbaeMatrixDeselectAllProc		deselect_all;
    XbaeMatrixSelectAllProc		select_all;
    XbaeMatrixDeselectCellProc		deselect_cell;
    XbaeMatrixDeselectRowProc		deselect_row;
    XbaeMatrixDeselectColumnProc	deselect_column;
    XbaeMatrixCommitEditProc		commit_edit;
    XbaeMatrixCancelEditProc		cancel_edit;
    XbaeMatrixAddRowsProc		add_rows;
    XbaeMatrixAddVarRowsProc		add_var_rows;
    XbaeMatrixDeleteRowsProc		delete_rows;
    XbaeMatrixAddColumnsProc		add_columns;
    XbaeMatrixDeleteColumnsProc		delete_columns;
    XbaeMatrixSetRowColorsProc		set_row_colors;
    XbaeMatrixSetColumnColorsProc	set_column_colors;
    XbaeMatrixSetCellColorProc		set_cell_color;
    XtPointer				extension;
} XbaeMatrixClassPart;

/*
 * Full class record declaration
 */
typedef struct _XbaeMatrixClassRec {
    CoreClassPart		core_class;
    CompositeClassPart		composite_class;
    ConstraintClassPart		constraint_class;
    XmManagerClassPart		manager_class;
    XbaeMatrixClassPart		matrix_class;
} XbaeMatrixClassRec;

externalref XbaeMatrixClassRec xbaeMatrixClassRec;


/*
 * Inheritance constants for set/get/edit methods
 */
#define XbaeInheritGetCell ((XbaeMatrixGetCellProc) _XtInherit)
#define XbaeInheritSetCell ((XbaeMatrixSetCellProc) _XtInherit)
#define XbaeInheritEditCell ((XbaeMatrixEditCellProc) _XtInherit)
#define XbaeInheritSelectCell ((XbaeMatrixSelectCellProc) _XtInherit)
#define XbaeInheritShowColumnArrows ((AXbaeMatrixShowColumnArrows) _XtInherit)
#define XbaeInheritSelectRow ((XbaeMatrixSelectRowProc) _XtInherit)
#define XbaeInheritSelectColumn ((XbaeMatrixSelectColumnProc) _XtInherit)
#define XbaeInheritHighlightCell ((XbaeMatrixHighlightCellProc) _XtInherit)
#define XbaeInheritHighlightRow ((XbaeMatrixHighlightRowProc) _XtInherit)
#define XbaeInheritHighlightColumn ((XbaeMatrixHighlightColumnProc) _XtInherit)
#define XbaeInheritDeselectAll ((XbaeMatrixDeselectAllProc) _XtInherit)
#define XbaeInheritSelectAll ((XbaeMatrixSelectAllProc) _XtInherit)
#define XbaeInheritDeselectCell ((XbaeMatrixDeselectCellProc) _XtInherit)
#define XbaeInheritDeselectRow ((XbaeMatrixDeselectRowProc) _XtInherit)
#define XbaeInheritDeselectColumn ((XbaeMatrixDeselectColumnProc) _XtInherit)
#define XbaeInheritCommitEdit ((XbaeMatrixCommitEditProc) _XtInherit)
#define XbaeInheritCancelEdit ((XbaeMatrixCancelEditProc) _XtInherit)
#define XbaeInheritAddRows ((XbaeMatrixAddRowsProc) _XtInherit)
#define XbaeInheritAddVarRows ((XbaeMatrixAddVarRowsProc) _XtInherit)
#define XbaeInheritDeleteRows ((XbaeMatrixDeleteRowsProc) _XtInherit)
#define XbaeInheritAddColumns ((XbaeMatrixAddColumnsProc) _XtInherit)
#define XbaeInheritDeleteColumns ((XbaeMatrixDeleteColumnsProc)_XtInherit)
#define XbaeInheritSetRowColors ((XbaeMatrixSetRowColorsProc)_XtInherit)
#define XbaeInheritSetColumnColors ((XbaeMatrixSetColumnColorsProc)_XtInherit)
#define XbaeInheritSetCellColor ((XbaeMatrixSetCellColorProc)_XtInherit)

/*
 * New data structures for the ScrollMgr code
 */
typedef struct _SmScrollNode {
    int x;
    int y;
    struct _SmScrollNode *next;
    struct _SmScrollNode *prev;
} SmScrollNodeRec, *SmScrollNode;

typedef struct _SmScrollMgr {
    int offset_x;
    int offset_y;
    int scroll_count;
    SmScrollNode scroll_queue;
    Boolean scrolling;
} SmScrollMgrRec, *SmScrollMgr;

/*
 * Rectangle struct used for internal calculations.  (x1,y1) are the upper
 * left corner, (x2,y2) are the lower right.
 */
typedef struct _Rectangle
{
    int x1, y1;
    int x2, y2;
}
Rectangle;

/*
 * Data structure for column labels
 */
typedef struct _ColumnLabelLines {
    int lines;
    int *lengths;
} ColumnLabelLinesRec, *ColumnLabelLines;

/*
 * Bundle per cell attributes into one structure
 * This bundles all the "2D array"s that were previously in the XbaeMatrixPart.
 */
typedef struct _XbaeMatrixPerCellRec {
	unsigned char	shadow_type;	/* Per cell shadow type		*/
	unsigned char	highlighted;	/* Is the cell highlighted ?	*/
	Boolean		selected;	/* Is the cell selected ?	*/
	Boolean		underlined;	/* Is the cell underlined ?	*/
	XtPointer	user_data;	/* Per cell user data		*/
	Pixel		background;	/* Background pixel per cell	*/
	Pixel		color;		/* Foreground pixel per cell	*/
	Widget		widget;		/* So-called cell widgets	*/
	XmFontList	font_list;	/* Per cell font		*/
} XbaeMatrixPerCellRec;

/*
 * New fields for the Matrix widget record
 */
typedef struct {
    /*
     * resources
     */
    Boolean	allow_column_resize;	/* can columns dynamically resize?   */
    Boolean	bold_labels;		/* draw bold row/column labels?	     */
    Boolean	button_labels;		/* draw labels as buttons?	     */
    Boolean	fill;			/* fill available space?	     */
    Boolean	trailing_attached_right;  /* trailing columns fixed to right */
    Boolean	trailing_attached_bottom; /* trailing rows fixed to bottom   */
    Boolean	reverse_select;		/* reverse colours - selected cells? */
    Boolean	scroll_select;		/* flag to scroll a selected cell    */
    Boolean	show_arrows;	        /* sow arrows when text obscured?    */
    Boolean     *show_column_arrows;    /* which columns will show arrows    */
    Boolean     *column_font_bold;      /* which columns have bold fonts     */
    Boolean     *column_button_labels;  /* which column labels are buttons   */
    Boolean     *row_button_labels;     /* which row labels are buttons      */
    Boolean	traverse_fixed;		/* allow traversal to fixed cells?   */
    Boolean	calc_cursor_position;	/* calculate insert pos from click   */
    Boolean     column_width_in_pixels; /*column width mesured in pixels?    */

    unsigned char cell_shadow_type;	/* cell shadow type		     */
    unsigned char *column_alignments;	/* alignment of each column	     */
    unsigned char *column_label_alignments;/* alignment of each column label */
    unsigned char *column_shadow_types;	/* 1D array of per col shadow types  */
    unsigned char grid_type;		/* shadowed in/shadowed out/plain    */
    unsigned char hsb_display_policy;	/* horiz scroll bar display policy   */
    unsigned char row_label_alignment;	/* alignment of row labels	     */
    unsigned char *row_shadow_types;	/* 1D array of per row shadow types  */
    unsigned char scrollbar_placement;	/* placement of the scrollbars	     */
    unsigned char selection_policy;	/* as for XmList */
    unsigned char shadow_type;		/* matrix window shadow type	     */
    unsigned char vsb_display_policy;	/* vert scroll bar display policy    */

    String	**cells;		/* 2D array of strings		     */
    String	*column_labels;		/* array of labels above each column */
    String	*row_labels;		/* array of labels next to each row  */

    XtPointer	*column_user_data;	/* 1D array of per column user data  */
    XtPointer	*row_user_data;		/* 1D array of per row user data     */

    short	*column_widths;		/* width of each column in chars     */
    short	row_label_width;	/* max width of row labels in chars  */

    int		alt_row_count;		/* # of rows for e/o background	     */
    int		columns;		/* number of cells per row	     */
    int		*column_max_lengths;	/* max length of each col in chars   */
    int         double_click_interval;	/* interval between clicks	     */
    int         left_column;		/* horizontal origin (in col space)  */
    int		rows;			/* number of rows per column	     */
    int		top_row;		/* vertical origin (in row space)    */

    Dimension	cell_highlight_thickness; /* hilite thickness for textField  */
    Dimension	cell_margin_height;	/* margin height for textField	     */
    Dimension	cell_margin_width;	/* margin width for textField	     */
    Dimension	cell_shadow_thickness;	/* shadow thickness for each cell    */
    Dimension	fixed_columns;		/* number of leading fixed columns   */
    Dimension	fixed_rows;		/* number of leading fixed rows	     */
    Dimension	space;			/* spacing for scrollbars	     */
    Dimension	text_shadow_thickness;	/* shadow thickness for text field   */
    Dimension	trailing_fixed_columns;	/* number of trailing fixed columns  */
    Dimension	trailing_fixed_rows;	/* number of trailing fixed rows     */
    Dimension	underline_width;	/* number of pixels thick the underline is */
    Dimension	visible_columns;	/* number of columns to make visible */
    Dimension	visible_rows;		/* number of rows to make visible    */

    Pixel	all_backgrounds;	/* use this for all cell backgrounds */
    Pixel	all_foregrounds;	/* use this for all cell foregrounds */
    Pixel	button_label_background; /* color of button label background */
    Pixel	column_label_color;	/* color of column label	     */
    Pixel	even_row_background;	/* even row background color	     */
    Pixel	grid_line_color;	/* color of grid, for XmGrid_LINE    */
    Pixel       odd_row_background;	/* odd row background color	     */
    Pixel	row_label_color;	/* color of row label		     */
    Pixel	selected_background;	/* background for selected cells     */
    Pixel	selected_foreground;	/* foreground for selected cells     */
    Pixel	text_background;	/* background for the "text" field   */
    Pixel	scroll_background;	/* bacground for scrollbar */

    Position underline_position;	/* number of pixels below the text baseline */

    XtTranslations text_translations;	/* translations for textField widget */

    XtCallbackList default_action_callback; /* called for a double click     */
    XtCallbackList draw_cell_callback;	/* called when a cell is drawn	     */
    XtCallbackList enter_cell_callback;	/* called when a cell is entered     */
    XtCallbackList label_activate_callback; /* called when label pressed     */
    XtCallbackList leave_cell_callback;	/* called when a cell is left	     */
    XtCallbackList modify_verify_callback; /* verify change to textField     */
					/* and a draw_cell_callback is set   */
    XtCallbackList process_drag_callback; /* called when a drag is initiated */
    XtCallbackList resize_callback;	/* called when Matrix is resized     */
    XtCallbackList resize_column_callback; /* called when column is resized  */
    XtCallbackList select_cell_callback; /* called when cells are selected   */
    XtCallbackList traverse_cell_callback; /* next cell to traverse to	     */
    XtCallbackList value_changed_callback; /* same as XmText(3)                    */
    XtCallbackList write_cell_callback;	/*called when a cell needs to be set*/

    XmFontList	font_list;		/* fontList of widget and textField  */
    XmFontList	label_font_list;	/* fontList of labels		     */


    /*
     * private state
     */
    unsigned char highlight_location;	/* What is being highlighted	     */
    int		cell_visible_height;	/* height of visible cells in pixels */
    int		column_label_maxlines;	/* max # lines in column labels	     */
    int		*column_positions;	/* pixel position of each column     */
    int		current_column;		/* column of the text field	     */
    int		current_row;		/* row of the text field	     */
    int		horiz_origin;		/* horiz origin (in pixel space)     */
    int		label_baseline;		/* baseline of label		     */
    int		last_column;		/* The last selected column	     */
    int		last_row;		/* The last selected row	     */
    int		num_selected_cells;	/* The number selected cells	     */
    int		text_baseline;		/* baseline of text in each cell     */
    int		traversing;		/* direction we are traversing	     */

    unsigned int current_clip;		/* current clip mask setting	     */
    unsigned int disable_redisplay;	/* disable redisplay counter	     */

    Dimension	desired_height;		/* height widget wants to be	     */
    Dimension	desired_width;		/* width widget wants to be	     */

    Time	last_click_time;	/* when last ButtonPress occurred    */

    Widget	text_field;		/* the text field		     */
    Widget	horizontal_sb;		/* the horizontal scrollbar	     */
    Widget      vertical_sb;		/* the vertical scrollbar	     */
    Widget	clip_window;		/* the clip child		     */
    Widget	left_clip;		/* clips for scrolling fixed cells   */
    Widget	right_clip;
    Widget	top_clip;
    Widget	bottom_clip;
    Widget	current_parent;		/* Current textField parent window   */

    GC		cell_bottom_shadow_clip_gc; /* GC for clipped bottom shadow  */
    GC          cell_grid_line_gc;
    GC		cell_top_shadow_clip_gc; /* GC for clipped top shadow	     */
    GC		draw_gc;		/* GC for drawing cells		     */
    GC          grid_line_gc;		/* GC for grid line		     */
    GC		label_clip_gc;		/* GC for clipped labels	     */
    GC		label_gc;		/* GC for drawing labels	     */
    GC		pixmap_gc;		/* GC for drawing pixmap cells	     */
    GC		resize_bottom_shadow_gc;
    GC		resize_top_shadow_gc;

    ColumnLabelLines column_label_lines; /* structs for multi line labels    */

    XFontStruct	*font_struct;		/* fontStruct from fontList	     */
    XFontStruct	*label_font_struct;	/* fontStruct from fontList	     */

    SmScrollMgr clip_scroll_mgr;	/* ScrollMgr for Clip		     */
    SmScrollMgr matrix_scroll_mgr;	/* ScrollMgr for Matrix		     */

    XFontSet	font_set;		/* fontSet from fontList	     */
    short	font_y;
    short	font_width;
    short	font_height;
    Font	fid;
    XFontSet	label_font_set;		/* fontSet from fontList	     */
    short	label_font_y;
    short	label_font_width;
    short	label_font_height;
    Font	label_fid;

    XtIntervalId traverseId;
    Cursor	cursor;			/* Used to be global static */

/* Implement variable height rows */
    short	*row_heights;		/* height of each row in chars     */
    Boolean	allow_row_resize;	/* can rows dynamically resize?   */
    Boolean     row_heights_used; 	/* True if user provided row_heights */
    int		*row_positions;		/* pixel position of each row */
    XtCallbackList resize_row_callback; /* called when row is resized  */
    int		*row_max_heights;	/* max height of each row in pixels   */
    int          vert_origin;		/* vert origin (in pixel space)     */

    Boolean	useXbaeInput;		/* Whether to use XbaeInput widget */
    Boolean	multi_line_cell;	/* Whether to draw more than one line in a cell */

    Boolean	vert_fill, horz_fill;
    XbaeMatrixPerCellRec	**per_cell;	/* 2D array */

/* XmString Column Labels */
    XmString	*xmcolumn_labels;
} XbaeMatrixPart;

/*
 * Full instance record declaration
 */
typedef struct _XbaeMatrixRec {
	CorePart		core;
	CompositePart		composite;
	ConstraintPart		constraint;
	XmManagerPart		manager;
	XbaeMatrixPart		matrix;
} XbaeMatrixRec;

extern void xbaeFillPerCell(XbaeMatrixWidget mw, XbaeMatrixPerCellRec *p);
extern void xbaeCopyPerCell(XbaeMatrixWidget mw);
extern void xbaeCreatePerCell(XbaeMatrixWidget mw);

/*
 * Macro replacements
 */
extern int YtoRow(XbaeMatrixWidget mw, Position y);
extern Widget _XbaeGetShellAncestor(Widget w);
extern int xbaeMaxVertScroll(XbaeMatrixWidget);

extern int xbaeCellClip(XbaeMatrixWidget mw, int row, int column);
extern Boolean xbaeSetClipRect(XbaeMatrixWidget mw, Rectangle *rect_p,int clip);


#ifdef __cplusplus
}
#endif

#endif /* _Xbae_MatrixP_h */
