// This may look like C code, but it is really -*- C++ -*-

/***********************************************************
Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts,
and the Massachusetts Institute of Technology, Cambridge, Massachusetts.

                        All Rights Reserved

Permission to use, copy, modify, and distribute this software and its 
documentation for any purpose and without fee is hereby granted, 
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in 
supporting documentation, and that the names of Digital or MIT not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.  

DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.

C++ interface author: Roman J. Budzianowski - Project Athena MIT

******************************************************************/

#ifndef _XawText_h
#define _XawText_h

#include <xt++/Xaw/Simple.h>

#include <xt++/Xaw/TextI.h>
#include <xt++/Xaw/TextSink.h>
#include <xt++/Xaw/TextSrc.h>

/****************************************************************
 *
 * Text widget
 *
 ****************************************************************/

/* Parameters:

 Name		     Class		RepType		Default Value
 ----		     -----		-------		-------------
 background	     Background		Pixel		XtDefaultBackground
 border		     BorderColor	Pixel		XtDefaultForeground
 borderWidth	     BorderWidth	Dimension	1
 destroyCallback     Callback		Pointer		NULL
 dialogHOffset	     Margin		int		10
 dialogVOffset	     Margin		int		10
 displayCaret	     Output		Boolean		True
 displayPosition     TextPosition	int		0
 editType	     EditType		XtTextEditType	XttextRead
 height		     Height		Dimension	font height
 insertPosition	     TextPosition	int		0
 leftMargin	     Margin		Dimension	2
 mappedWhenManaged   MappedWhenManaged	Boolean		True
 selectTypes	     SelectTypes	Pointer		(internal)
 selection	     Selection		Pointer		empty selection
 sensitive	     Sensitive		Boolean		True
 textSink	     TextSink		Pointer		(none)
 textSource	     TextSource		Pointer		(none)
 width		     Width		Dimension	100
 x		     Position		int		0
 y		     Position		int		0

*/

#define XtEtextScrollNever "never"
#define XtEtextScrollWhenNeeded "whenneeded"
#define XtEtextScrollAlways "always"

#define XtEtextWrapNever "never"
#define XtEtextWrapLine "line"
#define XtEtextWrapWord "word"

#define XtEtextResizeNever "never"
#define XtEtextResizeWidth "width"
#define XtEtextResizeHeight "height"
#define XtEtextResizeBoth "both"

#define XtNautoFill "autoFill"
#define XtNbottomMargin "bottomMargin"
#define XtNdialogHOffset "dialogHOffset"
#define XtNdialogVOffset "dialogVOffset"
#define XtNdisplayCaret "displayCaret"
#define XtNdisplayPosition "displayPosition"
#define XtNinsertPosition "insertPosition"
#define XtNleftMargin "leftMargin"
#define XtNresize "resize"
#define XtNrightMargin "rightMargin"
#define XtNscrollVertical "scrollVertical"
#define XtNscrollHorizontal "scrollHorizontal"
#define XtNselectTypes "selectTypes"
#define XtNselection "selection"
#define XtNtopMargin "topMargin"
#define XtNwrap "wrap"

#define XtCAutoFill "AutoFill"
#define XtCResize "Resize"
#define XtCScroll "Scroll"
#define XtCSelectTypes "SelectTypes"
#define XtCWrap "Wrap"

/* Return Error code for XawTextSearch */

#define XawTextSearchError      (-12345L)

/* Return codes from XawTextReplace */

#define XawReplaceError	       -1
#define XawEditDone		0
#define XawEditError		1
#define XawPositionError	2

extern Atom FMT8BIT;

/* Class record constants */

extern WidgetClass textWidgetClass;
extern "C" { 

extern void XawTextDisplay(Widget); 
extern void XawTextEnableRedisplay(Widget);
extern void XawTextDisableRedisplay(Widget);
extern void XawTextSetSelectionArray(Widget, XawTextSelectType*	 sarray);
extern void XawTextGetSelectionPos(Widget, XawTextPosition* begin_return, XawTextPosition* end_return);
extern void XawTextSetSource(Widget, Widget source, XawTextPosition position);
extern int XawTextReplace(Widget, XawTextPosition start, XawTextPosition end, XawTextBlock* text);
extern XawTextPosition XawTextTopPosition(Widget);
extern void XawTextSetInsertionPoint(Widget, XawTextPosition position);
extern XawTextPosition XawTextGetInsertionPoint(Widget);
extern void XawTextUnsetSelection(Widget);
extern void XawTextSetSelection(Widget, XawTextPosition	left, XawTextPosition right);
extern void XawTextInvalidate(Widget, XawTextPosition from, XawTextPosition to);
extern Widget XawTextGetSource(Widget);
extern XawTextPosition XawTextSearch(Widget, XawTextScanDirection dir, XawTextBlock* text);
extern void XawTextDisplayCaret(Widget, Boolean visible);

}

/****************************************************************
 *
 * Text widget private
 *
 ****************************************************************/
#define MAXCUT	30000	/* Maximum number of characters that can be cut. */

#define zeroPosition ((XawTextPosition) 0)

extern XtActionsRec textActionsTable[];
extern Cardinal textActionsTableCount;

#define LF	0x0a
#define CR	0x0d
#define TAB	0x09
#define BS	0x08
#define SP	0x20
#define DEL	0x7f
#define BSLASH	'\\'

/* constants that subclasses may want to know */
#define DEFAULT_TEXT_HEIGHT ((Dimension)~0)

/* displayable text management data structures */

struct XawTextLineTableEntry {
  XawTextPosition position;
  Position y;
  Dimension textWidth;
};

struct XawTextSelection {
    XawTextPosition   left, right;
    XawTextSelectType type;
    Atom*	     selections;
    int		     atom_count;
    int		     array_size;
};

struct XawTextSelectionSalt {
    struct _XawTextSelectionSalt    *next;
    XawTextSelection	s;
    char		*contents;
    int			length;
};

/* Line Tables are n+1 long - last position displayed is in last lt entry */
struct XawTextLineTable{
  XawTextPosition	 top;	/* Top of the displayed text.		*/
  int			 lines;	/* How many lines in this table.	*/
  XawTextLineTableEntry *info;  /* A dynamic array, one entry per line  */
};


struct XawTextMargin {
  Position left, right, top, bottom;
};

// ????
#define VMargins(ctx) ( (ctx)->text.margin.top + (ctx)->text.margin.bottom )
#define HMargins(ctx) ( (ctx)->text.margin.left + (ctx)->text.margin.right )

#define IsPositionVisible(ctx, pos) \
		(pos >= ctx->text.lt.info[0].position && \
		 pos < ctx->text.lt.info[ctx->text.lt.lines].position)

/*
 * Search & Replace data structure.
 */

struct SearchAndReplace {
  Boolean selection_changed;	/* flag so that the selection cannot be
				   changed out from underneath query-replace.*/
  Widget search_popup;		/* The poppup widget that allows searches.*/
  Widget label1;		/* The label widgets for the search window. */
  Widget label2;
  Widget left_toggle;		/* The left search toggle radioGroup. */
  Widget right_toggle;		/* The right search toggle radioGroup. */
  Widget rep_label;		/* The Replace label string. */
  Widget rep_text;		/* The Replace text field. */
  Widget search_text;		/* The Search text field. */
  Widget rep_one;		/* The Replace one button. */
  Widget rep_all;		/* The Replace all button. */
};
    
/* Private Text Definitions */

typedef int (*ActionProc)();

struct text_move {
    int h, v;
    struct text_move * next;
};

/* New fields for the Text widget record */
struct TextPart {
    /* resources */

    Widget              source, sink;
    XawTextPosition	insertPos;
    XawTextSelection	s;
    XawTextSelectType	*sarray;	   /* Array to cycle for selections. */
    XawTextSelectionSalt    *salt;	     /* salted away selections */
    int			options;	     /* wordbreak, scroll, etc. */
    int			dialog_horiz_offset; /* position for popup dialog */
    int			dialog_vert_offset;  /* position for popup dialog */
    Boolean		display_caret;	     /* insertion pt visible iff T */
    Boolean             auto_fill;           /* Auto fill mode? */
    XawTextScrollMode   scroll_vert, scroll_horiz; /*what type of scrollbars.*/
    XawTextWrapMode     wrap;            /* The type of wrapping. */
    XawTextResizeMode   resize;	             /* what to resize */
    XawTextMargin       r_margin;            /* The real margins. */
    
    /* private state */

    XawTextMargin       margin;            /* The current margins. */
    XawTextLineTable	lt;
    XawTextScanDirection extendDir;
    XawTextSelection	origSel;    /* the selection being modified */
    Time	    lasttime;	    /* timestamp of last processed action */
    Time	    time;	    /* time of last key or button action */ 
    Position	    ev_x, ev_y;	    /* x, y coords for key or button action */
    Widget	    vbar, hbar;	    /* The scroll bars (none = NULL). */
    SearchAndReplace * search;      /* Search and replace structure. */
    Widget          file_insert;    /* The file insert popup widget. */
    XawTextPosition  *updateFrom;   /* Array of start positions for update. */
    XawTextPosition  *updateTo;	    /* Array of end positions for update. */
    int		    numranges;	    /* How many update ranges there are. */
    int		    maxranges;	    /* How many ranges we have space for */
    XawTextPosition  lastPos;	    /* Last position of source. */
    GC              gc;
    Boolean	    showposition;   /* True if we need to show the position. */
    Boolean         hasfocus;       /* TRUE if we currently have input focus.*/
    Boolean	    update_disabled; /* TRUE if display updating turned off */
    Boolean         single_char;    /* Single character replaced. */
    XawTextPosition  old_insert;    /* Last insertPos for batched updates */
    short           mult;	    /* Multiplier. */
    text_move * copy_area_offsets;  /* Text offset area (linked list) */

    /* private state, shared w/Source and Sink */
    Boolean	    redisplay_needed; /* in SetValues */

};

/*************************************************************
 *
 * Resource types private to Text widget.
 *
 *************************************************************/

#define XtRScrollMode "ScrollMode"
#define XtRWrapMode "WrapMode"
#define XtRResizeMode "ResizeMode"

/****************************************************************
 *
 * Full instance record declaration
 *
 ****************************************************************/

class TextSrObject;

class TextWidget : public SimpleWidget {
 protected:
   TextPart text;

 public:
   void DisplayText() { XawTextDisplay(this); }

   void EnableRedisplay() { XawTextEnableRedisplay(this); }

   void DisableRedisplay() { XawTextDisableRedisplay(this); }

   void SetSelectionArray(XawTextSelectType* sarray)
     { XawTextSetSelectionArray(this, sarray);}

   void GetSelectionPos(XawTextPosition* begin_return, XawTextPosition* end_return)
     { XawTextGetSelectionPos(this, begin_return, end_return); }

   void SetSource(Widget source, XawTextPosition position)
     { XawTextSetSource(this, source, position); }

   int Replace(XawTextPosition start, XawTextPosition end, XawTextBlock* text)
     { return XawTextReplace(this, start, end, text); }

   XawTextPosition TopPosition() {  return XawTextTopPosition(this); }

   void SetInsertionPoint(XawTextPosition position) 
     {XawTextSetInsertionPoint(this, position);}

   XawTextPosition GetInsertionPoint() { return XawTextGetInsertionPoint(this); }

   void UnsetSelection() {  XawTextUnsetSelection(this); }

   void SetSelection(XawTextPosition left, XawTextPosition right)
     { XawTextSetSelection(this, left, right); }

   void Invalidate(XawTextPosition from, XawTextPosition to)
     { XawTextInvalidate(this, from, to); }

   TextSrObject* GetSource() { return (TextSrObject*)XawTextGetSource(this); }
     
   XawTextPosition Search(XawTextScanDirection dir, XawTextBlock* text)
     { return XawTextSearch(this, dir, text); }

   void DisplayCaret(Boolean visible) { XawTextDisplayCaret(this, visible); }

   Constructors(Text,text) {}
};

#include <xt++/Xaw/AsciiSrc.h>
#include <xt++/Xaw/AsciiSink.h>


#endif /* _XawText_h */
