package shape;

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


public class LineElement extends ShapeElement{

    int debug=0;

    public LineElement(){
        super();
    }

    public int getTypeE(){
        return Command.LINE;
    }
    
     public String getShapeIdString(){
         return "Line";
     }

    public Rectangle2D createTextArea(){
        return null;
    }
//ShapeElement
    public SegmentModifier[] getSegmentModifiers(){
        SegmentModifier[] modifiers=new SegmentModifier[0];
        return modifiers;
    }
//ShapeElement
    public Point2D[] getModifierPTs(){
        Point2D[] PTs=new Point2D[0];
        return PTs;
    }

    public void mouseStart(int ctrl, Point2D startPoint){
        super.mouseStart(ctrl, startPoint);
        this.startPoint=startPoint;
    }
  
    public void create(Rectangle2D boundingBox){}
    public void create(Point2D startPoint, Point2D currentPoint){
        this.curve2D=new Line2DE( startPoint, currentPoint);
    }
    
    public void create(Point2D[] points){}

    public void moveEndPoint(int ctrl, int movePtIndex, Point2D currentPoint){
        boolean resizable=this.shapeContainer.getBooleanProperty("Enable_Resizing", "LineElemrent");
        if(!resizable) return;
        boolean keep_line_direction=this.shapeContainer.getBooleanProperty("Keep_Line_Direction", 
                "LineElemrent");
        if(keep_line_direction) ctrl=3;

        this.getShapeContainer().setChangeCode(UndoConstants.SHAPE);
        Line2DE line=(Line2DE)this.curve2D;
        double r=line.getCurveLength(0, 1);
        if(movePtIndex==0){
            Point2D p1=line.getP1();
            Point2D newP1=currentPoint;
            if(ctrl==1||ctrl==2) newP1=DiscreteAngledLine.getControlledPT(0, 90, line.getP2(), newP1);
            //if(ctrl==1||ctrl==2) newP1=DiscreteAngledLine.getControlledPT(0, 90, line.getP2(), newP1);
            if(ctrl==3) newP1=this.getPointOnLine(line, newP1);
            if(ctrl==4) newP1=this.getPointOnCircle(r, line.getP2(), newP1);
            double len=Vector2D.dist(newP1, line.getP2());
            if(len>1.0d) line.setData(newP1, line.getP2());
        } else{
            Point2D p2=line.getP2();
            Point2D newP2=currentPoint;
            if(ctrl==1||ctrl==2) newP2=DiscreteAngledLine.getControlledPT(0, 90, line.getP1(), newP2);
            //if(ctrl==1||ctrl==2) newP2=DiscreteAngledLine.getControlledPT(0, 90, line.getP1(), newP2);
            if(ctrl==3) newP2=this.getPointOnLine(line, newP2);
            if(ctrl==4) newP2=this.getPointOnCircle(r, line.getP1(), newP2);
            double len=Vector2D.dist(newP2, line.getP1());
            if(len>1.0d) line.setData(line.getP1(), newP2);
        }
    }

    public void moveEndPoint(int ctrl, int movePtIndex, Point2D oldPoint, Point2D currentPoint){
        boolean resizable=this.shapeContainer.getBooleanProperty("Enable_Resizing", "LineElemrent");
        if(!resizable) return;
        boolean keep_line_direction=this.shapeContainer.getBooleanProperty("Keep_Line_Direction", 
                "LineElemrent");
        if(keep_line_direction) ctrl=3;
        
        this.getShapeContainer().setChangeCode(UndoConstants.SHAPE);
        double moveX=currentPoint.getX()-oldPoint.getX();
        double moveY=currentPoint.getY()-oldPoint.getY();
        Line2DE line=(Line2DE)this.curve2D;
        double r=line.getCurveLength(0, 1);
        if(movePtIndex==0){
            Point2D p1=line.getP1();
            Point2D newP1=new Point2D.Double(p1.getX()+moveX, p1.getY()+moveY);
            if(ctrl==1||ctrl==2) newP1=DiscreteAngledLine.getControlledPT(0, 90, line.getP2(), newP1);
            if(ctrl==3) newP1=this.getPointOnLine(line, newP1);
            if(ctrl==4) newP1=this.getPointOnCircle(r, line.getP2(), newP1);
            double len=Vector2D.dist(newP1, line.getP2());
            if(len>1.0d) line.setData(newP1, line.getP2());
        } else{
            Point2D p2=line.getP2();
            Point2D newP2=new Point2D.Double(p2.getX()+moveX, p2.getY()+moveY);
            if(ctrl==1||ctrl==2) newP2=DiscreteAngledLine.getControlledPT(0, 90, line.getP1(), newP2);
            if(ctrl==3) newP2=this.getPointOnLine(line, newP2);
            if(ctrl==4) newP2=this.getPointOnCircle(r, line.getP1(), newP2);
            double len=Vector2D.dist(newP2, line.getP1());
            if(len>1.0d) line.setData(line.getP1(), newP2);
        }
    }

    private Point2D getPointOnLine(Line2DE line, Point2D P){
        Point2D P1=line.getP1();
        Vector2D tangentVec=line.getTangent(0);
        Vector2D unitVec=Vector2D.unitVector(tangentVec);
        Vector2D vec=Vector2D.sub(P, P1);
        double sprod=Vector2D.sproduct(unitVec, vec);
        Vector2D newVec=Vector2D.multiply(sprod, unitVec);
        Point2D newPT=new Point2D.Double(P1.getX()+newVec.getX(),P1.getY()+newVec.getY());
        return newPT;
    }

    private Point2D getPointOnCircle(double r, Point2D P0, Point2D P){
        Vector2D vec=Vector2D.sub(P, P0);
        Vector2D unitVec=Vector2D.unitVector(vec);
        Vector2D newVec=Vector2D.multiply(r, unitVec);
        Point2D newPT=new Point2D.Double(P0.getX()+newVec.getX(), P0.getY()+newVec.getY());
        return newPT;
    }

    public void modify(int ctrl, Point2D oldPoint, Point2D currentPoint){}
    public void modifyPoint(Point2D point, String command){}
    //public int deletePoint(Point2D point){return 0;}

    public Object clone(){
        LineElement shapeElement=new LineElement();
        Line2DE curve=(Line2DE)curve2D.clone();
        shapeElement.setCurve2D(curve);
        return shapeElement;
    }

    public String toString(){
        String str="";
        if(this.curve2D==null){
            str+="Line: not defined";
            return str;
        }
        Line2DE line=(Line2DE)this.curve2D;
        str+="Line:"+" start=("+String.valueOf((int)line.getX1())+
                ","+String.valueOf((int)line.getY1())+")"
                +" end=("+String.valueOf((int)line.getX2())+
                ","+String.valueOf((int)line.getY2())+")";
        return str;
    }

}