/* Tform widget

   This widget is used for the outer window, with the Title3270 and
   X3270 windows as children.  It would have been nice to use a
   Form widget here, but that has too many problems, particularly
   with resizing.							*/

#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>
#include "TformP.h"

static void Initialize(), Resize();
static XtGeometryResult GeometryManager();
static void reposition();

TformClassRec tformClassRec = {
  /* Core fields */
  { /* superclass		*/	(WidgetClass) &compositeClassRec,
    /* class_name		*/	"Tform",
    /* widget_size		*/	sizeof(TformRec),
    /* class_initialize		*/	NULL,
    /* class_part_initialize	*/	NULL,
    /* class_inited		*/	FALSE,
    /* initialize	  	*/	Initialize,
    /* initialize_hook		*/	NULL,
    /* realize			*/	XtInheritRealize,
    /* actions			*/	NULL,
    /* num_actions		*/	0,
    /* resources		*/	NULL,
    /* num_resources		*/	0,
    /* xrm_class		*/	NULLQUARK,
    /* compress_motion		*/	TRUE,
    /* compress_exposure	*/	TRUE,
    /* compress_enterleave	*/	TRUE,
    /* visible_interest		*/	FALSE,
    /* destroy			*/	NULL,
    /* resize			*/	Resize,
    /* expose			*/	NULL,
    /* set_values		*/	NULL,
    /* set_values_hook		*/	NULL,
    /* set_values_almost	*/	XtInheritSetValuesAlmost,
    /* get_values_hook		*/	NULL,
    /* accept_focus		*/	NULL,
    /* version			*/	XtVersion,
    /* callback_private		*/	NULL,
    /* tm_table			*/	NULL,
    /* query_geometry		*/	NULL,
    /* display_accelerator      */      XtInheritDisplayAccelerator,
    /* extension                */      NULL,
  },
  /* Composite fields */
  { /* geometry_manager         */	GeometryManager,
    /* change_managed           */	NULL,
    /* insert_child	        */	XtInheritInsertChild,
    /* delete_child	        */	XtInheritDeleteChild,
    /* extension	        */	NULL
  },
  /* Tform fields */
  { /* empty			*/	0 }
};

WidgetClass tformWidgetClass = (WidgetClass) &tformClassRec;


/*ARGSUSED*/ static void Initialize(request, new)
     Widget request, new;
{
  TformWidget tw = (TformWidget) new;

  if (!tw->core.width) tw->core.width = 10;
  if (!tw->core.height) tw->core.height = 10;
}


static void Resize(w)
    Widget w;
{
  reposition(w);
}


/*ARGSUSED*/ static XtGeometryResult GeometryManager(w, request, reply)
     Widget w;
     XtWidgetGeometry *request;
     XtWidgetGeometry *reply;
{
  XtGeometryMask mode = request->request_mode;

  if (mode & ~(CWWidth | CWHeight | CWBorderWidth | XtCWQueryOnly))
    return XtGeometryNo;
  if (mode & XtCWQueryOnly) return XtGeometryYes;

  /* Do anything that is requested */
  if (mode & CWWidth) w->core.width = request->width;
  if (mode & CWHeight) w->core.height = request->height;
  if (mode & CWBorderWidth) w->core.border_width = request->border_width;
  reposition(w->core.parent);
  return XtGeometryYes;
}


static void reposition(tw)
     TformWidget tw;
{
  Widget titlew, textw;
  Dimension title_width, title_height, text_width, text_height, total_height;
  Position x, y;

  if (tw->composite.num_children != 2) return;
  titlew = tw->composite.children[0];
  textw = tw->composite.children[1];
  if (!XtIsManaged(titlew) || !XtIsManaged(textw)) return;
  
  title_width =  titlew->core.width  + 2 * titlew->core.border_width;
  title_height = titlew->core.height ? titlew->core.height +
                                       2 * titlew->core.border_width : 0;
  text_width =   textw->core.width   + 2 * textw->core.border_width;
  text_height =  textw->core.height  + 2 * textw->core.border_width;
  total_height = title_height + text_height;
  
  /* If the window is too small, ask to make it larger */
  if (text_width > tw->core.width || total_height > tw->core.height)
    {
      if (XtMakeResizeRequest(tw, text_width, total_height,
			      &text_width, &total_height) == XtGeometryAlmost)
	XtMakeResizeRequest(tw, text_width, total_height, NULL, NULL);
    }

  if (title_width != tw->core.width)
    {
      int nwidth;
      nwidth = (int) tw->core.width - 2 * (int) titlew->core.border_width;
      if (nwidth > 0)
	XtResizeWidget(titlew, (Dimension) nwidth, titlew->core.height,
		       titlew->core.border_width);
    }

  /* Center the text widget and place it below the title */
  x = ((int) tw->core.width - (int) text_width) / 2;
  if (x < 0) x = 0;
  y = (int) title_height + ((int) tw->core.height - (int) total_height) / 2;
  if (y < title_height) y = title_height;
  XtMoveWidget(textw, x, y);
}
