#include <stdio.h>
#include <X11/Intrinsic.h>
#include <Xm/Xm.h>
#include <Xm/RepType.h>
#include <Xm/PushB.h>
#include <Xm/ToggleB.h>
#include <Xm/MainWP.h>
#include <Xm/RowColumn.h>
#include <Xm/MessageB.h>
#include <Xm/CascadeB.h>
#include <Xm/Command.h>
#include <Xm/Frame.h>
#include <Xm/Label.h>

Widget GXTextIn, GXTextOut, GXStatus;
#define INITIAL_WIDTH 400
static String fallback_resources[] =
{
    "*background: tan",
    "*fontList: *-*-*-medium-r-*-*-*-100-*-*-p-*-*-*",
    "*tearOffModel: TEAR_OFF_ENABLED",
    "*GLWidget.width: 400",
    "*GLWidget.height: 200",
    "*GXStatus.height: 30",
    NULL
};

void ShowHelp(w, client_data, call_data)
Widget w;
XtPointer client_data;
XtPointer call_data;
{
  if (XmToggleButtonGetState(w))
    XtManageChild(GXStatus);
  else
    XtUnmanageChild(GXStatus);
}

void Quit(w, client_data, call_data)
Widget w;
XtPointer client_data, call_data;
{ 
    exit(0); 
}

void GXSetStatus(char *str) 
/* display str on status line */
{
  char *buf=str;
  if (!str) 
    buf=" ";
  {
    XmString xmstr;
    if (!GXStatus)
      return;
    xmstr=XmStringCreateLocalized(buf);
    XtVaSetValues(GXStatus,
		  XmNlabelString,xmstr,
		  NULL);
    XmStringFree(xmstr);
  }
}

void GXInitCommand(Widget parent, Boolean TEXTPORT)
/*-
 * Initialize the command area. if textport is true, grab standard output
 * and standard error and send them to a text output widget
-*/
{
    Arg args[20];
    int n;
    Widget w;

    /* make the text IO region */
    if (TEXTPORT) {
	GXTextOut = XmCreateScrolledText(parent, "GXTextOut", NULL, 0);
#ifndef __linux__
	/* FIXME */
	XmTextSetAddMode(GXTextOut, TRUE);
#endif
	XtVaSetValues(GXTextOut,
		      XmNskipAdjust, TRUE,
		      XmNeditMode, XmMULTI_LINE_EDIT,
		      XmNeditable, FALSE,
		      XmNtraversalOn, FALSE,
		      XmNwordWrap, TRUE,
		      XmNhighlightOnEnter, False,
		      XmNhighlightThickness, 0,
		      XmNrows, 6,
		      NULL);
	XtVaSetValues(XtParent(GXTextOut),
		      XmNskipAdjust, TRUE,
		      XmNleftOffset, 5,
		      XmNrightOffset, 5,
		      XmNbottomOffset, 5,
		      XmNhighlightOnEnter, FALSE,
		      XmNhighlightThickness, 0,
		      XmNresizeWidth, TRUE,
		      XmNresizeHeight, FALSE,
		      NULL);
	XtVaGetValues(XtParent(GXTextOut),
		      XmNhorizontalScrollBar, &w,
		      NULL);
	XtUnmanageChild(w);	/* kill off unneeded scrollbar */
	XtManageChild(GXTextOut);

    }

    /*- make the command Widget -*/
    GXTextIn = XmCreateTextField(parent, "GXTextIN", NULL, 0);
    XtVaSetValues(GXTextIn,
		  XmNhighlightOnEnter, False,
		  XmNhighlightThickness, 0,
		  XmNpaneMaximum, 30,
		  XmNpaneMinimum, 30,
		  XmNwidth, INITIAL_WIDTH,
		  NULL);
    XtManageChild(GXTextIn);
#if (XmVersion>=1002)		/* motif 1.2 or higher */
    XtVaSetValues(parent,
		  XmNinitialFocus, GXTextIn,
		  NULL);
#endif
}

int main(argc, argv)
int argc;
char **argv;
{
    XtAppContext app_context;
    Widget topLevel, mainWindow, menuBar, frame;
    Display *GXDisplay;
    Widget command, paned, GLWidget;

    Widget fileButton, fileMenu, quit, helpButton, helpMenu, help, helpBox;
    Widget temp;
    int n;
    Arg args[10];

    /* if compiling on a SGI, allow for non-default visuals. */
    XtToolkitInitialize();
    app_context = XtCreateApplicationContext();
    XtAppSetFallbackResources(app_context, fallback_resources);
    GXDisplay = XtOpenDisplay(app_context, NULL, "Mainw12", "Mainw12",
			      NULL, 0, &argc, argv);
    if (!GXDisplay) {
      printf("Couldn't open display. \n");
      exit(-1);
    }

    n = 0;
    topLevel = XtAppCreateShell("Mainw12", "Mainw12",
				applicationShellWidgetClass,
				GXDisplay, args, n);

    /* create main window */
    mainWindow = XtVaCreateManagedWidget(
            "mainWindow",               /* widget name */
            xmMainWindowWidgetClass,    /* widget class */
            topLevel,                   /* parent widget*/
            NULL);                      /* terminate varargs list */

    /* register converter for tearoff menus */
    XmRepTypeInstallTearOffModelConverter();

    /* create menu bar along top inside of main window */
    menuBar = XmCreateMenuBar(
            mainWindow, /* parent widget*/
            "menuBar",  /* widget name */
            NULL,       /* no arguments needed */
            0);         /* no arguments needed */
    XtManageChild(menuBar);

    paned = XmCreatePanedWindow(mainWindow, "GXPanedW", NULL, NULL);
    XtVaSetValues(paned, XmNspacing, 10, NULL);	    
    XtManageChild(paned);

    /* create blank drawing area for a holder */
    GLWidget = XmCreateDrawingArea(paned, "GLWidget", args, n);
    XtManageChild(GLWidget);

    XmMainWindowSetAreas(mainWindow, menuBar, NULL, NULL, NULL, NULL);
    GXInitCommand(paned, 1);

    {
      XmString xmstr = XmStringCreateLocalized(" ");
      GXStatus=XtVaCreateManagedWidget("GXStatus",xmLabelWidgetClass,
				       paned,
				       XmNalignment, XmALIGNMENT_BEGINNING,
				       XmNlabelString, xmstr,
				       NULL);
      XmStringFree(xmstr);
    }

    GXSetStatus("Status line");

    /*
     *  CREATE FILE MENU AND CHILDREN
     */

    /* create button that will pop up the menu */
    fileButton = XtVaCreateManagedWidget(
            "fileButton",               /* widget name */
            xmCascadeButtonWidgetClass, /* widget class */
            menuBar,                    /* parent widget*/
            NULL);                      /* terminate varargs list */

    /* create menu (really a Shell widget and RowColumn widget combo) */
    fileMenu = XmCreatePulldownMenu(
            menuBar,    /* parent widget*/
            "fileMenu", /* widget name */
            NULL,       /* no argument list needed */
            0);         /* no argument list needed */

    /* create the quit button up in the menu */
    quit = XtVaCreateManagedWidget(
            "quit",                     /* widget name */
            xmPushButtonWidgetClass,    /* widget class */
            fileMenu,                   /* parent widget*/
            NULL);                      /* terminate varargs list */

    /* 
     * Specify which menu fileButton will pop up.
     */
    XtVaSetValues(fileButton,
		  XmNsubMenuId, fileMenu,
		  NULL);

    /* arrange for quit button to call function that exits. */
    XtAddCallback(quit, XmNactivateCallback, Quit, 0);

    /*
     *  CREATE HELP BUTTON AND BOX
     */

    /* create button that will bring up help menu */
    helpButton = XtVaCreateManagedWidget(
            "Help",             /* widget name */
            xmCascadeButtonWidgetClass, /* widget class */
            menuBar,                   /* parent widget*/
            NULL);                     /* terminate varargs list */

    /* tell menuBar which is the help button (will be specially
       positioned) */
    XtVaSetValues(menuBar,
		  XmNmenuHelpWidget, helpButton,
		  NULL);

    /* create menu (really a Shell widget and RowColumn widget combo) */
    helpMenu = XmCreatePulldownMenu(
            menuBar,    /* parent widget*/
            "helpMenu", /* widget name */
            NULL,       /* no argument list needed */
            0);         /* no argument list needed */

    /* create the help button up in the menu */
    help = XtVaCreateManagedWidget(
            "status line",                     /* widget name */
            xmToggleButtonWidgetClass,    /* widget class */
            helpMenu,                   /* parent widget*/
            NULL);                      /* terminate varargs list */

    /* 
     * Specify which menu helpButton will pop up.
     */
    XtVaSetValues(helpButton,
		  XmNsubMenuId, helpMenu,
		  NULL);

    /* create popup that will contain help */
    helpBox = XmCreateMessageDialog(
	    help,       /* parent widget*/
            "helpBox",  /* widget name   */
            NULL,       /* no arguments needed */
            0);         /* no arguments needed */

    temp = XmMessageBoxGetChild (helpBox, XmDIALOG_CANCEL_BUTTON);
    XtUnmanageChild (temp);
    temp = XmMessageBoxGetChild (helpBox, XmDIALOG_HELP_BUTTON);
    XtUnmanageChild (temp);

    /* arrange for getHelp button to pop up helpBox */
    XtAddCallback(help, XmNvalueChangedCallback, ShowHelp, helpBox);

    XtRealizeWidget(topLevel);
    XtAppMainLoop(app_context);
    exit(0);
}

