/*
 *  Copyright (c) 1994, Riley Rainey,  riley@netcon.com
 *
 *  Permission to use, copy, modify and distribute (without charge) this
 *  software, documentation, images, etc. is granted, provided that this 
 *  comment and the author's name is retained.
 *
 *  This software is provided by the author as is, and without any expressed
 *  or implied warranties, including, but not limited to, the implied
 *  warranties of merchantability and fitness for a particular purpose.  In no
 *  event shall the author be liable for any direct, indirect, incidental, or
 *  consequential damages arising in any way out of the use of this software.
 */

#include <Xm/DrawingA.h>
#include <stdio.h>
#include "gedit.h"

static String normal_translations =
	"<Btn1Down>:		point-begin()	\n\
	<Btn1Up>:		point-end()";

static String extra_translations =
	"Shift<Btn1Down>:	point-begin(extend) \n\
	<Btn1Down>:		point-begin()	\n\
	<Btn1Motion>:		point-motion()	\n\
	<Btn1Up>:		point-end()	\n\
	<Btn2Down>:		close-polygon()";

static XtTranslations	normal, extra;

static void PointBegin(), PointMotion(), PointEnd(), DeleteCurrent(),
		ClosePolygon();

static XtActionsRec	action_list[] = {
	{ "point-begin",	PointBegin },
	{ "point-motion",	PointMotion },
	{ "point-end",		PointEnd },
	{ "close-polygon",	ClosePolygon },
	{ "delete-selection",	DeleteCurrent }
	};

extern void BeginPolygonPoint(), CompletePolygon(), CompleteDrag();
extern void CompleteMarker();
extern void BeginCirclePoint(), DragCirclePoint(), CompleteCircle();

void
InitializeTranslations (app, w1, w2)
XtAppContext	app;
Widget		w1, w2;
{

	XtAppAddActions (app, action_list, XtNumber(action_list));

	normal = XtParseTranslationTable (normal_translations);
	extra = XtParseTranslationTable (extra_translations);

	XtVaSetValues (w1,
		XmNtranslations,	extra,
		NULL);

	XtVaSetValues (w2,
		XmNtranslations,	extra,
		NULL);

}

void InstallNormalTranslations (w)
Widget	w;
{
	view_info_t	*p;

	XtVaGetValues (w,
		XmNuserData,	&p,
		NULL);

	XtVaSetValues (w,
		XmNtranslations,	normal,
		NULL);

	XtVaSetValues (p->other_widget,
		XmNtranslations,	normal,
		NULL);
}

void InstallExtraTranslations (w)
Widget	w;
{
	view_info_t	*p;

	XtVaGetValues (w,
		XmNuserData,	&p,
		NULL);

	XtVaSetValues (w,
		XmNtranslations,	extra,
		NULL);

	XtVaSetValues (p->other_widget,
		XmNtranslations,	extra,
		NULL);
}

/*
 *  The next action procedure is typically associated with Button 1 down.
 *
 *  The action taken here depends on the value of edit_state. But we may:
 *
 *    Determine the polygon nearest the click -- within reason.
 *
 *    Begin the process of entering a 3-D point.
 *
 *    Begin the process of relocating the origin.
 *
 */

static void
PointBegin (w, event, params, num_params)
Widget	w;
XEvent	*event;
String	*params;
Cardinal *num_params;
{
	XButtonEvent	*ev = (XButtonEvent *) event;
	view_info_t	*p;
	Boolean		extend = False;

	if ((*num_params > 0) && (strcmp (*params, "extend") == 0))
		extend = True;

	XtVaGetValues (w,
		XmNuserData,	&p,
		NULL);

	switch (edit_state) {
	case STATE_POINT:
		BeginPick (w, p, ev->x, ev->y, extend);
		break;

	case STATE_POLYGON:
		BeginPolygonPoint(w, p, ev->x, ev->y);
		break;

	case STATE_MOVE_ORIGIN:
		break;
		
	case STATE_CIRCLE:
		BeginCirclePoint (w, p, ev->x, ev->y);
		break;

	case STATE_MARKER:
		BeginPolygonPoint(w, p, ev->x, ev->y);
		break;

	}
}

/*
 *    Move the selected polygon in point mode.
 *
 *    Slide the new point along the perpedicular-axis line.
 *
 *    Move the origin locator.
 */

static void
PointMotion (w, event, params, num_params)
Widget	w;
XEvent	*event;
String	*params;
Cardinal *num_params;
{
	XMotionEvent	*ev = (XMotionEvent *) event;
	view_info_t	*p;

	XtVaGetValues (w,
		XmNuserData,	&p,
		NULL);

	switch (edit_state) {
	case STATE_POINT:
		DragSelection (w, p, ev->x, ev->y);
		break;

	case STATE_POLYGON:
	case STATE_MARKER:
		DragPolygonPoint(w, p, ev->x, ev->y);
		break;
		
	case STATE_CIRCLE:
		DragCirclePoint (w, p, ev->x, ev->y);
		break;

	case STATE_MOVE_ORIGIN:
		break;
	}
}

/*
 *    Lock in a polygon selection.
 *
 *    The point has been positioned and is ready to be registered.
 *
 *    Relocate the origin.
 */

static void
PointEnd (w, event, params, num_params)
Widget	w;
XEvent	*event;
String	*params;
Cardinal *num_params;
{
	XButtonEvent	*ev = (XButtonEvent *) event;
	view_info_t	*p;

	XtVaGetValues (w,
		XmNuserData,	&p,
		NULL);

	switch (edit_state) {
	case STATE_POINT:
		CompleteDrag(w, p, ev->x, ev->y);
		break;

	case STATE_POLYGON:
		CompletePolygonPoint (w, p, ev->x, ev->y);
		break;
		
	case STATE_CIRCLE:
		CompleteCirclePoint (w, p, ev->x, ev->y);
		break;

	case STATE_MOVE_ORIGIN:
		break;

	case STATE_MARKER:
		CompleteMarker (w, p, ev->x, ev->y);
		break;
	}
}

/*
 *    Delete the currently selected object.
 */

static void
DeleteCurrent (w, event, params, num_params)
Widget	w;
XEvent	*event;
String	*params;
Cardinal *num_params;
{
	ClearSelection ();
}

static void
ClosePolygon (w, event, params, num_params)
Widget	w;
XEvent	*event;
String	*params;
Cardinal *num_params;
{
	if (cur_polygon != (polygon_t *) NULL)
		CompletePolygon (w, cur_polygon);
}
