/*
 * Copyright 1994-1995 TriloBYTE Software Solutions.
 *
 * Author: Amen Zwa, TriloBYTE.
 */



// static char* sccsid = "XmWidget: %W%\t%G%\tAmen Zwa, TriloBYTE.";



// WTxt.h: text classes



#if !defined(WTXT_H)
#define WTXT_H

#include <ctype.h>
#include <float.h>
#include <limits.h>
#include "WFcsItm.h"
#include "WKeySym.h"



// text service manager base class
class WTxt : public WFcsItm {
protected:
    char* txttxt;			// text content
    int txtlen;				// text size
    Boolean is_arrow(int c) const {
	return c == WK_leftarrow || c == WK_rightarrow; }
    virtual void edit(XmTextVerifyCallbackStruct*) = 0;
    friend void cp_gainfocus_txt(Widget w, XtPointer, XtPointer);
    friend void cp_losefocus_txt(Widget w, XtPointer, XtPointer);
    friend void cp_modify_txt(Widget w, XtPointer, XtPointer wgt);
public:
    WTxt() { txttxt = 0; txtlen = 0; }
    ~WTxt() { if (txttxt) delete[] txttxt; }
    // access functions
    void set_text(const char* s) { XmTextSetString(xtwgt, (char*)s); }
    const char* get_text();
    void set_multiline(Boolean mulflg) {
	XtVaSetValues(xtwgt,
	    XmNeditMode, (mulflg?XmMULTI_LINE_EDIT:XmSINGLE_LINE_EDIT), 0); }
    void set_editable(Boolean edflg) { XmTextSetEditable(xtwgt, edflg); }
    void set_focus();
    void set_focus(Boolean gainflg, Boolean kbdflg=False);
    void get_selrng(XmTextPosition* l, XmTextPosition* r) const {
	XmTextGetSelectionPosition(xtwgt, l, r); }
    XmTextPosition get_length() const { return XmTextGetLastPosition(xtwgt); }
    // editing functions
    virtual void undo() { /**** sorry pal, ya can't do that :) ****/ }
    void cut() { XmTextCut(xtwgt, 0); }
    void copy() const { XmTextCopy(xtwgt, 0); }
    void paste() { XmTextPaste(xtwgt); }
    void clear() { XmTextClearSelection(xtwgt, 0); }
    void selectall() {
	XmTextSetSelection(xtwgt, 0, XmTextGetLastPosition(xtwgt), 0); }
    void unselect() { XmTextClearSelection(xtwgt, 0); }
    // test functions
    Boolean is_text() const { return True; }
    Boolean is_multiline() const;
    Boolean is_editable() const { return XmTextGetEditable(xtwgt); }
};



// text document
class WTextDoc : public WTxt {
    void edit(XmTextVerifyCallbackStruct*) { }
public:
    WTextDoc(Widget par, Boolean hsbflg=False, Boolean vsbflg=True);
};



// text field
class WTextField : public WTxt {
    void edit(XmTextVerifyCallbackStruct*) { }
public:
    WTextField(Widget par);
};



// numeral text base class
class WTextNum : public WTextField {
public:
    enum { numdigit = 12 };		// maximum number of digits
protected:
    ERange rng;				// valid number range
    Boolean is_sign(int c) const { return c == '+' || c == '-'; }
    virtual Boolean is_legal(int c) const = 0;
public:
    WTextNum(Widget par);
    // access functions
    void set_range(const ERange& r) { rng = r; }
    ERange get_range() const { return rng; }
};



// long integer text field
class WTextInt : public WTextNum {
    Boolean is_legal(int c) const {
	return isdigit(c) || c == WK_delete || is_arrow(c); }
    void edit(XmTextVerifyCallbackStruct* tcb);
public:
    WTextInt(Widget par) : WTextNum(par) { rng = ERange(-LONG_MAX, LONG_MAX); }
    // access functions
    void set_value(long v);
    int get_value(long* v);
};



// double precision floating point text field
class WTextFloat : public WTextNum {
    int prec;				// floating point precision
    Boolean is_legal(int c) const {
	return  c == '.' || is_sign(c) || isdigit(c) ||
	    c == WK_delete || is_arrow(c); }
    void edit(XmTextVerifyCallbackStruct* tcb);
public:
    WTextFloat(Widget par) : WTextNum(par) {
	rng = ERange(-DBL_MAX, DBL_MAX); prec = 6; }
    // access functions
    void set_value(double v);
    int get_value(double* v);
    void set_precision(int p) { prec = p; }
    int get_precision() const { return prec; }
};

#endif	// WTXT_H
