/*
    This file is part of the FElt finite element analysis package.
    Copyright (C) 1993 Jason I. Gobat and Darren C. Atkinson

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

/************************************************************************
 * File:
 *
 * Description:	
 *		
 ************************************************************************/

# include <stdio.h>
# include <unistd.h>
# include <X11/Intrinsic.h>
# include <X11/StringDefs.h>
# include <X11/Xaw/AsciiText.h>
# include <X11/Xaw/Command.h>
# include <X11/Xaw/Dialog.h>
# include <X11/Xaw/Form.h>
# include <X11/Xaw/MenuButton.h>
# include <X11/Xaw/Reports.h>
# include <X11/Xaw/SimpleMenu.h>
# include <X11/Xaw/Sme.h>
# include <X11/Xaw/SmeBSB.h>
# include "Drawing.h"
# include "dialog.h"
# include "forms.h"
# include "shells.h"
# include "globals.h"
# include "procedures.h"
# include "definitions.h"
# include "truss.xbm"
# include "question.xbm"
# include "computer.xbm"


static char *defaults [ ] = {
# include "xfelt.ad.h"
NULL
};

# ifndef LPCOMMAND
# define LPCOMMAND "lp"
# endif

# ifndef LPGRAPHICS
# define LPGRAPHICS "lp -oraw"
# endif

# ifndef XPRCOMMAND
# define XPRCOMMAND "xpr"
# endif

# ifndef FELTCOMMAND
# define FELTCOMMAND "felt"
# endif

void PanelCallback (widget, clientData, callData)
    Widget    widget;
    XtPointer clientData;
    XtPointer callData;
{
       switch (*(PanelId *) clientData) {

       case New:
           StartNew ();
	   break;

       case Load:
           OpenFile ();
	   break;

       case Save:
           WriteFeltFile ();
	   break;

       case SaveAs:
           WriteNamedFile ();
	   break;

       case Print:
	   PrintEditContents (editwin);
           break;

       case Cut:
           CutText (True);
	   break;

       case Paste:
           PasteText ();
	   break;

       case Copy:
           CopyText ();
	   break;

       case Configure:
           ConfigureXFelt ();
           break;

       case Exit:
           Quit ();
           break;

       case Options:
           SetFeltOptions ();
           break;

       case Info:
	   PopupDialog (info_dialog, "XFelt v1.0 by JIG and DCA", NULL, NULL);
           break;

       case Run:
           if (filename == NULL && 
               !XawAsciiSourceChanged(XawTextGetSource(editwin)))
              PopupDialog (error_dialog,"No input file is defined",NULL,NULL);
           else
              ExecuteFelt ();
           break;

       } /* end switch top of control panel */
}

/************************************************************************
 * Function:	 main							*
 *									*
 * Parameters:	 argc - number of command line arguments		*
 *		 argv - array of command line arguments			*
 *									*
 * Return value: 0 on success; nonzero on error				*
 *									*
 * Calls:	 ???							*
 *									*
 * Called by:	 none							*
 *									*
 * Global data:	 ???							*
 *									*
 * Description:	 Main is the startup function for the xfelt program.	*
 ************************************************************************/

int main (argc, argv)
    int   argc;
    char *argv [ ];
{
    int		   i, j;
    char	   string [32];
    String	   startup_file;
    Arg		   arglist [14];
    Cardinal	   count;
    XtTranslations trans;
    Window	   window;


    /* Create the top level widget. */

    toplevel = XtAppInitialize (&app_context, "XFelt", NULL, 0, &argc, argv,
				defaults, NULL, 0);

      
    /* Create all the other widgets */

    form     = XtCreateManagedWidget
		("form", formWidgetClass, toplevel, NULL, 0);

    control  = XtCreateManagedWidget
		("control", formWidgetClass, form, NULL, 0);

    count = 0;
    XtSetArg (arglist [count], XtNtype, XawAsciiFile); count++;
    XtSetArg (arglist [count], XtNeditType, XawtextEdit); count ++;

    editwin  = XtCreateManagedWidget
		("editwin", asciiTextWidgetClass, form, arglist, count);


    /* Create the bitmaps. */

    window = RootWindowOfScreen (XtScreen (toplevel));
    question = XCreateBitmapFromData (XtDisplay (toplevel), window,
				question_bits, question_width, question_height);

    computer = XCreateBitmapFromData (XtDisplay (toplevel), window,
				computer_bits, computer_width, computer_height);

    truss = XCreateBitmapFromData (XtDisplay (toplevel), window,
				truss_bits, truss_width, truss_height);


    /* Create the popup shells */

    outputShell  = CreateOutputShell ();
    drawingShell = CreateDrawingShell ();


    /* Focus all keyboard input to the edit widget. */

    XtSetKeyboardFocus (form, editwin);


    /* Create the control panel menus and buttons. */

    for (i = 0; i < XtNumber (panel); i ++) {
	panel [i].button = XtCreateManagedWidget
			   (panel [i].name, *panel [i].class, control, NULL, 0);

	if (!strcmp (panel [i].name, "run")) {
	    XtSetArg (arglist [0], XtNleftBitmap, computer);
	    XtSetValues (panel [i].button, arglist, 1);
	} else if (!strcmp (panel [i].name, "info")) {
	    XtSetArg (arglist [0], XtNleftBitmap, question);
	    XtSetValues (panel [i].button, arglist, 1);
	}

	if (panel [i].class == &menuButtonWidgetClass) {
	    sprintf (string, "%sMenu", panel [i].name);
	    panel [i].menu = XtCreatePopupShell
			     (string, simpleMenuWidgetClass, control, NULL, 0);

	    for (j = 0; j < panel [i].numentries; j ++) {
		panel [i].menuentry [j].widget = XtCreateManagedWidget
		 (panel [i].menuentry [j].name, smeBSBObjectClass,
		  panel [i].menu, NULL, 0);

		XtAddCallback (panel [i].menuentry [j].widget, XtNcallback,
		 PanelCallback, &panel [i].menuentry [j].id);
	    }

	} else if (panel [i].class == &commandWidgetClass)
	    XtAddCallback (panel [i].button, XtNcallback, PanelCallback,
	     &panel [i].menuentry [0].id);
    }


    /* Create the dialogs. */

    info_dialog    = CreateDialog (toplevel, "infod", Okay);
    error_dialog   = CreateDialog (toplevel, "errord", Okay);
    file_dialog    = CreateDialog (toplevel, "filed", Okay | Cancel);
    proceed_dialog = CreateDialog (toplevel, "proceedd", Okay | Cancel);
    qsave_dialog   = CreateDialog (toplevel, "qsaved", Yes | No | Cancel);

    XtSetArg (arglist [0], XtNicon, truss);
    XtSetValues (info_dialog -> dialogwidget, arglist, 1);

    option_form = CreateToggleForm (toplevel, option_entries);
    setup_form  = CreateTextEntryForm (toplevel, setup_entries);

    felt_command = FELTCOMMAND;
    lp_command   = LPCOMMAND;
    xpr_command  = XPRCOMMAND;
    lp_graphics  = LPGRAPHICS; 

    /* register the action table and set-up the translations */

    XtAppAddActions (app_context, actiontable, XtNumber (actiontable));
    trans = XtParseTranslationTable (default_translations);

    XtOverrideTranslations (editwin, trans);


    /* Figure out if the user is starting with a file */

    if (argc > 1) {
       if (access (argv[1], F_OK) == 0) {
          if (access (argv[1], R_OK | W_OK) != 0)
             PopupDialog (error_dialog, 
                 "file is not accessible, check file permissions",NULL,NULL);
          else {
             startup_file = argv[1];
             filename = startup_file;
          }
       }
       else
          filename = argv[1];
    }
    else {
       startup_file = NULL;
       filename = NULL;
    }

    count = 0;
    XtSetArg (arglist [count], XtNstring, startup_file); count++;
    XtSetValues (editwin, arglist, count);

    UpdateLabel ();

    /* Realize the top level widget */

    XtRealizeWidget (toplevel);


    /* Enter the main event loop */

    XtAppMainLoop (app_context);

    return 0; /* NOTREACHED */
}
