/*
 * Copyright 1989 O'Reilly and Associates, Inc.

     The X Consortium, and any party obtaining a copy of these files from
     the X Consortium, directly or indirectly, is granted, free of charge, a
     full and unrestricted irrevocable, world-wide, paid up, royalty-free,
     nonexclusive right and license to deal in this software and
     documentation files (the "Software"), including without limitation the
     rights to use, copy, modify, merge, publish, distribute, sublicense,
     and/or sell copies of the Software, and to permit persons who receive
     copies from any such party to do so.  This license includes without
     limitation a license to do the foregoing actions under any patents of
     the party supplying this software to the X Consortium.

     $Id: ScrollBox.c,v 1.15 2008/07/14 04:24:52 wmcbrine Exp $
 */

/* ScrollBox.c - scrollBox composite widget */

#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>

#include "x11/ScrollBoxP.h"

#include <stdio.h>

#define INITIAL_WIDTH 300
#define INITIAL_HEIGHT 300

/************************************************************************
 *                                                                      *
 * scrollBox Resources                                                  *
 *                                                                      *
 ************************************************************************/

static XtResource resources[] =
{
    { XtNhSpace, XtCHSpace, XtRDimension, sizeof(Dimension),
        XtOffset(ScrollBoxWidget, scrollBox.h_space),
        XtRImmediate, (XtPointer)4 },
    { XtNvSpace, XtCVSpace, XtRDimension, sizeof(Dimension),
        XtOffset(ScrollBoxWidget, scrollBox.v_space),
        XtRImmediate, (XtPointer)4 },
    { XtNheightInc, XtCHeightInc, XtRDimension, sizeof(Dimension),
        XtOffset(ScrollBoxWidget, scrollBox.increment_height),
        XtRImmediate, (XtPointer)13 },
    { XtNwidthInc, XtCWidthInc, XtRDimension, sizeof(Dimension),
        XtOffset(ScrollBoxWidget, scrollBox.increment_width),
        XtRImmediate, (XtPointer)7 },
};

/************************************************************************
 *                                                                      *
 * Full class record constant                                           *
 *                                                                      *
 ************************************************************************/

static void Initialize(Widget, Widget, ArgList, Cardinal *);
static void Resize(Widget);
static Boolean SetValues(Widget, Widget, Widget, ArgList, Cardinal *);
static void ChangeManaged(Widget);
static XtGeometryResult QueryGeometry(Widget, XtWidgetGeometry *,
                                      XtWidgetGeometry *);
static XtGeometryResult GeometryManager(Widget, XtWidgetGeometry *,
                                        XtWidgetGeometry *);
static void RefigureLocations(Widget);

ScrollBoxClassRec scrollBoxClassRec = {
  {
    /* core_class fields        */
        /* superclass           */  (WidgetClass) &compositeClassRec,
        /* class_name           */  "scrollBox",
        /* widget_size          */  sizeof(ScrollBoxRec),
        /* class_initialize     */  NULL,
        /* class_part_init      */  NULL,
        /* class_inited         */  FALSE,
        /* initialize           */  Initialize,
        /* initialize_hook      */  NULL,
        /* realize              */  XtInheritRealize,
        /* actions              */  NULL,
        /* num_actions          */  0,
        /* resources            */  resources,
        /* num_resources        */  XtNumber(resources),
        /* xrm_class            */  NULLQUARK,
        /* compress_motion      */  TRUE,
        /* compress_exposure    */  TRUE,
        /* compress_enterleave  */  TRUE,
        /* visible_interest     */  FALSE,
        /* destroy              */  NULL,
        /* resize               */  Resize,
        /* expose               */  NULL,
        /* set_values           */  SetValues,
        /* 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       */  QueryGeometry,
        /* display_accelerator  */  XtInheritDisplayAccelerator,
        /* extension            */  NULL
  },{
    /* composite_class fields   */
        /* geometry_manager     */  GeometryManager,
        /* change_managed       */  ChangeManaged,
        /* insert_child         */  XtInheritInsertChild,
        /* delete_child         */  XtInheritDeleteChild,
        /* extension            */  NULL
  },{
    /* scrollBox class fields   */
        /* empty                */  0,
  }
};

WidgetClass scrollBoxWidgetClass = (WidgetClass)&scrollBoxClassRec;


/************************************************************************
 *                                                                      *
 * Private Routines                                                     *
 *                                                                      *
 ************************************************************************/

/* Do a layout, either actually assigning positions, or just
   calculating size. */

static void DoLayout(Widget w, Boolean doit)
{
    ScrollBoxWidget sbw = (ScrollBoxWidget)w;
    Widget wmain, vscroll, hscroll, child;
    Dimension mw, mh;   /* main window */
    Dimension vh;   /* vertical scrollbar length (height) */
    Dimension hw;   /* horizontal scrollbar length (width) */
    Position vx;
    Position hy;
    Cardinal i;

    if (sbw->composite.num_children != 3)
        XtAppError(XtWidgetToApplicationContext(w),
            "ScrollBox: must manage exactly three widgets.");

    for (i = 0; i < sbw->composite.num_children; i++)
    {
        child = sbw->composite.children[i];

        if (!XtIsManaged(child))
            XtAppError(XtWidgetToApplicationContext(w),
                "ScrollBox: all three widgets must be managed.");
    }

    /* Child one is the main window, two is the vertical scrollbar,
       and three is the horizontal scrollbar. */

    wmain = sbw->composite.children[0];
    vscroll = sbw->composite.children[1];
    hscroll = sbw->composite.children[2];

    /* Size all three widgets so that space is fully utilized. */

    mw = sbw->core.width - (2 * sbw->scrollBox.h_space) -
        vscroll->core.width - (2 * vscroll->core.border_width) -
        (2 * wmain->core.border_width);

    mh = sbw->core.height - (2 * sbw->scrollBox.v_space) -
        hscroll->core.height - (2 * hscroll->core.border_width) -
        (2 * wmain->core.border_width);

    /* Force the main window to be sized to the appropriate increment. */

    mw = (mw / sbw->scrollBox.increment_width) *
        sbw->scrollBox.increment_width;

    mh = ((mh / sbw->scrollBox.increment_height) *
        sbw->scrollBox.increment_height) +
        sbw->scrollBox.increment_height;

    vx = wmain->core.x + mw + sbw->scrollBox.h_space +
        wmain->core.border_width + vscroll->core.border_width;

    hy = wmain->core.y + mh + sbw->scrollBox.v_space +
        wmain->core.border_width + hscroll->core.border_width;

    vh = mh;   /* scrollbars are always same length as main window */
    hw = mw;

    if (doit)
    {
        XtResizeWidget(wmain, mw, mh, 1);

        XtResizeWidget(vscroll, vscroll->core.width, vh, 1);
        XtMoveWidget(vscroll, vx, vscroll->core.y);

        XtResizeWidget(hscroll, hw, hscroll->core.height, 1);
        XtMoveWidget(hscroll, hscroll->core.x, hy);
    }
}

static XtGeometryResult GeometryManager(Widget w, XtWidgetGeometry *request,
                                        XtWidgetGeometry *reply)
{
    XtWidgetGeometry allowed;

    if (request->request_mode & ~(XtCWQueryOnly | CWWidth | CWHeight))
        return XtGeometryNo;

    if (request->request_mode & CWWidth)
        allowed.width = request->width;
    else
        allowed.width = w->core.width;

    if (request->request_mode & CWHeight)
        allowed.height = request->height;
    else
        allowed.height = w->core.height;

    if (allowed.width == w->core.width && allowed.height == w->core.height)
        return XtGeometryNo;

    if (!(request->request_mode & XtCWQueryOnly))
        RefigureLocations(w);

    return XtGeometryYes;
}

static void RefigureLocations(Widget w)
{
    DoLayout(w, False);
}

/* Calculate preferred size.  We can't just use the current sizes
   of the children, because that calculation would always end up with
   our current size.  Could query each child, and use that size to
   recalculate a size for us, then if it ends up being larger than width
   and height passed in, accept bounding box. However, we know our
   children and they don't have any particular preferred geometry,
   except the bigger the better. Therefore, if the parent suggested a
   size, we'll take it. */

static XtGeometryResult QueryGeometry(Widget w, XtWidgetGeometry *request,
                                      XtWidgetGeometry *reply_return)
{
    XtGeometryResult result=XtGeometryNo;

    request->request_mode &= CWWidth | CWHeight;

    /* parent isn't going to change w or h, so nothing to re-compute */

    if (request->request_mode == 0)
        return XtGeometryYes;

    /* if proposed size is large enough, accept it.  Otherwise, suggest
       our arbitrary initial size. */

    if (request->request_mode & CWHeight)
    {
        if (request->height < INITIAL_HEIGHT)
        {
            result = XtGeometryAlmost;
            reply_return->height = INITIAL_HEIGHT;
            reply_return->request_mode &= CWHeight;
        }
        else
            result = XtGeometryYes;
    }

    if (request->request_mode & CWWidth)
    {
        if (request->width < INITIAL_WIDTH)
        {
            result = XtGeometryAlmost;
            reply_return->width = INITIAL_WIDTH;
            reply_return->request_mode &= CWWidth;
        }
        else
            result = XtGeometryYes;
    }

    return result;
}

/* Actually layout the scrollBox  */

static void Resize(Widget w)
{
    DoLayout(w, True);
}

static void ChangeManaged(Widget w)
{
    DoLayout(w, True);
}

static void Initialize(Widget request, Widget new,
                       ArgList args, Cardinal *num_args)
{
    ScrollBoxWidget newsbw = (ScrollBoxWidget)new;

    if (newsbw->core.width == 0)
        newsbw->core.width = INITIAL_WIDTH;

    if (newsbw->core.height == 0)
        newsbw->core.height = INITIAL_HEIGHT;

}

static Boolean SetValues(Widget current, Widget request, Widget new,
                         ArgList args, Cardinal *num_args)
{
    ScrollBoxWidget sbwcurrent = (ScrollBoxWidget)current;
    ScrollBoxWidget sbwnew = (ScrollBoxWidget)new;

    /* need to relayout if h_space or v_space change */

    if ((sbwnew->scrollBox.h_space != sbwcurrent->scrollBox.h_space) ||
        (sbwnew->scrollBox.v_space != sbwcurrent->scrollBox.v_space))
        DoLayout(new, True);

    return False;
}
