#include "v_view.h"
#include "v_menu.h"
#include MUT_H
#include MPH_H
#include "mbk_extern.h"
#include "g_visu.h"
#include "g_extern.c"
#include "v_extern.h"

/*
put_it(drawable, xwin, ywin, dxwin, dywin)
Drawable drawable;
LAMBDA xwin, ywin, dxwin, dywin;
{
static int oldpattern;
register int i;

	switch (C_Config_List.C_VIEW) {
		case PATTERN:
			for (i = GC_BLKN; i < GC_INSTANCE; i++) 
				XSetFillStyle(display, V_gcCao[i], FillStippled);
			break;
		case FILL:
		case OUTLINE:
		default:
			for (i = GC_BLKN; i < GC_INSTANCE; i++) 
				XSetFillStyle(display, V_gcCao[i], FillSolid);
	}
	XFlush(display);
	put_it_all(drawable, xwin, ywin, dxwin, dywin);
	V_drawInsRef();
	V_drawAB();
}
*/

put_it(drawable, xwin, ywin, dxwin, dywin)
Drawable drawable;
LAMBDA xwin, ywin, dxwin, dywin;
{
	switch (C_Config_List.C_VIEW) {
		case PATTERN:
			put_it_pattern(drawable, xwin, ywin, dxwin, dywin);
			break;
		case OUTLINE:
			put_it_wire(drawable, xwin, ywin, dxwin, dywin);
			break;
		case FILL:
		default:
			put_it_fill(drawable, xwin, ywin, dxwin, dywin);
	}
	V_drawInsRef();
	V_drawAB();
}

put_it_pattern(drawable, xwin, ywin, dxwin, dywin)
Drawable drawable;
LAMBDA xwin, ywin, dxwin, dywin;
{
long x, y, dx, dy;
GC gc;
unsigned char flag, layer;
X_RECT *pt;

	for (layer = 0; layer < GC_DEFAULT; layer++) {
		if (((C_Config_List.C_VISIBLE >> layer)& 1)== 0)
			continue;
		pt = visu_db[layer];
		gc = V_gcCao[layer];
		if ((layer > GC_TALU1 && layer < GC_ALU2)|| layer == GC_CONT_VIA
				|| layer == GC_CONT_VIA2) {
			XSetForeground(display, V_gcCao[GC_FGND], V_colors[COLOR_BGND]);
			while (pt) {
			long xv, yv, dxv, dyv;
				xv = x = pt->X;
				dxv = dx = pt->DX;
				dyv = dy = pt->DY;
				yv = y = pt->Y;
				if (clip_to_window(&x, &y, &dx, &dy, xwin, ywin, dxwin, dywin)) {
					dx = (long)dxv * scale;
					dy = (long)dyv * scale;
					x = (long)((xv - xscreen)* scale);
					y = YMENU - 1 + (long)((yscreen - yv + dyscreen)* scale);
					if (dx || dy) {
						XSetFillStyle(display, gc, FillStippled);
						XFillRectangle(display, drawable, gc, (int)(x - (long)scale),
											(int)(y - (long)scale),
											(int)(dx + 1 + (((long)scale) << 1)), 
											(int)(dy + 1 + (((long)scale) << 1)));
						if (scale >= 1.0) 
							XFillRectangle(display, drawable, V_gcCao[GC_FGND],
												(int)(x + (long)scale),
												(int)(y + (long)scale),
												(int)(dx + 1 - (((long)scale) << 1)),
												(int)(dy + 1 - (((long)scale) << 1)));
						XSetFillStyle(display, gc, FillSolid);
						XDrawRectangle(display, drawable, gc, (int)x,
											(int)y, (int)dx, (int)dy);
						if (scale >= 1.0) 
							XDrawRectangle(display, drawable, V_gcCao[GC_FGND],
												(int)(x + (long)scale),
												(int)(y + (long)scale),
												(int)(dx - (((long)scale) << 1)),
												(int)(dy - (((long)scale) << 1)));
					}
				}
				pt = pt->NEXT;
			}
			XSetForeground(display, V_gcCao[GC_FGND], V_colors[COLOR_FGND]);
		} else if (layer == GC_INSTANCE) {
			XSetFillStyle(display, gc, FillSolid);
			while (pt) {
				x = pt->X;
				dx = pt->DX;
				dy = pt->DY;
				y = pt->Y;
				if (clip_to_window(&x, &y, &dx, &dy, xscreen, yscreen, dxscreen, dyscreen)) {
					dx = (long)dx * scale;
					dy = (long)dy * scale;
					x = (long)((x - xscreen)* scale);
					y = YMENU - 1 + (long)((yscreen - y + dyscreen)* scale);
					if (dx || dy) {
						XDrawRectangle(display, drawable, gc,
											(int)x, (int)y, (int)dx, (int)dy);
						/* string display */
						pt->TYPE |= 0x80;
					}
				} else
					pt->TYPE &= 0x7F;
				pt = pt->NEXT;
			}
		} else {
			while (pt) {
				x = pt->X;
				dx = pt->DX;
				dy = pt->DY;
				y = pt->Y;
				if (clip_to_window(&x, &y, &dx, &dy, xwin, ywin, dxwin, dywin)) {
					dx = (long)dx * scale;
					dy = (long)dy * scale;
					x = (long)((x - xscreen)* scale);
					y = YMENU - 1 + (long)((yscreen - y + dyscreen)* scale);
					if (dx || dy) {
						XSetFillStyle(display, gc, FillStippled);
						XFillRectangle(display, drawable, gc, (int)x,
												(int)y, (int)(dx + 1), (int)(dy + 1));
						XSetFillStyle(display, gc, FillSolid);
						XDrawRectangle(display, drawable, gc, (int)x,
											(int)y, (int)dx, (int)dy);
						/* string display */
						pt->TYPE |= 0x80;
					}
				} else
					pt->TYPE &= 0x7F;
				pt = pt->NEXT;
			}
		}
	}

	for (layer = 0; layer <= GC_DEFAULT; layer++) {
	int seen;
		if (((C_Config_List.C_VISIBLE >> layer)& 1)== 0)
			continue;
		if ((layer > GC_TALU1 && layer < GC_ALU2)|| layer == GC_CONT_VIA
				|| layer == GC_CONT_VIA2)
			continue;
		if (layer == GC_INSTANCE && scale < 1)
			continue;
		seen = layer == GC_INSTANCE ? 1 : 3;
		pt = visu_db[layer];
		while (pt) {
			if ((pt->TYPE & 0x80)< 0x80 || scale < seen) {
				pt = pt->NEXT;
				continue;
			}
			put_str(pt, drawable);
			pt = pt->NEXT;
		}
	}
}

put_it_wire(drawable, xwin, ywin, dxwin, dywin)
Drawable drawable;
LAMBDA xwin, ywin, dxwin, dywin;
{
long x, y, dx, dy;
GC gc;
unsigned char flag, layer;
X_RECT *pt;

	for (layer = 0; layer < GC_DEFAULT; layer++) {
		if (((C_Config_List.C_VISIBLE >> layer)& 1)== 0)
			continue;
		pt = visu_db[layer];
		gc = V_gcCao[layer];
		XSetFillStyle(display, gc, FillSolid);
		if ((layer > GC_TALU1 && layer < GC_ALU2)|| layer == GC_CONT_VIA
				|| layer == GC_CONT_VIA2) { 
			while (pt) {
			long xv, yv, dxv, dyv;
				xv = x = pt->X;
				dxv = dx = pt->DX;
				dyv = dy = pt->DY;
				yv = y = pt->Y;
				if (clip_to_window(&x, &y, &dx, &dy, xwin, ywin, dxwin, dywin)) {
					dx = (long)dxv * scale;
					dy = (long)dyv * scale;
					x = (long)((xv - xscreen)* scale);
					y = YMENU - 1 + (long)((yscreen - yv + dyscreen)* scale);
					if (dx || dy) {
						XDrawRectangle(display, drawable, gc,
											(int)(x - (long)scale),
											(int)(y - (long)scale),
											(int)(dx + (((long)scale) << 1)), 
											(int)(dy + (((long)scale) << 1)));
						XDrawLine(display, drawable, gc,
										(int)(x - (long)scale),
										(int)(y - (long)scale),
										(int)(x + dx + (long)scale),
										(int)(y + dy + (long)scale));
						XDrawLine(display, drawable, gc,
										(int)(x + dx + (long)scale),
										(int)(y - (long)scale),
										(int)(x - (long)scale),
										(int)(y + dy + (long)scale));
					}
				}
				pt = pt->NEXT;
			}
		} else if (layer == GC_INSTANCE) {
			while (pt) {
				x = pt->X;
				dx = pt->DX;
				dy = pt->DY;
				y = pt->Y;
				if (clip_to_window(&x, &y, &dx, &dy, xwin, ywin, dxwin, dywin)) {
					dx = (long)dx * scale;
					dy = (long)dy * scale;
					x = (long)((x - xscreen)* scale);
					y = YMENU - 1 + (long)((yscreen - y + dyscreen)* scale);
					if (dx || dy) {
						XDrawRectangle(display, drawable, gc,
											(int)x, (int)y, (int)dx, (int)dy);
						/* string display */
						pt->TYPE |= 0x80;
					}
				} else
					pt->TYPE &= 0x7F;
				pt = pt->NEXT;
			}
		} else {
			while (pt) {
				x = pt->X;
				dx = pt->DX;
				dy = pt->DY;
				y = pt->Y;
				if (clip_to_window(&x, &y, &dx, &dy, xwin, ywin, dxwin, dywin)) {
					dx = (long)dx *scale;
					dy = (long)dy *scale;
					x = (long)((x - xscreen)* scale);
					y = YMENU - 1 + (long)((yscreen - y + dyscreen)* scale);
					if (dx || dy) {
						XDrawRectangle(display, drawable, gc, (int)x,
											(int)y, (int)dx, (int)dy);
						/* string display */
						pt->TYPE |= 0x80;
					}
				} else
					pt->TYPE &= 0x7F;
				pt = pt->NEXT;
			}
		}
	}

	for (layer = 0; layer <= GC_DEFAULT; layer++) {
	int seen;
		if (((C_Config_List.C_VISIBLE >> layer)& 1)== 0)
			continue;
		if ((layer > GC_TALU1 && layer < GC_ALU2)|| layer == GC_CONT_VIA
				|| layer == GC_CONT_VIA2)
			continue;
		if (layer == GC_INSTANCE && scale < 1)
			continue;
		seen = layer == GC_INSTANCE ? 1 : 3;
		pt = visu_db[layer];
		while (pt) {
			if ((pt->TYPE & 0x80)< 0x80 || scale < seen) {
				pt = pt->NEXT;
				continue;
			}
			put_str(pt, drawable);
			pt = pt->NEXT;
		}
	}
}

put_it_fill(drawable, xwin, ywin, dxwin, dywin)
Drawable drawable;
LAMBDA xwin, ywin, dxwin, dywin;
{
long x, y, dx, dy;
GC gc;
unsigned char flag, layer;
X_RECT *pt;

	for (layer = 0; layer < GC_DEFAULT; layer++) {
		if (((C_Config_List.C_VISIBLE >> layer)& 1)== 0)
			continue;
		pt = visu_db[layer];
		gc = V_gcCao[layer];
		XSetFillStyle(display, gc, FillSolid);
		if ((layer > GC_TALU1 && layer < GC_ALU2)|| layer == GC_CONT_VIA
				|| layer == GC_CONT_VIA2) { 
			XSetForeground(display, V_gcCao[GC_FGND], V_colors[COLOR_BGND]);
			while (pt) {
			long xv, yv, dxv, dyv;
				xv = x = pt->X;
				dxv = dx = pt->DX;
				dyv = dy = pt->DY;
				yv = y = pt->Y;
				if (clip_to_window(&x, &y, &dx, &dy, xwin, ywin, dxwin, dywin)) {
					dx = (long)dxv * scale;
					dy = (long)dyv * scale;
					x = (long)((xv - xscreen)* scale);
					y = YMENU - 1 + (long)((yscreen - yv + dyscreen)* scale);
					if (dx || dy) {
						XFillRectangle(display, drawable, gc, (int)(x - (long)scale),
											(int)(y - (long)scale),
											(int)(dx + 1 + (((long)scale) << 1)), 
											(int)(dy + 1 + (((long)scale) << 1)));
						if (scale >= 1.0) 
							XFillRectangle(display, drawable, V_gcCao[GC_FGND],
												(int)(x + (long)scale),
												(int)(y + (long)scale),
												(int)(dx + 1 - (((long)scale) << 1)),
												(int)(dy + 1 - (((long)scale) << 1)));
					}
				}
				pt = pt->NEXT;
			}
			XSetForeground(display, V_gcCao[GC_FGND], V_colors[COLOR_FGND]);
		} else if (layer == GC_INSTANCE) {
			while (pt) {
				x = pt->X;
				dx = pt->DX;
				dy = pt->DY;
				y = pt->Y;
				if (clip_to_window(&x, &y, &dx, &dy, xwin, ywin, dxwin, dywin)) {
					dx = (long)dx *scale;
					dy = (long)dy *scale;
					x = (long)((x - xscreen)* scale);
					y = YMENU - 1 + (long)((yscreen - y + dyscreen)* scale);
					if (dx || dy) {
						XDrawRectangle(display, drawable, gc,
											(int)x, (int)y, (int)dx, (int)dy);
						/* string display */
						pt->TYPE |= 0x80;
					}
				} else
					pt->TYPE &= 0x7F;
				pt = pt->NEXT;
			}
		} else {
			while (pt) {
				x = pt->X;
				dx = pt->DX;
				dy = pt->DY;
				y = pt->Y;
				if (clip_to_window(&x, &y, &dx, &dy, xwin, ywin, dxwin, dywin)) {
					dx = (long)dx *scale;
					dy = (long)dy *scale;
					x = (long)((x - xscreen)* scale);
					y = YMENU - 1 + (long)((yscreen - y + dyscreen)* scale);
					if (dx || dy) {
						XFillRectangle(display, drawable, gc, (int)x,
												(int)y, (int)(dx + 1), (int)(dy + 1));
						/* string display */
						pt->TYPE |= 0x80;
					}
				} else
					pt->TYPE &= 0x7F;
				pt = pt->NEXT;
			}
		}
	}

	for (layer = 0; layer <= GC_DEFAULT; layer++) {
	int seen;
		if (((C_Config_List.C_VISIBLE >> layer)& 1)== 0)
			continue;
		if ((layer > GC_TALU1 && layer < GC_ALU2)|| layer == GC_CONT_VIA
				|| layer == GC_CONT_VIA2)
			continue;
		if (layer == GC_INSTANCE && scale < 1)
			continue;
		seen = layer == GC_INSTANCE ? 1 : 3;
		pt = visu_db[layer];
		while (pt) {
			if ((pt->TYPE & 0x80) < 0x80 || scale < seen) {
				pt = pt->NEXT;
				continue;
			}
			put_str(pt, drawable);
			pt = pt->NEXT;
		}
	}
}

void V_drawBox(rectBox, layer)
X_RECT *rectBox;
int layer;
{
GC gc;
int x, y, dx, dy;

	gc = V_gcCao[layer];
	dx = (int)(rectBox->DX * scale);
	dy = (int)(rectBox->DY * scale);
	x = (int)((rectBox->X - (int)xscreen)* scale),
	y = (int)(YMENU - 1 + (int)((yscreen - rectBox->Y + dyscreen)* scale));
	if (!dx || !dy)
		return;
	if (layer == GC_INSTANCE) {
		XDrawRectangle(display, V_window, gc, x, y, dx, dy);
		if (scale > 1)
			put_str(rectBox, V_window);
	} else if ((layer > GC_TALU1 && layer < GC_ALU2)|| layer == GC_CONT_VIA
            || layer == GC_CONT_VIA2) {
		if (C_Config_List.C_VIEW == FILL) {
			XFillRectangle(display, V_window, gc, (int)(x - (long)scale),
								(int)(y - (long)scale),
								(int)(dx + 1 + (((long)scale) << 1)), 
								(int)(dy + 1 + (((long)scale) << 1)));
			if (scale >= 1.0) 
				XFillRectangle(display, V_window, V_gcCao[GC_FGND],
									(int)(x + (long)scale),
									(int)(y + (long)scale),
									(int)(dx + 1 - (((long)scale) << 1)),
									(int)(dy + 1 - (((long)scale) << 1)));
/*
			XSetFillStyle(display, gc, FillSolid);
			XFillRectangle(display, V_window, gc, x, y,
								(int)(dx + 1), (int)(dy + 1));
*/
		} else if (C_Config_List.C_VIEW == OUTLINE) {
			XDrawRectangle(display, V_window, gc,
								(int)(x - (long)scale),
								(int)(y - (long)scale),
								(int)(dx + (((long)scale) << 1)), 
								(int)(dy + (((long)scale) << 1)));
			XDrawLine(display, V_window, gc,
							(int)(x - (long)scale),
							(int)(y - (long)scale),
							(int)(x + dx + (long)scale),
							(int)(y + dy + (long)scale));
			XDrawLine(display, V_window, gc,
							(int)(x + dx + (long)scale),
							(int)(y - (long)scale),
							(int)(x - (long)scale),
							(int)(y + dy + (long)scale));
/*
			XSetFillStyle(display, gc, FillSolid);
			XDrawRectangle(display, V_window, gc, x, y, dx, dy);
*/
		} else if (C_Config_List.C_VIEW == PATTERN) {
			XSetFillStyle(display, gc, FillStippled);
			XFillRectangle(display, V_window, gc, (int)(x - (long)scale),
								(int)(y - (long)scale),
								(int)(dx + 1 + (((long)scale) << 1)), 
								(int)(dy + 1 + (((long)scale) << 1)));
			if (scale >= 1.0) 
				XFillRectangle(display, V_window, V_gcCao[GC_FGND],
									(int)(x + (long)scale),
									(int)(y + (long)scale),
									(int)(dx + 1 - (((long)scale) << 1)),
									(int)(dy + 1 - (((long)scale) << 1)));
			XSetFillStyle(display, gc, FillSolid);
			XDrawRectangle(display, V_window, gc, (int)x,
								(int)y, (int)dx, (int)dy);
			if (scale >= 1.0) 
				XDrawRectangle(display, V_window, V_gcCao[GC_FGND],
									(int)(x + (long)scale),
									(int)(y + (long)scale),
									(int)(dx - (((long)scale) << 1)),
									(int)(dy - (((long)scale) << 1)));
/*
			XSetFillStyle(display, gc, FillStippled);
			XFillRectangle(display, V_window, gc,
								x, y, (int)(dx + 1), (int)(dy + 1));
			XSetFillStyle(display, gc, FillSolid);
			XDrawRectangle(display, V_window, gc, x, y, dx, dy);
*/
		}
/*
		XSetForeground(display, V_gcCao[GC_FGND], V_colors[COLOR_BGND]);
		XFillRectangle(display, V_window, V_gcCao[GC_FGND],
							(int)(x + (long)scale),
							(int)(y + (long)scale),
							(int)(dx + 1 - (long)scale - (long)scale),
							(int)(dy + 1 - (long)scale - (long)scale));
		XSetForeground(display, V_gcCao[GC_FGND], V_colors[COLOR_FGND]);
*/
	} else {
		if (C_Config_List.C_VIEW == FILL) {
			XSetFillStyle(display, gc, FillSolid);
			XFillRectangle(display, V_window, gc, x, y,
								(int)(dx + 1), (int)(dy + 1));
		} else if (C_Config_List.C_VIEW == PATTERN) {
			XSetFillStyle(display, gc, FillStippled);
			XFillRectangle(display, V_window, gc, x, y, (int)(dx + 1),
								(int)(dy + 1));
			XSetFillStyle(display, gc, FillSolid);
			XDrawRectangle(display, V_window, gc, x, y, dx, dy);
		} else if (C_Config_List.C_VIEW == OUTLINE) {
			XSetFillStyle(display, gc, FillSolid);
			XDrawRectangle(display, V_window, gc, x, y, dx, dy);
		}
		if (scale > 3)
			put_str(rectBox, V_window);
	}
	V_drawInsRef();
	XFlush(display);
}

put_it_all(drawable, xwin, ywin, dxwin, dywin)
Drawable drawable;
LAMBDA xwin, ywin, dxwin, dywin;
{
long x, y, dx, dy;
GC gc;
unsigned char flag, layer;
X_RECT *pt;

	XSetForeground(display, V_gcCao[GC_FGND], V_colors[COLOR_BGND]);
	for (layer = 0; layer < GC_DEFAULT; layer++) {
		if (((C_Config_List.C_VISIBLE >> layer)& 1)== 0)
			continue;
		pt = visu_db[layer];
		gc = V_gcCao[layer];
		if ((layer > GC_TALU1 && layer < GC_ALU2)|| layer == GC_CONT_VIA
				|| layer == GC_CONT_VIA2) {
			while (pt) {
				x = pt->X;
				dx = pt->DX;
				dy = pt->DY;
				y = pt->Y;
				if (clip_to_window(&x, &y, &dx, &dy, xwin, ywin, dxwin, dywin)) {
					dx = (long)dx * scale;
					dy = (long)dy * scale;
					x = (long)((x - xscreen)* scale);
					y = YMENU - 1 + (long)((yscreen - y + dyscreen)* scale);
					if (dx || dy) {
						XFillRectangle(display, drawable, gc, (int)(x - (long)scale),
											(int)(y - (long)scale),
											(int)(dx + 1 + (((long)scale) << 1)), 
											(int)(dy + 1 + (((long)scale) << 1)));
						if (scale >= 1.0) 
							XFillRectangle(display, drawable, V_gcCao[GC_FGND],
												(int)(x + (long)scale),
												(int)(y + (long)scale),
												(int)(dx + 1 - (((long)scale) << 1)),
												(int)(dy + 1 - (((long)scale) << 1)));
						XDrawRectangle(display, drawable, gc, (int)x,
											(int)y, (int)dx, (int)dy);
						if (scale >= 1.0) 
							XDrawRectangle(display, drawable, V_gcCao[GC_FGND],
												(int)(x + (long)scale),
												(int)(y + (long)scale),
												(int)(dx - (((long)scale) << 1)),
												(int)(dy - (((long)scale) << 1)));
					}
				}
				pt = pt->NEXT;
			}
		} else if (layer == GC_INSTANCE) {
			while (pt) {
				x = pt->X;
				dx = pt->DX;
				dy = pt->DY;
				y = pt->Y;
				if (clip_to_window(&x, &y, &dx, &dy, xwin, ywin, dxwin, dywin)) {
					dx = (long)dx * scale;
					dy = (long)dy * scale;
					x = (long)((x - xscreen)* scale);
					y = YMENU - 1 + (long)((yscreen - y + dyscreen)* scale);
					if (dx || dy) {
						XDrawRectangle(display, drawable, gc,
											(int)x, (int)y, (int)dx, (int)dy);
						/* string display */
						pt->TYPE |= 0x80;
					}
				} else
					pt->TYPE &= 0x7F;
				pt = pt->NEXT;
			}
		} else {
			while (pt) {
				x = pt->X;
				dx = pt->DX;
				dy = pt->DY;
				y = pt->Y;
				if (clip_to_window(&x, &y, &dx, &dy, xwin, ywin, dxwin, dywin)) {
					dx = (long)dx * scale;
					dy = (long)dy * scale;
					x = (long)((x - xscreen)* scale);
					y = YMENU - 1 + (long)((yscreen - y + dyscreen)* scale);
					if (dx || dy) {
						XFillRectangle(display, drawable, gc, (int)x,
												(int)y, (int)(dx + 1), (int)(dy + 1));
						XDrawRectangle(display, drawable, gc, (int)x,
											(int)y, (int)dx, (int)dy);
						/* string display */
						pt->TYPE |= 0x80;
					}
				} else
					pt->TYPE &= 0x7F;
				pt = pt->NEXT;
			}
		}
	}
	XSetForeground(display, V_gcCao[GC_FGND], V_colors[COLOR_FGND]);

	for (layer = 0; layer <= GC_DEFAULT; layer++) {
	int seen;
		if (((C_Config_List.C_VISIBLE >> layer)& 1)== 0)
			continue;
		if ((layer > GC_TALU1 && layer < GC_ALU2)|| layer == GC_CONT_VIA
				|| layer == GC_CONT_VIA2)
			continue;
		if (layer == GC_INSTANCE && scale < 1)
			continue;
		seen = layer == GC_INSTANCE ? 1 : 3;
		pt = visu_db[layer];
		while (pt) {
			if ((pt->TYPE & 0x80)< 0x80 || scale < seen) {
				pt = pt->NEXT;
				continue;
			}
			put_str(pt, drawable);
			pt = pt->NEXT;
		}
	}
}
