/* Copyright 1996 Acorn Computers Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/****************************************************************************
 * This source file was written by Acorn Computers Limited. It is part of   *
 * the RISCOS library for writing applications in C for RISC OS. It may be  *
 * used freely in the creation of programs for Archimedes. It should be     *
 * used with Acorn's C Compiler Release 3 or later.                         *
 *                                                                          *
 ***************************************************************************/

/*
 * Title:   txt.h
 * Purpose: Text display object.
 *
 */

#ifndef __txt_h
#define __txt_h

#ifndef BOOL
#define BOOL int
#define TRUE 1
#define FALSE 0
#endif

/*
 * A txt is an array of characters, displayed in a window on the screen. It
 * behaves in many ways in a manner similar to a single buffer from a
 * conventional full screen text editor.
 *
 */

/*
 * This interface is intended to be independent of any underlying window
 * system.
 *
 */

/****************************** TXT DATA TYPE *****************************/

/* This is an abstract handle on a text object. */

typedef struct txt1_str *txt;



/****************************** INTERFACE FUNCTIONS ************************/


/* ------------------------------- txt_new ---------------------------------
 * Description:   Creates a new txt object, containing no charcters, with a
 *                given title (to appear in its window).
 *
 * Parameters:    char *title -- the text title to appear in its window
 * Returns:       pointer to the newly created text.
 * Other Info:    This function does not result in the text being displayed
 *                on the screen; it purely creates a new text object.
 *                0 is returned if there is not enough space to create the
 *                object.
 *
 */

txt txt_new(char *title);


/* -------------------------------- txt_show -------------------------------
 * Description:   Display a given text object in a free standing window of
 *                its own.
 *
 * Parameters:    txt t -- the text to be displayed.
 * Returns:       void.
 * Other Info:    "t" should have been created using txt_new.
 *
 */

void txt_show(txt t);


/* ------------------------------ txt_hide ---------------------------------
 * Description:   Hide a text which has been displayed.
 *
 * Parameters:    txt t -- the text to be hidden.
 * Returns:       void.
 * Other Info:    none.
 *
 */

void txt_hide(txt t);


/* ---------------------------- txt_settitle -------------------------------
 * Description:   Change the title of the window used to display a text
 *                object.
 *
 * Parameters:    txt t -- the text object
 *                char *title -- new title of window.
 * Returns:       void.
 * Other Info:    Long titles may be truncated when displayed.
 *
 */

void txt_settitle(txt, char *title);


/* ----------------------------- txt_dispose -------------------------------
 * Description:   Destroy a text and the window associated with it.
 *
 * Parameters:    txt *t -- pointer to the text.
 * Returns:       void.
 * Other Info:    none.
 *
 */

void txt_dispose(txt *t);


/*************************** General control operations. *******************/

/* A text object's main data content is an array of characters. This resides
 * in a buffer of known size. The characters of the array are not laid out
 * precisely in the buffer, gaps and wraparound of various forms are used in
 * order to make insertion and deletion fast. When initially created a text
 * has bufsize=0. If the buffer size is precisely the same as the number of
 * characters in the array then some operations (e.g. moving around in the
 * array) become even faster, this may be relevant when building fixed-size
 * VDU emulations.
 *
 */


/* ----------------------------- txt_bufsize -------------------------------
 * Description:   Informs caller of how many characters can be stored in the
 *                buffer, before more memory needs to be requested from the
 *                operating system.
 *
 * Parameters:    txt t -- the text.
 * Returns:       size of buffer.
 * Other Info:    none.
 *
 */

int txt_bufsize(txt);


/* --------------------------- txt_setbufsize ------------------------------
 * Description:   Allocates more space for the text buffer.
 *
 * Parameters:    txt t -- the text.
 *                int b -- new buffer size
 * Returns:       TRUE if space could be allocated successfully.
 * Other Info:    This call increases the buffer size, such that at least
 *                "b" characters can be stored, before requiring more from
 *                the operating system.
 *
 */

BOOL txt_setbufsize(txt, int);


/*
 * The character array is displayed on the screen in a window.  The
 * characters travel horizontally from left to right. If a '\n' is
 * encountered this signifies the end of the current text line, and the
 * start of a new one. All lines have the same height, although characters
 * may be of differing widths. There is no limit on the number of characters
 * allowed in a line. There is no restriction on the characters allowed in
 * the array, [0..255] are all acceptable.
 * Clearing the DISPLAY flag can be used during a long and complex sequence
 * of edits, to reduce the overall amount of display activity. The UPDATED
 * flag is set by the insertion or deletion of any characters in the array.
 *
 */

typedef enum { txt_DISPLAY = 1,     /* display changes to text as made */
               txt_CARET = 2,       /* give visible indictaion of "dot" */
               txt_UPDATED = 4      /* set when chars are inserted/deleted */
             } txt_charoption;


/* ----------------------------- txt_charoptions ---------------------------
 * Description:   Informs caller of currenly set charoptions.
 *
 * Parameters:    txt t -- text object.
 * Returns:       Currently set charoptions.
 * Other Info:    none.
 *
 */

txt_charoption txt_charoptions(txt);


/* ----------------------------- txt_setcharoptions ------------------------
 * Description:   Sets flags which are used to control display of text in
 *                screen window.
 *
 * Parameters:    txt t -- text object
 *                txt_charoption affect -- flags to affect
 *                txt_charoption values -- values to give to affected flags
 * Returns:       void.
 * Other Info:    Only the flags named in "affect" are affected - they are
 *                set to the value "values".
 *                Thus this has the meaning:
 *                  (previousState & ~affect) | (affect & values).
 *
 */

void txt_setcharoptions(txt, txt_charoption affect, txt_charoption values);

/* ----------------------------- txt_lastref -------------------------------
 * Description:   Returns last_ref field (for Message_DataSaved).
 *
 * Parameters:    txt t -- text object.
 * Returns:       Current value of last_ref (for Message_DataSaved).
 * Other Info:    none.
 *
 */

int txt_lastref(txt);


/* ----------------------------- txt_setlastref ----------------------------
 * Description:   Sets value of last_ref (for Message_DataSaved).
 *
 * Parameters:    txt t -- text object
 *                int newvalue -- new value
 * Returns:       void.
 * Other Info:    Sets the last_ref field in a txt, so that subsequently a
 *                Message_DataSaved can mark the data unmodified.
 *
 */

void txt_setlastref(txt, int newvalue);


/* -------------------------- txt_setdisplayok -----------------------------
 * Description:   Sets the display flag in charoptions for a given text
 *
 * Parameters:    txt t -- text object
 * Returns:       void.
 * Other Info:    You may have unset the display flag during a long/complex
 *                update to the array of characters. A call to this function
 *                turns display back on.
 *
 */

void txt_setdisplayok(txt);


/******************** Operations on the array of characters. ***************/

/*
 * "dot" is an index into the character array. If there are n chars in the
 * array, with indices in [0..n-1], then dot is in [0..n]. It is thought of
 * as pointing just before the character with the same index, but it can also
 * point just after the last one. When the text is displayed, the character
 * after the dot is always visible. The Caret is a visible indication of the
 * position of the dot within the array, it can be made visible using
 * SetCharOptions above.
 */

typedef int txt_index; /* An index into the char array */


/* ------------------------------ txt_dot ----------------------------------
 * Description:   Informs caller of where the "dot" (current position) is in
 *                the array of characters.
 *
 * Parameters:    txt t -- text object
 * Returns:       An index into the array of characters.
 * Other Info:    none.
 *
 */

txt_index txt_dot(txt t);


/* ------------------------------- txt_size --------------------------------
 * Description:   Informs the caller as to the maximum value "dot" can take
 *
 * Parameters:    txt t -- text object.
 * Returns:       Maximum permissible value of "dot".
 * Other Info:    none.
 *
 */

txt_index txt_size(txt t);


/* ------------------------------- txt_setdot ------------------------------
 * Description:   Sets the "dot" at a given index in the array of characters.
 *
 * Parameters:    txt t -- text object.
 *                txt_index i -- index at which to set "dot".
 * Returns:       void.
 * Other Info:    If "i" is outside the bounds of the array it is set to the
 *                beginning/end of the array appropriately.
 *
 */

void txt_setdot(txt t, txt_index i);


/* ------------------------------ txt_movedot ------------------------------
 * Description:   Move the "dot" by a given distance in the array.
 *
 * Parameters:    txt t -- text object
 *                int by -- distance to move by.
 * Returns:       void
 * Other Info:    If the resulting "dot" is outside the bounds of the array
 *                it is set to the beginning/end of the array appropriately.
 *
 */

void txt_movedot(txt, int by);


/* ----------------------------- txt_insertchar ----------------------------
 * Description:   Insert a character into the text just after the "dot".
 *
 * Parameters:    txt t -- text object
 *                char c -- the character to be inserted.
 * Returns:       void.
 * Other Info:    If the DISPLAY option flag is set, the window is
 *                redisplayed after insertion.
 *
 */

void txt_insertchar(txt t, char c);


/* --------------------------- txt_insertstring ----------------------------
 * Description:   Inserts a given character string into a text.
 *
 * Parameters:    txt t -- text object
 *                char *s -- the character string.
 * Returns:       void.
 * Other Info:    If the DISPLAY option flag is set, the window is
 *                redisplayed after insertion.
 *
 */

void txt_insertstring(txt t, char *s);


/* ------------------------------ txt_delete -------------------------------
 * Description:   Deletes "n" characters from the "dot" onwards.
 *
 * Parameters:    txt t -- text object
 *                int n -- number of characters to delete.
 * Returns:       void.
 * Other Info:    If "dot +n" is beyond the end of the array, then deletion
 *                is to end of array.
 *
 */

void txt_delete(txt t, int n);


/* ---------------------------- txt_replacechars ---------------------------
 * Description:   Deletes "ntodelete" charcters from "dot", and inserts "n"
 *                characters in their place, where the characters are
 *                pointed at by "a".
 *
 * Parameters:    txt t -- text object
 *                int ntodelete -- number of characters to delete
 *                char *a -- pointer to characters to insert
 *                int n -- number of characters to insert.
 * Returns:       void.
 * Other Info:    none.
 *
 */

void txt_replacechars(txt t, int ntodelete, char *a, int n);


/* ---------------------------- txt_charatdot ------------------------------
 * Description:   Informs caller of the character held at "dot" in the array.
 *
 * Parameters:    txt t -- text object.
 * Returns:       Character at "dot".
 * Other Info:    Returns 0 if "dot" is at/beyond end of array.
 *
 */

char txt_charatdot(txt t);


/* ------------------------------ txt_charat -------------------------------
 * Description:   Informs caller of the character at a given index in the
 *                array.
 *
 * Parameters:    txt t -- text object
 *                txt_index i -- the index into the array.
 * Returns:       Character at given index in array.
 * Other Info:    Returns 0 if index is at/beyond end of array.
 *
 */

char txt_charat(txt t, txt_index i);


/* ---------------------------- txt_charsatdot -----------------------------
 * Description:   Copies at most "n" characters from "dot" in the array into
 *                a supplied buffer.
 *
 * Parameters:    txt t -- text object
 *                char *buffer -- the buffer
 *                int *n -- maximum characters to copy.
 * Returns:       void.
 * Other Info:    If you are close to the end of the array, then "n" chars
 *                may not be available. In this case, chars up to the end of
 *                the array are copied, and *n is updated to report how many
 *                were copied.
 *
 */

void txt_charsatdot(txt, char/*out*/ *buffer, int /*inout*/ *n);


/* -------------------------- txt_replaceatend -----------------------------
 * Description:   Deletes a specified number of characters from the end of
 *                the array and then inserts specified characters.
 *
 * Parameters:    txt t -- text object
 *                int ntodelete -- number of characters to delete
 *                char *s -- pointer to characters to insert
 *                int n -- number of characters to insert.
 * Returns:       void.
 * Other Info:    none.
 *
 */

void txt_replaceatend(txt, int ntodelete, char*, int);


/************************ Layout-dependent Operations. *********************/

/*
 * These operations are provided specifically for the support of cursor-
 * key-driven editing.
 */


/* ------------------------- txt_movevertical ------------------------------
 * Description:   Moves the "dot" by a specified number of textual lines,
 *                with the caret staying in the same horizontal position
 *                on the screen.
 *
 * Parameters:    txt t -- text object
 *                int by -- number of lines to move by
 *                int caretstill -- set to non-zero, if you want the text to
 *                                  move rather than the caret.
 * Returns:       void.
 * Other Info:    none.
 *
 */

void txt_movevertical(txt t, int by, int caretstill);


/* --------------------------- txt_movehorizontal --------------------------
 * Description:   Move the caret (and "dot") "horizontally".
 *
 * Parameters:    txt t -- text object
 *                int by -- distance to move by.
 * Returns:       void.
 * Other Info:    This behaves like txt_movedot(), except that if "by" is
 *                positive and the end of the current text line is
 *                encountered, then the caret will continue to move to the
 *                right on the screen.
 *
 */

void txt_movehorizontal(txt, int by);


/* -------------------------- txt_visiblelinecount -------------------------
 * Description:   Gives the number of lines visible or partially visible
 *                on the display.
 *
 * Parameters:    txt t -- text object.
 * Returns:       Number of visible lines.
 * Other Info:    Takes into account current window size, font etc.
 *
 */

int txt_visiblelinecount(txt t);


/* -------------------------- txt_visiblecolcount --------------------------
 * Description:   Gives the number of columns currently visible.
 *
 * Parameters:    txt t -- text object.
 * Returns:       Visible column count.
 * Other Info:    If a fixed pitch font is currently in use, then this gives
 *                the number of display columns, otherwise it makes a guess
 *                for "average" characters.
 *
 */

int txt_visiblecolcount(txt t);


/*************************** Operations on Markers. ************************/

/*
 * Markers are indices into the array. Once set, a marker will point to the
 * same character in the array regardless of insertions or deletions within
 * the array. If the character pointed at by the marker is deleted then the
 * marker will point to the next character. Markers never "fall off the end"
 * of the array, but stay at the top or bottom of it if that's where they
 * end up.
 */

typedef struct {int a; int b;} txt_marker;
/* Abstract record, uses of fields not public. */


/* ---------------------------- txt_newmarker ------------------------------
 * Description:   Create a new "marker" in the text.
 *
 * Parameters:    txt t -- text object
 *                txt_marker *mark -- pointer to your text marker.
 * Returns:       void.
 * Other Info:    Marker itself is kept by the client of this function, but
 *                the text object retains a pointer to it. The client's
 *                marker is updated by the text object whenever necessary.
 *                Its initial value is the same as "dot". If the character
 *                at which a marker points is deleted, then the marker gets
 *                moved to the value of "dot" when the deletion occurred. If
 *                characters are inserted when the marker is at dot, the
 *                marker stays with "dot".
 *
 */

void txt_newmarker(txt, txt_marker *mark);


/* -------------------------- txt_movemarker -------------------------------
 * Description:   Resets an existing marker.
 *
 * Parameters:    txt t  - text object
 *                txt_marker *mark -- the marker
 *                txt_index to -- place to move the marker to
 * Returns:       void.
 * Other Info:    The amrker must already point into this text object
 *
 */

void txt_movemarker(txt t, txt_marker *mark, txt_index to);


/* ------------------------- txt_movedottomarker ---------------------------
 * Description:   Moves the "dot" to a given marker.
 *
 * Parameters:    txt t -- text object
 *                txt_marker *mark -- pointer to the marker
 * Returns:       void.
 * Other Info:    none.
 *
 */

void txt_movedottomarker(txt t, txt_marker *mark);


/* ----------------------- txt_indexofmarker -------------------------------
 * Description:   Gives the current index into the array of a given marker
 *
 * Parameters:    txt t -- text object
 *                txt_marker *mark.
 * Returns:       Index of marker
 * Other Info:    none.
 *
 */

txt_index txt_indexofmarker(txt t, txt_marker *mark);


/* ---------------------------- txt_disposemarker --------------------------
 * Description:   Delete a marker from a text object.
 *
 * Parameters:    txt t -- text object
 *                txt_marker *mark -- the marker to be deleted.
 * Returns:       void.
 * Other Info:    WARNING: You should remember to dispose of a marker which
 *                logically ceases to exist, otherwise the text object will
 *                continue to update the location where it was!.
 *
 */

void txt_disposemarker(txt, txt_marker*);


/*********************** Operations on a selection. ************************/

/* The selection is a contiguous portion of the array which is
 * displayed highlighted.
 */

/* ---------------------------- txt_selectset ------------------------------
 * Description:   Informs caller whether there is a selction made in a text.
 *
 * Parameters:    txt t -- text object.
 * Returns:       TRUE if there is a selection in this text.
 * Other Info:    none.
 *
 */

BOOL txt_selectset(txt t);


/* --------------------------- txt_selectstart -----------------------------
 * Description:   Gives the index into the array of the start of the current
 *                selection.
 *
 * Parameters:    txt t -- text object.
 * Returns:       Index of selection start.
 * Other Info:    none.
 *
 */

txt_index txt_selectstart(txt t);


/* --------------------------- txt_selectend -------------------------------
 * Description:   Gives the index into the array of the end of the current
 *                selection.
 *
 * Parameters:    txt t -- text object.
 * Returns:       Index of selection end.
 * Other Info:    none.
 *
 */

txt_index txt_selectend(txt t);


/* -------------------------- txt_setselect --------------------------------
 * Description:   Sets a selection in a given text, from "start" to "end"
 *
 * Parameters:    txt t -- text object
 *                txt_index start -- array index of start of selection
 *                txt_index end -- array index of end of selection.
 *
 * Returns:       void.
 * Other Info:    If "start" >= "end" then the selection will be unset.
 *
 */

void txt_setselect(txt, txt_index start, txt_index end);


/*************************** Input from the user ***************************/

/* Characters entered into the keyboard, and various mouse events, are
buffered up by the text object for use by the client. */

typedef int txt_eventcode;


/* ------------------------------- txt_get ---------------------------------
 * Description:   Gives the next user event code to the caller.
 *
 * Parameters:    txt t -- text object.
 * Returns:       The event code.
 * Other Info:    The returned code can be ASCII, or various other (system-
 *                specific) values for function keys etc.
 *
 */

txt_eventcode txt_get(txt t);


/* ------------------------------- txt_queue -------------------------------
 * Description:   Informs caller of how many event codes are currently
 *                buffered for a given text.
 *
 * Parameters:    txt t -- text object.
 * Returns:       No. of buffered event codes.
 * Other Info:    none.
 *
 */

int txt_queue(txt t);


/* ----------------------------- txt_unget ---------------------------------
 * Description:   Puts an event code back on the front of the event queue
 *                for a given text.
 *
 * Parameters:    txt t -- text object
 *                txt_eventcode code -- the event code.
 * Returns:       void.
 * Other Info:    none.
 *
 */

void txt_unget(txt t, txt_eventcode code);


/****************************** Mouse events *******************************/

typedef enum {
  txt_MSELECT = 0x01000000,
  txt_MEXTEND = 0x02000000,
  txt_MSELOLD = 0x04000000,
  txt_MEXTOLD = 0x08000000,
  txt_MEXACT = 0x10000000,
  txt_EXTRACODE = 0x40000000,
  txt_MOUSECODE = ~0x7fffffff
} txt_mouseeventflag; /* used as a set */

/* A mouse event occurs when the mouse is pointing in the text object and a
 * button is pressed or released, or the mouse moves while any button is
 * depressed. A mouse event will result in Get producing an EventCode with
 * bit 31 set, bits 24..28 as a mouseeventflags value, and the rest of the
 * word containing an index value.
 *
 * The index shows where in the visible representation of the array the mouse
 * event happened. If all three index bytes are 255 then the event happened
 * outside the window. The mouseeventflags show what button transitions
 * occurred:
 *    MSELECT -- select's new value
 *    MEXTEND -- extend's new value
 *    MSELOLD -- select's old value
 *    MEXTOLD -- extend's old value
 *    MEXACT -- the event is in exactly the same place as the last one
 * The byte gives the values of the select and extend buttons, 1 for
 * depressed and 0 for not depressed. It gives their previous values,
 * allowing transitions to be detected. It says if the position of the mouse
 * is exactly the same as for the last event, so that multiple clicks may be
 * detected. No assumptions should be made concerning the relationship of
 * these bits to the last mouse event sent to the programmer, as polling
 * delays etc. could cause any combinations to happen.
 *
 * If txt_EXTRACODE is set then the identity of the event is not defined
 * by this interface. This is used for any expansion. Clients of this
 * interface which receive such events that they do not recognise, should
 * ignore them without reporting an error.
 *
 * The menu button on the mouse is not transmitted through this interface,
 * but caught elsewhere.
 *
 */

typedef void (*txt_event_proc)(txt,void *handle);


/* ---------------------------- txt_eventhandler ---------------------------
 * Description:   Register an eventhandler function for a given text,
 *                which will be called whenever there is a value ready which
 *                can be picked up by txt_get().
 *
 * Parameters:    txt t -- text object
 *                txt_event_proc func -- event handler function
 *                void *handle -- caller-defined handle to be passed to func.
 * Returns:       void.
 * Other Info:    If func==0 then no function is registered.
 *
 */

void txt_eventhandler(txt, txt_event_proc, void *handle);


/* -------------------------- txt_readeventhandler -------------------------
 * Description:   Informs caller of the currently registered eventhandler
 *                function associated with a given text, and the handle which
 *                is passed to it.
 *
 * Parameters:    txt t -- text object
 *                txt_event_proc *func -- returned pointer to handler func
 *                void **handle -- returned pointer to handle.
 * Returns:       void.
 * Other Info:    none.
 *
 */

void txt_readeventhandler(txt t, txt_event_proc *func, void **handle);


/******************* Direct Access to the array of characters **************/

/* ---------------------------- txt_arrayseg -------------------------------
 * Description:   Gives a direct pointer into the memory used to hold the
 *                characters in a text.
 *
 * Parameters:    txt t -- text object
 *                txt_index at -- index into the text
 *                char **a -- *a will point at the character whose index
 *                            in the text is "at"
 *                int *n -- *n == no. of contiguous bytes after "at"
 * Returns:       void.
 * Other Info:    It is permissible for the caller of this function to change
 *                the characters pointed at by *a, provided that a redsiplay
 *                is prompted (using setcharoptions).
 *
 */

void txt_arrayseg(txt t, txt_index at, char **a /*out*/, int *n /*out*/);


/******************************* System hook *******************************/


/* ---------------------------- txt_syshandle ------------------------------
 * Description:   Obtains a system_dependent handle on the object underlying
 *                a text.
 *
 * Parameters:    txt t -- text object.
 * Returns:       System-dependent handle for the given text.
 * Other Info:    none.
 *
 */

int txt_syshandle(txt t);


/* ---------------------------------- txt_init -----------------------------
 * Description:   Initialise the txt module of the library
 *
 * Parameters:    void.
 * Returns:       void.
 * Other Info:    none.
 *
 */

void txt_init(void);

# endif

/* end txt.h */