/* This file is part of `mogul'
 * Copyright (c) 1995 David Deaven
 *
 * In the following, "you" and "You" refer to any entity other than 
 * the Microsoft corporation and its subsidiaries.  All rights are
 * reserved by the author in connection with Microsoft and its
 * subsidiaries.  The Microsoft Network is explicity denied the right
 * to copy, reproduce, or transmit this software.
 *
 *   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.
 *
 * $Author: deaven $
 * $Id: zoom.c,v 2.0 1996/07/09 20:48:28 deaven Exp deaven $
 */

#ifndef MOGUL_SOURCE
#define MOGUL_SOURCE
#endif

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/Scrollbar.h>
#include <X11/Xaw/Command.h>
#include <X11/Xaw/Label.h>
#include "dmd/memory.h"
#include "dmd/geometry.h"
#include "xmogul.h"

#define MAX_ZOOM 10.0 /* maximum zoom-up */

struct ZoomRec {
	Widget w;
	double width, height;
};

static void set_scroll(Widget w, float top)
{
	Arg arg;
	if(sizeof(float) > sizeof(XtArgVal))
	  XtSetArg(arg, XtNtopOfThumb, &top);
	else {
	  XtArgVal *l_top = (XtArgVal *) &top;
	  XtSetArg(arg, XtNtopOfThumb, *l_top);
	}
	XtSetValues(w, &arg, (Cardinal) 1);
}

void MPZoomZero(MogulPanel mp)
{
	float top;

	mp->zoom->width = mp->plot->attr.width;
	mp->zoom->height = mp->plot->attr.height;

	top = 1.0 - 1.0 / sqrt(MAX_ZOOM);

	set_scroll(mp->zoom->w, top);
}

static void zero_callback(Widget widget,
  XtPointer client_data, XtPointer call_data)
{
	MogulPanel mp = (MogulPanel) client_data;
	MPZoomZero(mp);
}

static void jump_callback(Widget widget,
  XtPointer client_data, XtPointer call_data)
{
	MogulPanel mp = (MogulPanel) client_data;
	float percent = *((float *) call_data);

	percent = MAX_ZOOM * (1.0 - percent) * (1.0 - percent);

	mp->plot->attr.width = mp->zoom->width / percent;
	mp->plot->attr.height = mp->zoom->height / percent;

	if(MogulRender(mp->plot, (MogulDevice) MWGetDevice(mp->mogul)))
	  MogulPerror("rendering in zoom control");
}

void MPCreateZoom(MogulPanel mp)
{
	Widget form, button;

	mp->zoom = NewPointer(mp->zoom);

	form =
	  XtVaCreateManagedWidget("ZoomControls", formWidgetClass, mp->frame,
	  NULL);

	/* zoom scrollbar */

	mp->zoom->w =
	  XtVaCreateManagedWidget("scroll", scrollbarWidgetClass, form,
	  XtNorientation, XtorientVertical, NULL);
	XtAddCallback(mp->zoom->w, XtNjumpProc, jump_callback, mp);

	/* zero button */

	button =
	  XtVaCreateManagedWidget("zero", commandWidgetClass, form, NULL);
	XtAddCallback(button, XtNcallback, zero_callback, mp);

	MPZoomZero(mp);
}
