/****************************************************************************/
/*                                                                          */
/*                      Chaine de CAO & VLSI   Alliance                     */
/*                                                                          */
/*    Produit : ring router                                                 */
/*    Fichier : bigvia.c                                                    */
/*                                                                          */
/*    (c) copyright 1992 Laboratoire MASI equipe CAO & VLSI                 */
/*    Tous droits reserves                                                  */
/*    Support : e-mail cao-vlsi@masi.ibp.fr                                 */
/*                                                                          */
/*    Ecrit   par : Fred                                le : 01/08/92       */
/*    Modifie par : Franck Wajsburt                     le :   /  /         */
/*                                                                          */
/****************************************************************************/

#include <stdio.h>
#include "includes.h"
#include "struct.h"

/* #include MUT_H
#include MLO_H
#include MPH_H */

/*#define BV_VIA_VIA 4  must be even, whatever! 
#define BV_VIASIZE 3 /* design rule for equipotential vias  */
/*******************************************************************************
* this creates a mega-via, the best way we can do it, I hope                   *
* the envelop of the bigvia is calculated, and then its center is placed       *
* as close as possible of the x, y coordinates given as arguments.             *
*******************************************************************************/
void
bigvia_ring(f, x, y, dx, dy)
phfig_list *f;
long	x, y, dx, dy;
{
	int	i, j;
	long	stepx, stepy, xv, yv, dxv, dyv;

	if (dx < 0 || dy < 0) {
		fflush(stdout);
		fprintf(stderr, "*** mbk error ***\n bigvia impossible :");
		fprintf(stderr, " negative values dx = %d, dy = %d\n", dx, dy);
		fprintf(stderr, "in figure '%s' at (%d, %d)\n", f->NAME, x, y);
		EXIT(1);
	}
	/* euclidian division :
	   dividing and then multipliing doesen't give the initial value.
		we calculate the center of the bunch of vias and adjust it to the given
		x, y coordinates. */
	stepx = (dx - BV_VIASIZE * SCALE_X) / (BV_VIA_VIA * SCALE_X);
	stepy = (dy - BV_VIASIZE * SCALE_X) / (BV_VIA_VIA * SCALE_X);
	dxv = stepx * BV_VIA_VIA * SCALE_X;
	dyv = stepy * BV_VIA_VIA * SCALE_X;
	xv = x - dxv / 2;
	yv = y - dyv / 2;
	/* draw the vias */
	for (i = 0; i <= stepx; i++)
		for (j = 0; j <= stepy; j++) {
			bigvias++;

			if (mode_debug) {

				/* new rules for disk space :
	   	   just a ring of via for big pates. */

				if (i == 0 || i == stepx || j == 0 || j == stepy) {
					addphvia(f, CONT_VIA, xv + i * BV_VIA_VIA * SCALE_X, yv + j * BV_VIA_VIA * SCALE_X);
					ringvias++;
				}
			} /* fin du if mode_debug */ else {   /* pave complet de vias ! */
				if (i == 0 || i == stepx || j == 0 || j == stepy) 
					ringvias++;

				addphvia(f, CONT_VIA, xv + i * BV_VIA_VIA * SCALE_X, yv + j * BV_VIA_VIA * SCALE_X);
			}
		}
	/* put segments around the vias :
	   this warranties that no notches may appear on the borders. */
	if (stepx)
		addphseg(f, ALU1, BV_VIASIZE * SCALE_X, xv, yv, xv + stepx * BV_VIA_VIA * SCALE_X, yv, NULL);
	if (stepx || stepy)
		addphseg(f, ALU1, BV_VIASIZE * SCALE_X, xv + stepx * BV_VIA_VIA * SCALE_X, yv, xv + stepx * BV_VIA_VIA *
		    SCALE_X, yv + stepy * BV_VIA_VIA * SCALE_X, NULL);
	if (stepx || stepy)
		addphseg(f, ALU1, BV_VIASIZE * SCALE_X, xv + stepx * BV_VIA_VIA * SCALE_X, yv + stepy * BV_VIA_VIA * SCALE_X,
		     xv, yv + stepy * BV_VIA_VIA * SCALE_X, NULL);
	if (stepy)
		addphseg(f, ALU1, BV_VIASIZE * SCALE_X, xv, yv, xv, yv + stepy * BV_VIA_VIA * SCALE_X, NULL);
	if (stepx)
		addphseg(f, ALU2, BV_VIASIZE * SCALE_X, xv, yv, xv + stepx * BV_VIA_VIA * SCALE_X, yv, NULL);
	if (stepx || stepy)
		addphseg(f, ALU2, BV_VIASIZE * SCALE_X, xv + stepx * BV_VIA_VIA * SCALE_X, yv, xv + stepx * BV_VIA_VIA *
		    SCALE_X, yv + stepy * BV_VIA_VIA * SCALE_X, NULL);
	if (stepx || stepy)
		addphseg(f, ALU2, BV_VIASIZE * SCALE_X, xv + stepx * BV_VIA_VIA * SCALE_X, yv + stepy * BV_VIA_VIA * SCALE_X,
		     					xv, yv + stepy * BV_VIA_VIA * SCALE_X, NULL);
	if (stepy)
		addphseg(f, ALU2, BV_VIASIZE * SCALE_X, xv, yv, xv, yv + stepy * BV_VIA_VIA * SCALE_X, NULL);

	/* fill the leftover space :
	   we use computed via coordinates, and substract one in order not to
	   take care of even or odd values. */
	if (dxv && dyv)
		addphseg(f, ALU2, dyv - 1 * SCALE_X, xv, yv + dyv / 2, xv + dxv, yv + dyv / 2, NULL);
	if (dxv && dyv)
		addphseg(f, ALU1, dyv - 1 * SCALE_X, xv, yv + dyv / 2, xv + dxv, yv + dyv / 2, NULL);
}

