/* *************************************************************************
 *  Copyright (C) 1990-1993 by ILOG.
 *  All Rights Reserved.
 *
 *  N O T I C E
 *
 *  THIS MATERIAL IS CONSIDERED A TRADE SECRET BY ILOG.
 *  UNAUTHORIZED ACCESS, USE, REPRODUCTION OR DISTRIBUTION IS PROHIBITED.
 * *************************************************************************/

#include <X11/Intrinsic.h>
#include <Xm/Xm.h>
#include <Xm/ScrollBar.h>
#include <scrollhook.h>

// --------------------------------------------------------------------------
void
IlvScrollViewHook::adjustScrollBars()
{
    IlvRect bbox = _bbox;
    IlvTransformer* t = getManager()->getTransformer(getView());
    if(t) t->apply(bbox);
    IlvDim w,h;
    getView()->size(w,h);
    IlvRect visibleRect(0,0,w,h);
    bbox.add(visibleRect); // In case when the view is larger than its contents
    _previousx = -bbox.x();
    _previousy = -bbox.y();
    //Initialize ScrollBars
    if (_verticalSB)
	    XtVaSetValues((Widget)_verticalSB,
			  XmNminimum,       0,
			  XmNmaximum,       bbox.h(),
			  XmNsliderSize,    h,
			  XmNvalue,         _previousy,
			  XmNpageIncrement, h/2,
			  0);
    if (_horizontalSB)
	    XtVaSetValues((Widget)_horizontalSB,
			  XmNminimum,       0,
			  XmNmaximum,       bbox.w(),
			  XmNsliderSize,    w,
			  XmNvalue,         _previousx,
			  XmNpageIncrement, w/2,
			  0);
}

// --------------------------------------------------------------------------
void
IlvScrollViewHook::adjustView()
{
    //Compute Scrollbars positions
    int scrollX = (int)_previousx;
    int scrollY = (int)_previousy;
    int sd, in, p;
    if (_verticalSB)
	    XmScrollBarGetValues((Widget)_verticalSB, &scrollY, &sd, &in, &p);
    if (_horizontalSB)
	    XmScrollBarGetValues((Widget)_horizontalSB, &scrollX, &sd, &in, &p);
    getManager()->translateView(getView(),
				_previousx-scrollX, _previousy-scrollY);
    IlvRect bbox = _bbox;
    IlvTransformer* t = getManager()->getTransformer(getView());
    if(t) t->apply(bbox);
    IlvDim w,h;
    getView()->size(w,h);
    IlvRect visibleRect(0,0,w,h);
    bbox.add(visibleRect); // In case when the view is larger than its contents
    _previousx = -bbox.x();
    _previousy = -bbox.y();
}

// --------------------------------------------------------------------------
static void
Scroll(Widget, XtPointer cdata, XtPointer)
{
    ((IlvScrollViewHook*)cdata)->adjustView();
}

// --------------------------------------------------------------------------
void
IlvScrollViewHook::initScrollBars()
{
    if (_verticalSB) {
	XtAddCallback((Widget)_verticalSB, XmNdragCallback, Scroll, (XtPointer)this);
	XtAddCallback((Widget)_verticalSB, XmNvalueChangedCallback, Scroll, (XtPointer)this);
    }
    if (_horizontalSB) {
	XtAddCallback((Widget)_horizontalSB, XmNdragCallback, Scroll, (XtPointer)this);
	XtAddCallback((Widget)_horizontalSB, XmNvalueChangedCallback, Scroll, (XtPointer)this);
    }
    adjustScrollBars();
}
