

#ifndef motif_DEFINED
#define motif_DEFINED

#include <stdio.h>		/* Other systems need this */

#include <X11/X.h>
#include <string.h>

#include <stdarg.h>

#include <math.h>
#include <X11/StringDefs.h>


#include <Xm/Xm.h>
#include <Xm/DialogS.h>
#include <Xm/Form.h>
#include <Xm/Frame.h>
#include <Xm/DrawingA.h>
#include <Xm/PushB.h>
#include <Xm/PushBG.h>
#include <Xm/Label.h>
#include <Xm/LabelG.h>
#include <Xm/List.h>
#include <Xm/RowColumn.h>
#include <Xm/ScrollBar.h>
#include <Xm/Separator.h>
#include <Xm/TextF.h>
#include <Xm/Scale.h>
#include <Xm/ToggleB.h>
#include <Xm/ToggleBG.h>
#include <Xm/CascadeB.h>
#include <Xm/CascadeBG.h>
#include <Xm/MessageB.h>
#include <Xm/ScrolledW.h>
#include <Xm/SelectioB.h>
#include <Xm/Text.h>
#include <Xm/ArrowB.h>
#include <Xm/ArrowBG.h>
#include <Xm/PanedW.h>
#include "Drag.h"

#include <X11/cursorfont.h>

//Ghost Busters Against False Definitions!
#ifdef clear
#undef clear
#endif

#define mShell		0
#define mForm		1
#define mPushButton	2
#define mRowColumn	3
#define mLabel		4
#define mMenuBar	6
#define mCascadeButton	7
#define mPulldownMenu	8
#define mOptionMenu	9
#define mFrame		10
#define mDrawingArea	11
#define mScrollBar	12
#define mList		13
#define mToggleButton	14
#define mTextField	15
#define mSeparator	16
#define mScrolledList	17
#define mMessageBox	18
#define mScrolledWindow	19
#define mScale		20
#define mMagics		21
#define mSelectionBox	22
#define mText		23
#define mRadioBox        28
#define mBulletinBoard   33
#define mPopupMenu       34
#define mArrowButton       	 35
#define mPanedWindow       	 36

// New widgets ...

#define mMatrix		24
#define mChart		25
#define mDecChart	26

#define mDragWidget     27
#define mHyper          29
#define mIconLabel	30
#define mIconButton	31
#define mArray	32
#define mLine	33
#define mCarousel       	 37
#define mPaper       	 38
#define mTab       	 39

// Internal functions....

int MInitArgs(Arg*, const char*, va_list);
// Initialize an array of type Arg... 
//        (usefull before a XtSetValues, XtGetValues, XtCreate...

void MFreeArgs(Arg*, int);
// Free memory...

char * Mxstos(XmString);
// Convert a XmString to a const char * ...
//	Allocate the memory.

XmString Mstoxs(const char*);
// Convert a XmString to a const char * ...
//	Allocate the memory.

class MAppContext
{
public:
	Display         *display;
	XtAppContext 	app_context;

	void 		init(int&, char**,int = 0);
	void 		appMainLoop()	
				{ XtAppMainLoop(app_context); }
	void		visMainLoop();
	Display* 	getDisplay()	
				{ return display; }	
	int 		getScreen()	
				{ return DefaultScreen(display); }	
        short           getDepth()
				{ return DefaultDepth(display,getScreen()); }
};


class MWidget 
{
	void    *data;

public:
	Widget  widget;
	short	ident;

	MWidget(Widget w = NULL,void *d = NULL) { data = d; widget = w; }
	int	isRealized() { return (widget && XtIsRealized(widget)); }
	int	isManaged() { return (widget && XtIsManaged(widget)); }
	void    manage() 
			{ XtManageChild(widget); }
	void    unmanage() 
			{ XtUnmanageChild(widget); }
	int	manageItsChildren();
	void    map() 
			{ XtMapWidget(widget); }
	void    unmap() 
			{ XtUnmapWidget(widget); }
	void    setValues(const char*, ...);
	void    setValue(const char*,  XtPointer); 
	void    getValue(const char*, XtPointer);

	void    setValuesToAll(const char*, ...);
	//	Set values of widget and all descendents
	//	Input: List of:
	//		widget name ("*" to match all)
	//		resource name
	//		resource list

	void    addProc(const char*, ...);
	void    removeProc(const char*, ...);
	Pixmap 	getPixmapFromFile(const char*);
	void    setButtonPixmaps(const char*);
	void    setButtonPixmaps(Pixmap);
	void 	overlayButtonPixmaps(const char*);
	void 	setPixmap(const char *, ...);
	void 	setHalfPixmap(const char *, ...);
	void 	setColor(const char *, ...);
	void 	putResources(const char *, const char*, const char*);
	void 	setFont(const char *, ...);
	Boolean isMOptionMenu() 
			{ return ( (ident == mOptionMenu) ? TRUE : FALSE); }
	Display *getDisplay()  
			{ return XtDisplay(widget); }
	Window 	getWindow()  
			{ return XtWindow(widget); }
	void	attachObject() 
			{setValue(XmNuserData, (XtPointer) this); }
	static   MWidget *returnObject(Widget widget);
	MWidget *returnParent();
	int	returnChildren(Widget **children);
	MWidget *returnChild(const char * name);
	void 	sensitive() 
			{ XtSetSensitive(widget, True); }
	void 	insensitive() 
			{ XtSetSensitive(widget, False); }
	Boolean isSensitive() ;
	int	x() ;
	int	y() ;
	int	width();
	int	height();
	char  	*getLabel();
	void	setCursor(unsigned int);
	void	resetCursor();
        void    attachData(void *d) 
			{ data = d; }
        void    *returnData()   
			{ return data; }
	const char *  name()  
			{ return XtName(widget); }
	void 	destroy()
			{ XtDestroyWidget(widget); }
	void 	addEventProc(EventMask event_mask, XtEventHandler proc,
               		     XtPointer data);
	void 	removeEventProc(EventMask event_mask, XtEventHandler proc,
                                XtPointer data);

	void 	GetApplicationResources(XtPointer, XtResourceList, Cardinal,
									ArgList = NULL, Cardinal = 0);
	void    GetSubresources(XtPointer, const char *, const char *, XtResourceList,
						    Cardinal, ArgList = NULL, Cardinal = 0);
	void    SetMappedWhenManaged(Boolean);

	void    acceptDropCallback(XtCallbackProc cb, XtPointer datum)
        { DragAcceptDropCallback(widget, cb,  datum); }

	virtual ~MWidget(){}
};

void Mmanage_link (Widget w, MWidget *client_data, caddr_t call_data);

void Munmanage_link (Widget w, MWidget *client_data, caddr_t call_data);

void Mdisable_link(Widget w, MWidget *client_data, caddr_t call_data);

void Menable_link (Widget w, MWidget *client_data, caddr_t call_data);

class MShell : public MWidget
{
	int	dialog;
public:
	Widget 	**shells;
	int	num_shells;

	MShell() { dialog = 1; }
	void 	init(Display*, const char*, int, char**, ...);
	void    setTopLevel() { dialog = 0; }
	void 	init(MWidget* parent, const char* name, ...);
	void 	realizeWidget() 
			{ XtRealizeWidget(widget); }
	void 	manage()
			{ realizeWidget();
			  XMapRaised(XtDisplay(widget), XtWindow(widget)); } 
	void	addWMProc(const char*, XtCallbackProc, XtPointer);
};

class MForm : public MWidget
{
public:
	void 	init(MWidget* parent, const char* name, ...);
};

class MPushButton : public MWidget
{
public:
	void 	init(MWidget* parent, const char* name, ...);
	void 	init(Boolean, MWidget* parent, const char* name, ...);
};

class MRowColumn : public MWidget
{
public:
	void 	init(MWidget* parent, const char * name, ...);
	void 	clear();   
			// Delete all the children of the RowColumn
	void 	addItem(short buttontype, const char *name, ...);
			// Add a Button n the RowColumn:
			// buttontype: mPushButton or mToggleButton 
	void 	addChildrenProc(const char *proc, ...);
			// Add Callbacks to all the buttons of the RowColumn. 
	void 	select(const char *name);
			// Select the button with the given name.
	void 	unselect(const char *name);
			// Unselect the button with the given name.
	void 	select();
			// Select all the buttons.
	void 	unselect();
			// Unselect all the buttons.
	int 	returnSelectedItems(Widget *);
			// Return the selected buttons of the RowColumn.
	int 	returnSelectedItems(MWidget **);
			// Return the selected MWidgets of the RowColumn.
	int 	returnSelectedItems(char **);
			// Return the names od the selected buttons of the 
			// RowColumn.
	char* 	returnSelectedItemLabel();
			// If the RowColum has a radio behavior return the
			// name of teh selected button.
	void 	sensitive(const char *name);
			// The button with the given name becomes sensitive.
	void 	insensitive(const char *name);
			// The button with the given name becomes insensitive.
	Boolean isSensitive(const char *name);
			// Is the button with the given name sensitive.
	void 	sensitive();
			// All the buttons become sensitive.
	void 	insensitive();
			// all the button become insensitive.
};

class MLabel : public MWidget
{
public:
	void init(MWidget* parent, const char *name, ...);
	void 	init(Boolean, MWidget* parent, const char* name, ...);
};

class MScrolledList : public MWidget
{
public:
	void init(MWidget* parent, const char *name, ...);
};

class MScrollBar : public MWidget
{
public:
	void init(MWidget* parent, const char *name, ...);
	void scrollWH(MWidget *parent);
	void scrollWV(MWidget *parent);
};

class MScrolledWindow : public MWidget
{
public:
	void init(MWidget* parent, const char *name, ...);
	void manage(MWidget *horiz, MWidget *vert, MWidget *work);
	void manage(MWidget *work);
};

class MList : public MWidget
{
public:
	void 	init(MWidget* parent, const char *name, ...);
	void 	setValues(const char *proc, ...);
	void 	clear();
			// Clear the List.
	void 	addItem(int n, const char * name);
			// Add an item at the position n. Check selection
	void 	addItem(int n, XmString name);
			// Add an item at the position n using XmString. Check selection
	void 	addItemUnselected(int n, const char * name);
			// Add an item at the position n even if selected.
	void 	addItemUnselected(int n, XmString name);
			// Add an item at the position n even if selected, using XmString.
	void	addItems(int n, int count, XmStringTable items);
			// Add a list of items at position n.
	void 	selectItem(const char * item, Boolean notify = False);
			// Select the item with given name.
			// If notify, the application will be notified
			// (Callback called...) 
	void 	selectItem(int item, Boolean notify = False);
			// Select the item with the given posotion.
			// If notify, the application will be notified
			// (Callback called...) 
	void 	unselectItem(const char * item);
			// Unselect the item with the given name.
	void 	unselectItem(int item);
			// Unselect the item with the given position.
	void	unselectAllItems();
			// Unselect all list items.
	int     returnSelectedItems(XmStringTable *items);
			// Return selected items as XMStrings
	int 	returnSelectedItems(char **items);
			// Return the name of the selected items.
	int 	returnSelectedItems(int **items);
			// Return the position of the selected items.
    int 	selected();
			// Return the number of selected items.
	int		listed();
			// Return number of listed items.
	int		returnItems(XmStringTable *items);
			// Return all items in the list and the count.
	void	setSelectedItems(XmStringTable items, int item_cnt);
			// Select a list of items from their const char * value.
	void    addListMax(int, const char *);
	void    addListMax(const char *);

};

class MToggleButton : public MWidget
{
public:
	void 	init(MWidget* parent, const char *name, ...);
	void 	init(Boolean, MWidget* parent, const char* name, ...);
	Boolean isSelected();
	void 	select(Boolean select = True);
			// If select = True , the button will be selected.
	void 	unselect();
};

class MTextField : public MWidget
{
public:
	void 	init(MWidget* parent, const char *name, ...);
	char* 	returnValue();
	void 	setValue(const char *text) 
			{ MWidget::setValue(XmNvalue, (XtPointer)text);}
   	void 	setValue(int v);
   	void 	setValue(float v);
   	void 	setValue(double v);
	inline void setString(const char *s) 
		{ XmTextFieldSetString(widget, (char*)s); }
	inline char * getString()
		{ return XmTextFieldGetString(widget); }

};

class MSeparator : public MWidget
{
public:
	void 	init(MWidget* parent, const char *name, ...);
};

class MMenuBar : public MWidget
{
public:
	void 	init(MWidget* parent, const char *name, ...);
};
 
class MOptionMenu : public MWidget
{
public:
	void 	init(MWidget* parent, const char *name, ...);
	void 	manage(MWidget *child);
        void 	addItem(const char * name);
        void 	clear();
        void 	selectItem(const char * item);
        void 	selectItem(int position);
        int 	returnSelectedItems(char **items);
	char* 	returnSelectedItemLabel();
	MWidget* returnSelectedItem();

};
 
class MCascadeButton : public MWidget
{
public:
	void 	init(MWidget* parent, const char *name, ...);
	void 	init(Boolean,MWidget* parent, const char *name, ...);
	void 	manage(MWidget *child);
};
 
class MPulldownMenu : public MRowColumn
{
public:
	void 	init(MWidget* parent, const char *name, ...);
};

class MFrame : public MWidget
{
public:
	void	init(MWidget* parent, const char *name, ...);
};

class MScale : public MWidget
{
public:
	void 	init(MWidget* parent, const char *name, ...);
	void 	init(Boolean, MWidget* parent, const char* name, ...);
	int  	returnValue();
	void 	setValue(int value) 
			{ MWidget::setValue(XmNvalue, (XtPointer) value); }
};

class MDrawingArea : public MWidget
{
	unsigned long speed;
public:
	void 	init(MWidget* parent, const char *name, ...);
	int  	treatEvent(XEvent *event, int *x, int *y);
	void 	addTimer(void *canvas, XtTimerCallbackProc Timer, 
		         int interval = -1);
	void 	removeTimer();
	void 	resize(int width, int height);
	char 	*keyPressed(XEvent *event);	
	void 	mouseXY(int *x, int *y) ;

};

class MMessageBox : public MWidget
{
public:
	void 	init(MWidget* parent, const char *name, ...);
	void 	deleteCancel();
	void 	deleteOk();
	void 	manage(const char * message, XtArgVal cat);
	void 	manage() { XtManageChild(widget); }
	MWidget	*getChild(int child);
};

class MText : public MWidget
{
public:
	void 	init(MWidget* parent, const char *name, ...);
	char 	*returnValue();
	void 	setValue(const char *text);
	void    loadText(const char *, Boolean);
	void 	saveText(const char *);
	inline void setString(const char *s) 
		{ XmTextSetString(widget, (char*)s); }
	inline char * getString()
		{ return XmTextGetString(widget); }
	void replaceSelection(const char*);
	void replaceSelection(char);
	void replaceSelection(long);
	void replaceSelection(double);
	void setEditable(Boolean on) { XmTextSetEditable(widget,on); }
	void selectLine(int);
	void moveToEnd();
};

class MScrolledText : public MText {
public:
	void    init(MWidget* parent, const char *name, ...);
};

class MSelectionBox : public MWidget
{
public:
	void 	init(MWidget* parent, const char *name, ...);
	MWidget	*getChild(int child);
};
class MRadioBox : public MRowColumn
{
public:
        void    init(MWidget *parent, const char *name, ...);
        void 	addItem(char *name, ...);
};
class MBulletinBoard :  public MWidget
{
public:
        void    init(MWidget *parent, const char *name, ...);
};

class MPopupMenu : public MRowColumn
{
public:
	void 	init(MWidget* parent, const char *name, ...);
	void    manage();
	Boolean map(XEvent*);
};

class MArrowButton : public MWidget
{
public :
	void    init(MWidget *parent, const char *name, ...);
	void 	init(Boolean, MWidget* parent, const char* name, ...);
};

class MPanedWindow : public MWidget
{
public :
	void    init(MWidget *parent, const char *name, ...);
};
#endif

