/*
    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:		list_form.c
*
* Description:	This file contains routines for the creation and 
*
* History:	by Jason Gobat and Darren Atkinson
*
****************************************************************************/

# include <stdio.h>
# include <X11/Intrinsic.h>
# include <X11/StringDefs.h>
# include <X11/Shell.h>
# include <X11/Xaw/Dialog.h>
# include <X11/Xaw/Form.h>
# include <X11/Xaw/Label.h>
# include <X11/Xaw/List.h>
# include <X11/Xaw/Viewport.h>
# include "forms.h"

# define max(x,y)	((x) > (y) ? (x) : (y))
# define min(x,y)	((x) < (y) ? (x) : (y))

static void SetButtonState ();

static unsigned selected;

#define Okay   1
#define Cancel 2

static struct {
   String	name;
   unsigned	flag;
} buttons [ ] = {
   {"okay",	Okay},
   {"cancel",	Cancel},
};


ListForm *CreateListForm (parent_w, label)
   Widget	parent_w;
   String	label;
{
   unsigned		i;
   Arg			arglist[10];
   Cardinal		count;
   ListForm		*list_form;

   list_form = XtNew (ListForm);

   list_form -> shellwidget = XtCreatePopupShell ("listShell", 
                                transientShellWidgetClass, parent_w, 
                                NULL, 0);

   list_form -> formwidget = XtCreateManagedWidget ("listForm", 
                                formWidgetClass, list_form -> shellwidget, 
                                NULL, 0);

   count = 0;
   XtSetArg (arglist [count], XtNlabel, label); count++;
   XtSetArg (arglist [count], XtNjustify, XtJustifyLeft); count++;
   XtSetArg (arglist [count], XtNtop, XawChainTop); count++;
   XtSetArg (arglist [count], XtNbottom, XawChainTop); count++;
   XtSetArg (arglist [count], XtNborderWidth, 0); count++;
   
   list_form -> labelwidget = XtCreateManagedWidget ("label",
                   labelWidgetClass, list_form -> formwidget, 
                   arglist, count);
   
   count = 0;
   XtSetArg (arglist [count], XtNallowVert, True); count++;
   XtSetArg (arglist [count], XtNuseRight, True); count++;
   XtSetArg (arglist [count], XtNtop, XawChainTop); count++;
   XtSetArg (arglist [count], XtNbottom, XawChainBottom); count++;
   XtSetArg (arglist [count], XtNleft, XawChainLeft); count++;
   XtSetArg (arglist [count], XtNright, XawChainRight); count++;
   XtSetArg (arglist [count], XtNfromVert, list_form -> labelwidget); count++;

   list_form -> viewportwidget = XtCreateManagedWidget ("listViewport",
                                viewportWidgetClass, 
                                list_form -> formwidget, arglist, count);

   count = 0;
   XtSetArg (arglist [count], XtNdefaultColumns, 1); count++;
   XtSetArg (arglist [count], XtNforceColumns, True); count++;

   list_form -> listwidget = XtCreateManagedWidget ("list", 
                   listWidgetClass, list_form -> viewportwidget, 
                   arglist, count);
  
   count = 0;
   XtSetArg (arglist [count], XtNborderWidth, 0); count++;
   XtSetArg (arglist [count], XtNlabel, ""); count++;
   XtSetArg (arglist [count], XtNtop, XawChainBottom); count++;
   XtSetArg (arglist [count], XtNbottom, XawChainBottom); count++;
   XtSetArg (arglist [count], XtNleft, XawChainLeft); count++;
   XtSetArg (arglist [count], XtNright, XawChainLeft); count++;
   XtSetArg (arglist [count], XtNfromVert, 
             list_form -> viewportwidget); count++;

   list_form -> dialogwidget = XtCreateManagedWidget ("dialog", 
                                 dialogWidgetClass, list_form -> formwidget, 
                                 arglist, count); 

   for (i = 0 ; i < XtNumber (buttons) ; i++)
      XawDialogAddButton (list_form -> dialogwidget, buttons [i].name, 
                             SetButtonState, &buttons [i].flag);

   list_form -> topwidget = parent_w;

   return list_form;
}


int GetListFormValue (list_form, highlight_item)
   ListForm		*list_form;
   int			highlight_item;
{
   Widget	        shell;
   XEvent	        event;
   XawListReturnStruct *item;
   unsigned		flag;
   int			list_index;
   Arg			arglist[4];
   Cardinal		count;
   Dimension    	formwidth, formheight,
                	topwidth, topheight,
                	borderwidth;
   Position     	formx,formy,topx,topy;

   shell = list_form -> shellwidget;

   XtRealizeWidget (shell);

   count = 0;
   XtSetArg(arglist[count], XtNx, &topx); count++;
   XtSetArg(arglist[count], XtNy, &topy); count++;
   XtSetArg(arglist[count], XtNwidth, &topwidth); count++;
   XtSetArg(arglist[count], XtNheight, &topheight); count++;
   XtGetValues(list_form -> topwidget, arglist, count);

   count = 0;
   XtSetArg(arglist[count], XtNwidth, &formwidth); count++;
   XtSetArg(arglist[count], XtNheight, &formheight); count++;
   XtSetArg(arglist[count], XtNborderWidth, &borderwidth); count++;
   XtGetValues(shell, arglist, count);

   formx = max(0, 
       min(topx + ((Position)topwidth - (Position)formwidth) / 2, 
           (Position)DisplayWidth(XtDisplay(shell), 
	    DefaultScreen(XtDisplay(shell))) -
            (Position)formwidth - 2 * (Position)borderwidth));
   formy = max(0, 
       min(topy + ((Position)topheight - (Position)formheight) / 2,
           (Position)DisplayHeight(XtDisplay(shell), 
	    DefaultScreen(XtDisplay(shell))) -
            (Position)formheight - 2 * (Position)borderwidth));

   count = 0;
   XtSetArg(arglist[count], XtNx, formx); count++;
   XtSetArg(arglist[count], XtNy, formy); count++;
   XtSetValues(shell, arglist, count);
  
   XtPopup (shell, XtGrabExclusive);

   XWarpPointer(XtDisplay(shell), 
                XtWindow(list_form -> topwidget),
                XtWindow(shell), 
                0, 0, 0, 0,
                formwidth / 2, formheight / 2);

   if (highlight_item != -1)
      XawListHighlight (list_form -> listwidget, highlight_item);
   else
      XawListUnhighlight (list_form -> listwidget);

   flag = 1;
   while (flag) {
      selected = 0;
      while (!(selected & (Okay | Cancel))) {
         XtAppNextEvent (XtWidgetToApplicationContext (shell), &event);
         XtDispatchEvent (&event);
      }

      if (selected == Okay) {
         item = XawListShowCurrent (list_form -> listwidget);
         if (item -> list_index != XAW_LIST_NONE) {
            list_index = item -> list_index;
            flag = 0;
         }
      } 
      else {
         flag = 0;
         list_index = XAW_LIST_NONE;
      } 
   }
     
   XtPopdown (shell); 
   return list_index;
}


void SetListItems (list_form, items, nitems)
   ListForm	*list_form;
   String	*items;
   int		nitems;
{
   XawListChange (list_form -> listwidget, items, nitems, 0, True);
}


static void SetButtonState (w, client_data, call_data)
   Widget 	w;
   XtPointer	client_data,
		call_data;
{
   selected = *(unsigned *) client_data;
}
