/*
 *  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/Xm.h>
#include <stdio.h>

#include "../util/memory.h"
#include "shared.h"
#include "gutil.h"
#include "gutil1.h"

#define edit_IMPORT
#include "edit.h"

void
Mirror (int op)
{

	int             i, j;
	polygon_t       *new, *poly;
	view_info_t             *p;
	XtVaGetValues (twindow,
		XmNuserData,    &p,
		NULL);

	for (i = sel_polygon; i >= 0; i = polygon_list[i].next) {
		new = BeginPolygon ();
		poly = &polygon_list[i];
		new->num_points = poly->num_points;
		new->point =
			(point_t *) memory_allocate(new->num_points * sizeof (point_t), NULL);

		for (j=0; j < poly->num_points; ++j) {

			switch (op) {

			case MENU_MIRROR_XZ:
				new->point[j] =
					poly->point[poly->num_points - j - 1];
				new->point[j].point.y =
					- new->point[j].point.y;
				PointToXYZ (p, &new->point[j]);
				break;

			case MENU_MIRROR_XY:
				new->point[j] =
					poly->point[poly->num_points - j - 1];
				new->point[j].point.z =
					- new->point[j].point.z;
				PointToXYZ (p, &new->point[j]);
				break;

			case MENU_MIRROR_YZ:
				new->point[j] =
					poly->point[poly->num_points - j - 1];
				new->point[j].point.x =
					- new->point[j].point.x;
				PointToXYZ (p, &new->point[j]);
				break;

			}
		}

		ComputePlaneEquation (new);
		new->next = sel_polygon;
		sel_polygon = new->id;
		cur_polygon = (polygon_t *) NULL;
	}

	DrawWidget (twindow, False);
	DrawWidget (p->other_widget, False);
}

void
PointToXYZ (view_info_t *p, point_t *point)
{

/*
 *  warning, signs assume the original layout only
 */

	switch (p->layout) {

	case VL_NXZ:
		point->x = (int) (- point->point.x / pixel_scale) +
			p->origin_x;
		point->y = (int) (- point->point.y / pixel_scale) +
			p->other_view->origin_y;
		point->z = (int) (point->point.z / pixel_scale) +
			p->origin_y;
		break;

	case VL_NXNY:
		point->x = (int) (- point->point.x / pixel_scale) +
			p->origin_x;
		point->y = (int) (- point->point.y / pixel_scale) +
			p->origin_y;
		point->z = (int) (point->point.z / pixel_scale) +
			p->other_view->origin_y;
		break;

	case VL_NYZ:
		point->x = (int) (point->point.x / pixel_scale) +
			p->other_view->origin_y;
		point->y = (int) (- point->point.y / pixel_scale) +
			p->origin_x;
		point->z = (int) (point->point.z / pixel_scale) +
			p->origin_y;
		break;

	case VL_NYX:
		point->x = (int) (point->point.x / pixel_scale) +
			p->origin_y;
		point->y = (int) (- point->point.y / pixel_scale) +
			p->origin_x;
		point->z = (int) (point->point.z / pixel_scale) +
			p->other_view->origin_y;
		break;
	}
}

void
ClearSelection()
{

	int i, j;
	view_info_t     *p;

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

	for (i=sel_polygon; i>= 0; i = j) {
		j = polygon_list[i].next;
		FreePolygon (&polygon_list[i]);
	}

	sel_polygon = -1;

	DrawWidget (twindow, False);
	DrawWidget (p->other_widget, False);
}

void
CopySelection()
{
	int i, j, nn = 0;
	view_info_t     *p;
	polygon_t *new,  *poly;

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

	ClearClipboard();

	for (i = sel_polygon; i >= 0; i = polygon_list[i].next) {
		new = BeginPolygon ();
		poly = &polygon_list[i];
		new->num_points = poly->num_points;
		new->point =
			(point_t *) memory_allocate(new->num_points * sizeof (point_t), NULL);

		for (j=0; j < poly->num_points; ++j) {
			new->point[j] = poly->point[j];
			PointToXYZ (p, &new->point[j]);
		}

		ComputePlaneEquation (new);
		new->next = clipboard_polygon;
		clipboard_polygon = new->id;
		cur_polygon = (polygon_t *) NULL;
		++nn;
	}
}

void
ClearClipboard()
{
	int i, j;
	view_info_t     *p;

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

	for (i=clipboard_polygon; i>= 0; i = j) {
		j = polygon_list[i].next;
		FreePolygon (&polygon_list[i]);
	}

	clipboard_polygon = -1;
}

void
PasteSelection()
{
	int i, j, nn = 0;
	view_info_t     *p;
	polygon_t *new,  *poly;

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

	ClearSelection();

	for (i = clipboard_polygon; i >= 0; i = polygon_list[i].next) {
		new = BeginPolygon ();
		poly = &polygon_list[i];
		new->num_points = poly->num_points;
		new->point =
			(point_t *) memory_allocate(new->num_points * sizeof (point_t), NULL);

		for (j=0; j < poly->num_points; ++j) {
			new->point[j] = poly->point[j];
			/*new->point[j].y += 1.0;
			  new->point[j].z += 1.0;*/
			PointToXYZ (p, &new->point[j]);
		}

		ComputePlaneEquation (new);
		new->next = sel_polygon;
		sel_polygon = new->id;
		cur_polygon = (polygon_t *) NULL;
		++nn;
	}

	DrawWidget (twindow, False);
	DrawWidget (p->other_widget, False);
}

void
RotateXSelection()
{
	int i, j;
	view_info_t     *p;
	double tmp;
	polygon_t *poly;

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

	for (i = sel_polygon; i >= 0; i = polygon_list[i].next) {
		poly = &polygon_list[i];

		for (j=0; j < poly->num_points; ++j) {
			tmp = poly->point[j].point.z;
			poly->point[j].point.z = poly->point[j].point.y;
		    poly->point[j].point.y = tmp;
			PointToXYZ (p, &poly->point[j]);
		}

		ComputePlaneEquation (poly);

	}

	DrawWidget (twindow, False);
	DrawWidget (p->other_widget, False);
}

void
PrintList(int start)
{
	int i;

	if (start == -1) {
		printf ("NULL");
	}
	else {
		for (i = start; i >= 0; i = polygon_list[i].next) {
			printf ("%d ", i);
		}
	}
	printf ("\n");
}

void
PrintDiagnostics()
{
	printf ("sel_polygon list : ");
	PrintList (sel_polygon);
	printf ("unsel_polygon list : ");
	PrintList (unsel_polygon);
	printf ("clipboard_polygon list : ");
	PrintList (clipboard_polygon);
}
	


