package shapeUtil;

import java.awt.geom.*;
import java.util.*;
import DrawTop.*;
import shape.*;
import DrawTop.*;
import util.*;
import geomExtension.*;

public class CreateAuxShape {

    public CreateAuxShape(){}

    public void centerLine(ShapeContainer[] containers){
        //System.out.println("CreateAuxShape.centerLine");
        ContainerManager containerManager=ObjectTable.getContainerManager();
        int len=containers.length;
        ShapeContainer[] newContainers=new ShapeContainer[2*len];
        for(int i=0;i<len;i++){
            Rectangle2D box=containers[i].getBoundingBox();
            double X=box.getX();
            double Y=box.getY();
            double W=box.getWidth();
            double H=box.getHeight();
            double w=0.2*H;
            double h=0.2*W;
            Point2D P1=null;
            Point2D P2=null;
            newContainers[2*i]=null;
            newContainers[2*i+1]=null;
          //Horizontal line
            if(H>1.0) {
                P1=new Point2D.Double(X, Y+0.5*H);
                P2=new Point2D.Double(X+W, Y+0.5*H);
                if(W<1){
                    P1=new Point2D.Double(X-w, Y+0.5*H);
                    P2=new Point2D.Double(X+w, Y+0.5*H);
                }
                Line2DE line1=new Line2DE(P1, P2);
                LineElement lineE1=new LineElement();
                lineE1.setCurve2D(line1);
                newContainers[2*i]=new ShapeContainer();
                newContainers[2*i].setElement(lineE1);
                lineE1.setShapeContainer(newContainers[2*i]);
                newContainers[2*i].setNewShapeId(containerManager, false);
            }
          //Vertical line
            if(W>1.0) {
                P1=new Point2D.Double(X+0.5*W, Y);
                P2=new Point2D.Double(X+0.5*W, Y+H);
                if(H<1){
                    P1=new Point2D.Double(X+0.5*W, Y-h);
                    P2=new Point2D.Double(X+0.5*W, Y+h);
                }
                Line2DE line2=new Line2DE(P1, P2);
                LineElement lineE2=new LineElement();
                lineE2.setCurve2D(line2);
                newContainers[2*i+1]=new ShapeContainer();
                newContainers[2*i+1].setElement(lineE2);
                lineE2.setShapeContainer(newContainers[2*i+1]);
                newContainers[2*i+1].setNewShapeId(containerManager, false);
            }
        }
        
      //------------------------  undo setup  --------------------//
        containerManager.undoSetupStart();
        for(int i=0;i<newContainers.length;i++){
            if(newContainers[i]==null) continue;
            newContainers[i].setSelected(true);
            this.setKeepLineDirectionProperty(newContainers[i]);
            containerManager.addContainer(newContainers[i]);
        }
        containerManager.undoSetupEnd();
      //---------------------------------------------------------//
        for(int i=0;i<len;i++){
            containers[i].setSelected(false);
        }
    }

    public void lineBisector(ShapeContainer[] containers){
       ContainerManager containerManager=ObjectTable.getContainerManager();
        int len=containers.length;
        ShapeContainer[] newContainers=new ShapeContainer[len];
        for(int i=0;i<len;i++){
            ShapeElement element=containers[i].getElement();
            if(element.getTypeE()!=Command.LINE) continue;
            Point2D[] PT=element.getEndPTs();
            Vector2D vec=Vector2D.sub(PT[1], PT[0]);
            double dist=Vector2D.dist(PT[1], PT[0]);
            Vector2D unitVec=Vector2D.unitVector(vec);
            Vector2D unitNVec=Vector2D.unitNormalVector(vec);
            Vector2D centerVec=Vector2D.multiply(0.5*dist, unitVec);
            centerVec=Vector2D.add(new Vector2D(PT[0]), centerVec);
            double nlen=0.2*dist;
            Vector2D nVec=Vector2D.multiply(nlen, unitNVec);
            Point2D P1=new Point2D.Double(centerVec.getX()+nVec.getX(),
                    centerVec.getY()+nVec.getY());
            Point2D P2=new Point2D.Double(centerVec.getX()-nVec.getX(),
                    centerVec.getY()-nVec.getY());
            Line2DE line=new Line2DE(P1, P2);
            LineElement lineE=new LineElement();
            lineE.setCurve2D(line);
            newContainers[i]=new ShapeContainer();
            newContainers[i].setElement(lineE);
            lineE.setShapeContainer(newContainers[i]);
            newContainers[i].setNewShapeId(containerManager, false);
        }

      //------------------------  undo setup  --------------------//
        containerManager.undoSetupStart();
        for(int i=0;i<newContainers.length;i++){
            if(newContainers[i]==null) continue;
            newContainers[i].setSelected(true);
            this.setKeepLineDirectionProperty(newContainers[i]);
            containerManager.addContainer(newContainers[i]);
        }
        containerManager.undoSetupEnd();
      //---------------------------------------------------------//
        for(int i=0;i<len;i++){
            containers[i].setSelected(false);
        }
    }

    public void angleBisector(ShapeContainer[] containers){
       ContainerManager containerManager=ObjectTable.getContainerManager();
        int len=containers.length;
        Vector vector=new Vector();
        for(int i=0;i<len;i++){
            for(int j=i+1;j<len;j++){
                Curve2D curve1 = containers[i].getElement().getCurve2D();
                Curve2D curve2 = containers[j].getElement().getCurve2D();
                CrossCurvePT[] crossPTs = Curve2DUtil.getIntersectionPts(curve1, curve2);
                for(int k=0;k<crossPTs.length;k++){
                    Curve2D[] lines=this.createCrossLine(curve1, curve2, crossPTs[k]);
                    for(int m=0;m<lines.length;m++){
                        ShapeContainer newContainer=new ShapeContainer();
                        ShapeElement element=new LineElement();
                        element.setCurve2D(lines[m]);
                        newContainer.setElement(element);
                        element.setShapeContainer(newContainer);
                        newContainer.setNewShapeId(containerManager, false);
                        vector.add(newContainer);
                    }
                }
            }
        }

      //------------------------  undo setup  --------------------//
        containerManager.undoSetupStart();
        for(int i=0;i<vector.size();i++){
            ShapeContainer container=(ShapeContainer)vector.get(i);
            container.setSelected(true);
            this.setKeepLineDirectionProperty(container);
            containerManager.addContainer(container);
        }
        containerManager.undoSetupEnd();
      //---------------------------------------------------------//
        for(int i=0;i<len;i++){
            containers[i].setSelected(false);
        }
    }

    private Curve2D[] createCrossLine(Curve2D curve1, Curve2D curve2, CrossCurvePT crossPT){
        Vector2D tan1=curve1.getTangent(crossPT.getParameterT1());
        Vector2D tan2=curve2.getTangent(crossPT.getParameterT2());
        Point2D pt=crossPT.getP1();
        Vector2D unitTan1=Vector2D.unitVector(tan1);
        Vector2D unitTan2=Vector2D.unitVector(tan2);
        Vector2D unitVec=Vector2D.unitVector(Vector2D.add(unitTan1, unitTan2));
        Vector2D unitNvec=Vector2D.unitNormalVector(unitVec);
        double vecLen=DrawParameters.TempLineLength;
        Vector2D vec1=Vector2D.multiply(vecLen, unitVec);
        Vector2D vec2=Vector2D.multiply(vecLen, unitNvec);
      // The first line2D
        Point2D p1=new Point2D.Double(pt.getX()-vec1.getX(), pt.getY()-vec1.getY());
        Point2D p2=new Point2D.Double(pt.getX()+vec1.getX(), pt.getY()+vec1.getY());
        Curve2D[] lines=new Curve2D[2];
        lines[0]=new Line2DE(p1, p2);
      // The second line2D
        p1=new Point2D.Double(pt.getX()-vec2.getX(), pt.getY()-vec2.getY());
        p2=new Point2D.Double(pt.getX()+vec2.getX(), pt.getY()+vec2.getY());
        lines[1]=new Line2DE(p1, p2);
        return lines;
    }

    private void setKeepLineDirectionProperty(ShapeContainer container){
        String key=Command.getCommandString(Command.KEEP_LINE_DIRECTION);
        container.setProperty(key, true, "CreateAuxShape");
    }
}
