#ifndef lint
static char *SccsId = "@(#)outp_ldm.c 4.3 (TU-Delft) 01/20/92";
#endif
/*
 *      Copyright 1990 by Delft University of Technology (DUT),
 *                      Delft, The Netherlands.
 * 
 *                        All Rights Reserved
 * 
 * Permission to use, copy, modify, and distribute this software and
 * its  documentation  without  fee,  is  hereby  granted  for  non-
 * commercial purposes  only,  provided  that  the  above  copyright
 * notice  appear  in all copies and that both that copyright notice
 * and this permission notice appear  in  supporting  documentation,
 * and  that the name of DUT not be used in advertising or publicity
 * pertaining to distribution  of  the  software  without  specific,
 * written prior permission.
 * 
 * THE DUT DISCLAIMS ALL WARRANTIES WITH REGARD  TO  THIS  SOFTWARE,
 * INCLUDING  ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
 * IN NO EVENT SHALL THE DUT BE LIABLE FOR ANY SPECIAL, INDIRECT  OR
 * CONSEQUENTIAL  DAMAGES  OR  ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION  OF  CONTRACT,
 * NEGLIGENCE  OR  OTHER  TORTIOUS  ACTION,  ARISING  OUT  OF  OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 * 
 * Author(s):
 *           S. de Graaf
 *           T.G.R. van Leuken
 *           P. Kist
 * 
 * 
 * Contact address:
 * 
 * 
 * Dimes Design and Test Centre     phone: + 31 (15) 78 1459
 * Delft University of Technology   fax:   + 31 (15) 62 3271
 * P.O. Box 5053 		    email: nelsis@dutentb.tudelft.nl
 * Feldmannweg 17, 2600 GB Delft    The Netherlands
 */
#include "incl.h"
#include "extern.h"

outp_ldm (cell)
char *cell;
{
    PF "ms %s\n", cell);
    ldm_term_copy ();
    ldm_box_copy ();
    ldm_nor_copy (cell);
    ldm_mc_copy ();
    PF "me\n");
}

static
ldm_term_copy ()
{
    register DM_STREAM *stream;

    stream = dmOpenStream (ckey, "term", "r");
    while (dmGetDesignData (stream, GEO_TERM) > 0) {
	PF "term %s %d %d %d %d %s", ldmlay[gterm.layer_no],
	    gterm.xl, gterm.xr, gterm.yb, gterm.yt, gterm.term_name);
	if (gterm.nx) PF " cx %d %d", gterm.dx, gterm.nx);
	if (gterm.ny) PF " cy %d %d", gterm.dy, gterm.ny);
	PF "\n");
    }
    dmCloseStream (stream, COMPLETE);
}

static
ldm_box_copy ()
{
    register DM_STREAM *stream;

    stream = dmOpenStream (ckey, "box", "r");
    while (dmGetDesignData (stream, GEO_BOX) > 0) {
	PF "box %s %d %d %d %d", ldmlay[gbox.layer_no],
	    gbox.xl, gbox.xr, gbox.yb, gbox.yt);
	if (gbox.nx) PF " cx %d %d", gbox.dx, gbox.nx);
	if (gbox.ny) PF " cy %d %d", gbox.dy, gbox.ny);
	PF "\n");
    }
    dmCloseStream (stream, COMPLETE);
}

static
ldm_nor_copy (cell)
char *cell;
{
    double  xs, ys, r1, r2, step;
    int     n_edges, no_xy;
    char   *layer;
    register DM_STREAM *stream;

    stream = dmOpenStream (ckey, "nor", "r");

    while (dmGetDesignData (stream, GEO_NOR_INI) > 0) {
	layer = ldmlay[gnor_ini.layer_no];
	no_xy = gnor_ini.no_xy;

	if (dmGetDesignData (stream, GEO_NOR_XY) <= 0)
	    error (2, cell);
	xs = gnor_xy.x;
	ys = gnor_xy.y;

	switch (gnor_ini.elmt) {
	    case WIRE_NOR: 
		if (no_xy < 3) error (9, cell);
		PF "swire %s w %s", layer, dtoa (xs));
		while (--no_xy > 0) {
		    if (dmGetDesignData (stream, GEO_NOR_XY) <= 0)
			error (2, cell);
		    PF " %s %s", dtoa (gnor_xy.x), dtoa (gnor_xy.y));
		}
		break;
	    case SBOX_NOR: 
		if (no_xy != 2) error (9, cell);
		if (dmGetDesignData (stream, GEO_NOR_XY) <= 0)
		    error (2, cell);
		PF "sbox %s %s %s %s %s", layer,
		    dtoa (xs), dtoa (ys), dtoa (gnor_xy.x), dtoa (gnor_xy.y));
		break;
	    case RECT_NOR: 
		if (no_xy != 4) error (9, cell);
	    case POLY_NOR: 
		if (no_xy < 3) error (9, cell);
		PF "poly %s %s %s", layer, dtoa (xs), dtoa (ys));
		while (--no_xy > 0) {
		    if (dmGetDesignData (stream, GEO_NOR_XY) <= 0)
			error (2, cell);
		    PF " %s %s", dtoa (gnor_xy.x), dtoa (gnor_xy.y));
		}
		PF " %s %s", dtoa (xs), dtoa (ys));
		break;
	    case CIRCLE_NOR: 
		if (no_xy < 2 || no_xy > 4) error (9, cell);
		if (dmGetDesignData (stream, GEO_NOR_XY) <= 0)
		    error (2, cell);
		r1 = gnor_xy.x;
		r2 = gnor_xy.y;
		step = 0;
		if (no_xy > 2) {
		    if (dmGetDesignData (stream, GEO_NOR_XY) <= 0)
			error (2, cell);
		    step = gnor_xy.x;
		}
		if (no_xy > 3 || r2 > 0.0) {
		    PF "cpeel %s %s %s %s %s",
			layer, dtoa (xs), dtoa (ys), dtoa (r1), dtoa (r2));
		    if (no_xy > 3) {
			if (dmGetDesignData (stream, GEO_NOR_XY) <= 0)
			    error (2, cell);
			PF " %s %s", dtoa (gnor_xy.x), dtoa (gnor_xy.y));
		    }
		    else {
			PF " 0 360");
		    }
		}
		else {
		    PF "circle %s %s %s %s",
			layer, dtoa (xs), dtoa (ys), dtoa (r1));
		}
		n_edges = 32000;
		if (step > 0) {
		    if (step >= 8) {
			n_edges = step;
			if (n_edges % 8) n_edges = 360.0 / step + 0.5;
		    }
		    else n_edges = 360.0 / step + 0.5;
		    n_edges /= 8;
		    n_edges *= 8;
		    if (n_edges < 8) n_edges = 8;
		    if (n_edges > 32000) n_edges = 32000;
		}
		if (n_edges != 32) PF " %d", n_edges);
		break;
	    default: 
		error (6, cell);
	}

	if (gnor_ini.nx)
	    PF " cx %s %d", dtoa (gnor_ini.dx), gnor_ini.nx);
	if (gnor_ini.ny)
	    PF " cy %s %d", dtoa (gnor_ini.dy), gnor_ini.ny);
	PF "\n");
    }
    dmCloseStream (stream, COMPLETE);
}

static
ldm_mc_copy ()
{
    int     tx, ty, pos, sfx, sfy;
    register DM_STREAM *stream;
    struct na_elmt *q;

    stream = dmOpenStream (ckey, "mc", "r");

    while (dmGetDesignData (stream, GEO_MC) > 0) {

	if (gmc.imported) {
	    if (!(q = findold (gmc.cell_name, 0))) error (1, gmc.cell_name);
	    if (iclist)
		inst_alias (iclist, q -> name);
	    else
		iclist = inst_ic_elmt (q -> name);
	}

	if (strcmp (gmc.inst_name, ".") == 0)
	    PF "mc %s", gmc.cell_name);
	else
	    PF "mc <%s> %s", gmc.inst_name, gmc.cell_name);

	if (gmc.mtx[0] == 0) {
	    if (gmc.mtx[3] > 0) {
		if (gmc.mtx[1] > 0) {/* MX+R90 */
		    pos = 5;
		    sfx = gmc.mtx[3];
		    sfy = gmc.mtx[1];
		}
		else {		/* R90 */
		    pos = 1;
		    sfx = gmc.mtx[3];
		    sfy = -gmc.mtx[1];
		}
	    }
	    else {
		if (gmc.mtx[1] > 0) {/* R270 */
		    pos = 3;
		    sfx = -gmc.mtx[3];
		    sfy = gmc.mtx[1];
		}
		else {		/* MY+R90 */
		    pos = 7;
		    sfx = -gmc.mtx[3];
		    sfy = -gmc.mtx[1];
		}
	    }
	}
	else {
	    if (gmc.mtx[0] > 0) {
		if (gmc.mtx[4] > 0) {/* R0 */
		    pos = 0;
		    sfx = gmc.mtx[0];
		    sfy = gmc.mtx[4];
		}
		else {		/* MX+R0 */
		    pos = 4;
		    sfx = gmc.mtx[0];
		    sfy = -gmc.mtx[4];
		}
	    }
	    else {
		if (gmc.mtx[4] > 0) {/* MY */
		    pos = 6;
		    sfx = -gmc.mtx[0];
		    sfy = gmc.mtx[4];
		}
		else {		/* R180 */
		    pos = 2;
		    sfx = -gmc.mtx[0];
		    sfy = -gmc.mtx[4];
		}
	    }
	}

	if (sfx > 1) PF " sfx %d", sfx);
	if (sfy > 1) PF " sfy %d", sfy);

	switch (pos) {
	    case 1: PF " r3"); break;
	    case 2: PF " r6"); break;
	    case 3: PF " r9"); break;
	    case 4: PF " mx"); break;
	    case 5: PF " mx r3"); break;
	    case 6: PF " my"); break;
	    case 7: PF " my r3"); break;
	}

	if (o_mode) {
	    tx = gmc.mtx[2];
	    ty = gmc.mtx[5];
	}
	else {
	    tx = gmc.bxl;
	    ty = gmc.byb;
	    if (gmc.dx < 0) gmc.dx = -gmc.dx;
	    if (gmc.dy < 0) gmc.dy = -gmc.dy;
	}
	if (tx || ty) PF " %d %d", tx, ty);
	if (gmc.nx) PF " cx %d %d", gmc.dx, gmc.nx);
	if (gmc.ny) PF " cy %d %d", gmc.dy, gmc.ny);
	PF "\n");
    }
    dmCloseStream (stream, COMPLETE);
}
