/*
 *                            COPYRIGHT
 *
 *  PCB, interactive printed circuit board design
 *  Copyright (C) 1994,1995,1996 Thomas Nau
 *
 *  This module, report.c, was written and is Copyright (C) 1997 harry eaton
 *
 *  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.
 *
 *  Contact addresses for paper mail and Email:
 *  Thomas Nau, Schlehenweg 15, 88471 Baustetten, Germany
 *  Thomas.Nau@rz.uni-ulm.de
 *
 */

static  char    *rcsid = "$Id: report.c,v 144.1 1997/07/30 07:08:17 nau Exp $";

#include "report.h"
#include "data.h"
#include "dialog.h"
#include "drill.h"
#include "error.h"
#include "search.h"
#include "misc.h"
#include "mymem.h"


#include <X11/Shell.h>
#include <X11/Xaw/AsciiText.h>
#include <X11/Xaw/Command.h>
#include <X11/Xaw/Dialog.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/Label.h>
#include <X11/Xaw/Toggle.h>


static	int	ReturnCode;		/* filled in by dialog */

/*
 * some local prototypes
 */
static	void	CB_OK(Widget, XtPointer, XtPointer);

/* ---------------------------------------------------------------------------
 * callback for standard dialog
 * just copies the button-code which is passed as ClientData to a
 * public identifier
 */
static void CB_OK(Widget W, XtPointer ClientData, XtPointer CallData)
{
        ReturnCode = (int) ClientData;
}

void ReportDrills(void)
{
	DrillInfoTypePtr	AllDrills;
	Cardinal		n;
	char			*stringlist, *thestring;
        Widget	popup;
        static  DialogButtonType        button =
                { "defaultButton", "  OK  ", CB_OK, (XtPointer) OK_BUTTON, NULL };

	AllDrills = GetDrillInfo(PCB->Data);
	stringlist = malloc(512L + AllDrills->DrillN * 64L);
	sprintf(stringlist,"There are %d different drill sizes used in this layout\n\n"
			   "Drill Diam. (mils)      # of Pins     # of Vias    # of Elements\n",
			   AllDrills->DrillN);
	thestring = stringlist;
	while (*thestring != '\0')
		thestring++;
	for (n = 0; n < AllDrills->DrillN; n++)
	{
		sprintf(thestring, "  %5d                 %5d          %5d            %2d\n",
			AllDrills->Drill[n].DrillSize, AllDrills->Drill[n].PinCount,
			AllDrills->Drill[n].ViaCount, AllDrills->Drill[n].ElementN);
		while (*thestring != '\0')
			thestring++;
	}
	FreeDrillInfo(AllDrills);
                /* create dialog box */
    popup = CreateDialogBox(stringlist, &button, 1, "Drill Report");
    StartDialog(popup);

                /* wait for dialog to complete */
    DialogEventLoop(&ReturnCode);
    EndDialog(popup);
    SaveFree(stringlist);
}

			
	

void ReportDialog(void)
{
        void    *ptr1, *ptr2, *ptr3;
	int	type;
	char	report[2048];
        Widget	popup;
        static  DialogButtonType        button =
                { "defaultButton", "  OK  ", CB_OK, (XtPointer) OK_BUTTON, NULL };

        switch(type = SearchObjectByPosition(REPORT_TYPES, &ptr1, &ptr2, &ptr3,
                Crosshair.X, Crosshair.Y))
	{
		case VIA_TYPE:
		{
			PinTypePtr via = (PinTypePtr) ptr2;

			sprintf(&report[0],"VIA ID# %d   Flags:0x%08x\n"
				"(X,Y) = (%d, %d)\n"
				"Copper width = %d mils  Drill width = %d mils\n"
				"Name = \"%s\"", via->ID, via->Flags, via->X,
				via->Y, via->Thickness, via->DrillingHole,
				via->Name);
			break;
		}
		case PIN_TYPE:
		{
			PinTypePtr Pin = (PinTypePtr) ptr2;
			ElementTypePtr element = (ElementTypePtr) ptr1;
			int found = 0;

			PIN_LOOP(element, {
				found++;
				if (pin == Pin) break;
			});
			sprintf(&report[0],"PIN ID# %d   Flags:0x%08x\n"
				"(X,Y) = (%d, %d)\n"
				"Copper width = %d mils  Drill width = %d mils\n"
				"Name = \"%s\"\n"
				"It is owned by element %s\n"
				"As pin number %d\n", Pin->ID, Pin->Flags, Pin->X,
				Pin->Y, Pin->Thickness, Pin->DrillingHole,
				Pin->Name, element->Name[1].TextString,
				found);
			break;
		}
		case LINE_TYPE:
		{
			LineTypePtr line = (LineTypePtr) ptr2;
			sprintf(&report[0],"LINE ID# %d   Flags:0x%08x\n"
				"FirstPoint(X,Y) = (%d, %d)  ID = %d\n"
				"SecondPoint(X,Y) = (%d, %d)  ID = %d\n"
				"Width = %d mils. It is on layer %d\n"
				"%s\n", line->ID, line->Flags,
				line->Point1.X, line->Point1.Y,
				line->Point1.ID, line->Point2.X, line->Point2.Y,
				line->Point2.ID, line->Thickness,
				GetLayerNumber(PCB->Data, (LayerTypePtr) ptr1),
				TEST_FLAG(RATFLAG, line) ? "and it's a rats-nest line." : " ");
			break;
		}
		case POLYGON_TYPE:
		{
			PolygonTypePtr Polygon = (PolygonTypePtr) ptr2;

			sprintf(&report[0], "POLYGON ID# %d   Flags:0x%08x\n"
				"It has %d points and could store %d more\n"
				"without using more memory.\n"
				"It resides on layer %d\n", Polygon->ID,
				Polygon->Flags, Polygon->PointN, Polygon->PointMax
				- Polygon->PointN,
				GetLayerNumber(PCB->Data, (LayerTypePtr) ptr1));
			break;
		}
		case PAD_TYPE:
		{
			PadTypePtr Pad = (PadTypePtr) ptr2;
			ElementTypePtr element = (ElementTypePtr) ptr1;
			int found = 0;

			PAD_LOOP(element, {
				found++;
				if (pad == Pad) break;
			});
			sprintf(&report[0],"PAD ID# %d   Flags:0x%08x\n"
				"FirstPoint(X,Y) = (%d, %d)  ID = %d\n"
				"SecondPoint(X,Y) = (%d, %d)  ID = %d\n"
				"Width = %d It is owned by SMD element %s\n"
				"As pin number %d and is on the %s\n"
				"side of the board.\n", Pad->ID,
				Pad->Flags, Pad->Point1.X,
				Pad->Point1.Y, Pad->Point1.ID, Pad->Point2.X, Pad->Point2.Y,
				Pad->Point2.ID, Pad->Thickness,
				element->Name[1].TextString, found,
				TEST_FLAG(ONSOLDERFLAG, Pad) ? "solder (bottom)" : "component");
			break;
		}
		case ELEMENT_TYPE:
		{
			ElementTypePtr element = (ElementTypePtr) ptr2;
			sprintf(&report[0],"ELEMENT ID# %d   Flags:0x%08x\n"
				"Descriptive Name \"%s\"\n"
				"Name on board \"%s\"\n"
				"Part number name \"%s\"\n"
				"Mark located at point (X,Y) = (%d,%d)\n"
				"It is on the %s side of the board.\n",
				element->ID, element->Flags, element->Name[0].TextString,
				element->Name[1].TextString, element->Name[2].TextString,
				element->MarkX, element->MarkY, TEST_FLAG(ONSOLDERFLAG, element)
				? "solder (bottom)" : "component");
			break;
		}
		case TEXT_TYPE:
		case ELEMENTNAME_TYPE:
		{
			TextTypePtr text = (TextTypePtr) ptr2;
			sprintf(&report[0], "TEXT ID# %d   Flags:0x%08x\n"
				"Located at (X,Y) = (%d,%d)\n"
				"Characters are %d mils tall\n"
				"Value is \"%s\"\n"
				"Direction is %d\n"
				"It %s\n", text->ID, text->Flags,
				text->X, text->Y, text->Scale,
				text->TextString, text->Direction,
				(type == TEXT_TYPE) ? "is free-standing text." :
				"is an element name.");
			break;
		}
		case LINEPOINT_TYPE:
		case POLYGONPOINT_TYPE:
		{
			PointTypePtr point = (PointTypePtr) ptr2;
			sprintf(&report[0], "POINT ID# %d Points don't have flags."
				"Located at (X,Y) = (%d,%d)\n"
				"It belongs to a %s on layer %d\n",point->ID,
				point->X, point->Y, 
				(type == LINEPOINT_TYPE) ? "line" : "polygon",
				GetLayerNumber(PCB->Data, (LayerTypePtr) ptr1));
				
		}
		case NO_TYPE:
			report[0] = '\0';
			break;

		default:
			sprintf(&report[0], "Unknown\n");
			break;
	}

	if (report[0] == '\0')
	{
		Message("Nothing found to report on\n");
		return;
	}
	HideCrosshair(False);
                /* create dialog box */
        popup = CreateDialogBox(&report[0], &button, 1, "Report");
        StartDialog(popup);

                /* wait for dialog to complete */
        DialogEventLoop(&ReturnCode);
	RestoreCrosshair(False);
        EndDialog(popup);
}

