/* -*- tab-width: 4 -*-
 *
 * Electric(tm) VLSI Design System
 *
 * File: SimpleWirer.java
 *
 * Copyright (c) 2003, Static Free Software. All rights reserved.
 *
 * Electric(tm) 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 3 of the License, or
 * (at your option) any later version.
 *
 * Electric(tm) 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, see <http://www.gnu.org/licenses/>.
 */

package com.sun.electric.tool.routing;

import com.sun.electric.database.EditingPreferences;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;

import com.sun.electric.database.geometry.PolyMerge;
import com.sun.electric.database.hierarchy.Cell;

/**
 * A Simple wiring tool for the user to draw wires.
 */
public class SimpleWirer extends InteractiveRouter {

    public SimpleWirer(EditingPreferences ep) {
        super(ep);
    }

    /* ----------------------- Router Methods ------------------------------------- */

    public String toString() { return "SimpleWirer"; }


    protected boolean planRoute(Route route, Cell cell, RouteElementPort endRE,
                                Point2D startLoc, Point2D endLoc, Point2D clicked, PolyMerge stayInside, VerticalRoute vroute,
                                boolean contactsOnEndObj, boolean extendArcHead, boolean extendArcTail, Rectangle2D contactArea) {
/*
        RouteElementPort startRE = route.getEnd();

        // find port protos of startRE and endRE, and find connecting arc type
        PortProto startPort = startRE.getPortProto();
        PortProto endPort = endRE.getPortProto();
        ArcProto useArc = getArcToUse(startPort, endPort);

        // first, find location of corner of L if routing will be an L shape
        Point2D cornerLoc = null;

    	// see if it fits the angle increment so that a single arc can be drawn
        boolean singleArc = false;
    	if (useArc != null)
    	{
    		int inc = 10*useArc.getAngleIncrement();
    		if (inc == 0) singleArc = true; else
    		{
    			int ang = GenMath.figureAngle(startLoc, endLoc);
    			if ((ang % inc) == 0) singleArc = true;
    		}
    	} else
    	{
    		// no arc specified: allow direct if manhattan
            if (startLoc.getX() == endLoc.getX() || startLoc.getY() == endLoc.getY()) singleArc = true;
    	}

        if (contactArea != null) {
            cornerLoc = new Point2D.Double(contactArea.getCenterX(), contactArea.getCenterY());
        } else {
            if (singleArc)
            {
                // single arc
                if (contactsOnEndObj)
                    cornerLoc = endLoc;
                else
                    cornerLoc = startLoc;
            } else
            {
                Point2D pin1 = new Point2D.Double(startLoc.getX(), endLoc.getY());
                Point2D pin2 = new Point2D.Double(endLoc.getX(), startLoc.getY());
                // find which pin to use
                int clickedQuad = findQuadrant(endLoc, clicked);
                int pin1Quad = findQuadrant(endLoc, pin1);
                int pin2Quad = findQuadrant(endLoc, pin2);
                int oppositeQuad = (clickedQuad + 2) % 4;
                // presume pin1 by default
                cornerLoc = pin1;
                if (pin2Quad == clickedQuad)
                {
                    cornerLoc = pin2;                // same quad as pin2, use pin2
                } else if (pin1Quad == clickedQuad)
                {
                    cornerLoc = pin1;                // same quad as pin1, use pin1
                } else if (pin1Quad == oppositeQuad)
                {
                    cornerLoc = pin2;                // near to pin2 quad, use pin2
                }

                if (stayInside != null && useArc != null)
                {
                    // make sure the bend stays inside of the merge area
                    double pinSize = useArc.getDefaultLambdaBaseWidth();
                    Layer pinLayer = useArc.getLayerIterator().next();
                    Rectangle2D pin1Rect = new Rectangle2D.Double(pin1.getX()-pinSize/2, pin1.getY()-pinSize/2, pinSize, pinSize);
                    Rectangle2D pin2Rect = new Rectangle2D.Double(pin2.getX()-pinSize/2, pin2.getY()-pinSize/2, pinSize, pinSize);
                    if (stayInside.contains(pinLayer, pin1Rect)) cornerLoc = pin1; else
                        if (stayInside.contains(pinLayer, pin2Rect)) cornerLoc = pin2;
                }
            }
        }

        int startAngle = GenMath.figureAngle(startLoc, cornerLoc);
        int endAngle = GenMath.figureAngle(endLoc, cornerLoc);

        // never use universal arcs unless the user has selected them
        if (useArc == null) {
            // use universal if selected
            if (User.getUserTool().getCurrentArcProto() == Generic.tech().universal_arc)
                useArc = Generic.tech().universal_arc;
            else {
                route.add(endRE);
                route.setEnd(endRE);
                vroute.buildRoute(route, cell, startRE, endRE, startLoc, endLoc, cornerLoc, stayInside, contactArea);
                return true;
            }
        }

        route.add(endRE);
        route.setEnd(endRE);

        // startRE and endRE can be connected with an arc.  If one of them is a bisectArcPin,
        // and can be replaced by the other, just replace it and we're done.
        if (route.replaceBisectPin(startRE, endRE)) {
            route.remove(startRE);
            return true;
        } else if (route.replaceBisectPin(endRE, startRE)) {
            route.remove(endRE);
            route.setEnd(startRE);
            return true;
        }

        // find arc width to use
        double width = getArcWidthToUse(startRE, useArc, startAngle);
        double width2 = getArcWidthToUse(endRE, useArc, endAngle);
        if (width2 > width) width = width2;

        // see if we should only draw a single arc
        if (singleArc) {
            // draw single
            RouteElement arcRE = RouteElementArc.newArc(cell, useArc, width, startRE, endRE,
            	startLoc, endLoc, null, null, null, extendArcHead, extendArcTail, stayInside);
            route.add(arcRE);
            return true;
        }

        // this router only draws horizontal and vertical arcs
        // if either X or Y coords are the same, create a single arc
//        boolean newV = DBMath.areEquals(startLoc.getX(), endLoc.getX()) || DBMath.areEquals(startLoc.getY(), endLoc.getY());
//        boolean oldV = (startLoc.getX() == endLoc.getX() || startLoc.getY() == endLoc.getY());
//        if (newV != oldV)
//            System.out.println("Precision problem in SimpleWireer");

        if (DBMath.areEquals(startLoc.getX(), endLoc.getX()) || DBMath.areEquals(startLoc.getY(), endLoc.getY()))
        {
            // single arc
            RouteElement arcRE = RouteElementArc.newArc(cell, useArc, width, startRE, endRE,
            	startLoc, endLoc, null, null, null, extendArcHead, extendArcTail, stayInside);
            route.add(arcRE);
        } else {
            // otherwise, create new pin and two arcs for corner
            // make new pin of arc type
            PrimitiveNode pn = useArc.findOverridablePinProto();
            SizeOffset so = pn.getProtoSizeOffset();
            double defwidth = pn.getDefWidth()-so.getHighXOffset()-so.getLowXOffset();
            double defheight = pn.getDefHeight()-so.getHighYOffset()-so.getLowYOffset();
            RouteElementPort pinRE = RouteElementPort.newNode(cell, pn, pn.getPort(0), cornerLoc,
                    defwidth, defheight);
            RouteElement arcRE1 = RouteElementArc.newArc(cell, useArc, width, startRE, pinRE,
            	startLoc, cornerLoc, null, null, null, extendArcHead, true, stayInside);
            RouteElement arcRE2 = RouteElementArc.newArc(cell, useArc, width, pinRE, endRE,
            	cornerLoc, endLoc, null, null, null, true, extendArcTail, stayInside);
            route.add(pinRE);
            route.add(arcRE1);
            route.add(arcRE2);
        }
*/
        return true;
    }

}

