package geomExtension;

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


public class Polyline2DE extends Curve2D{

    public Polyline2DE(Segment2D[] segments){
        super(segments);
    }

    public Polyline2DE(Point2D[] points){
        this.setData(points);
    }

    public Polyline2DE(Point2D[] points, boolean closed){
        this.generalPath=new GeneralPath(Curve2D.Path2D_WIND);
        this.segments=new Segment2D[points.length-1];
        this.closed=closed;
        if(closed) points[points.length-1]=points[0];

        for(int i=0;i<points.length-1;i++) {
            Line2D line=new Line2D.Double(points[i], points[i+1]);
            Segment2D segment=new Segment2D(Segment2D.LINE, line);
            generalPath.append(line,true);
            segments[i]=segment;
        }
    }

//Polyline2DE proper
    public void setData(Point2D[] points){
        this.generalPath=new GeneralPath(Curve2D.Path2D_WIND);
        this.segments=new Segment2D[points.length-1];
        this.closed=false;
        int np=points.length;
        double dist=Vector2D.dist(points[0], points[np-1]);
        if(dist<Curve2D.closedTolerance) {
            points[np-1]=(Point2D)points[0].clone();
            this.closed=true;
        }
        for(int i=0;i<points.length-1;i++) {
            Line2D line=new Line2D.Double(points[i], points[i+1]);
            Segment2D segment=new Segment2D(Segment2D.LINE, line);
            generalPath.append(line,true);
            segments[i]=segment;
        }
    }

//Curve2D method
    public int getType2DE(){
        return Command.POLYLINE;
    }
//Polyline2DE proper
    public Point2D[] getPoints(){
        Point2D[] points=new Point2D[this.segments.length+1];
        for(int i=0;i<points.length;i++) {
            points[i]=new Point2D.Double(this.getP(i).getX(), this.getP(i).getY());
        }
        return points;
    }
//Polyline2DE proper
    public Point2D getPoint(int index){
        if(index<0||index>this.segments.length){
            System.out.println("*** Error Polyline2DE.getPoint; index out of range; index="+index);
            return null;
        }
        return this.getP(index);
    }

//Polyline2DE proper
    public Polyline2DE getTrimmedCurve2D(double t1, double t2){
        if(this.isClosed()||t1==0.0&&t2==0.0) return this;
        Polyline2DE trimmedCurve=null;
        Vector vector=new Vector();
        int it1=(int)t1;
        int it2=(int)t2;
        if(Math.abs(t2-it2)<Curve2D.eps&&t2>=1) it2=it2-1;
        for(int i=it1;i<=it2;i++){
            double t01=0;
            double t02=1;
            if(i==it1) t01=t1-it1;
            if(i==it2) t02=t2-it2;
            Segment2D segment=this.getSegment2D(i);
            if(Math.abs(t02-t01)>Curve2D.eps) {
                Segment2D subSegment=segment.trimSegment(t01, t02);
                vector.add(subSegment);
            }
        }
        int size=vector.size();
        if(size==0)return null;
        Segment2D[] segments=new Segment2D[size];
        for(int i=0;i<size;i++) segments[i]=(Segment2D)vector.get(i);
        trimmedCurve=new Polyline2DE(segments);
        return trimmedCurve;
    }

    public Polyline2DE getTrimmedPolyline(double cut1, double cut2){
        if(this.isClosed()||cut1==0.0&&cut2==0.0) return this;
        int numseg=this.getNumOfSegments();
        double length1=this.getCurveLength(0, 1);
        double t1=cut1/length1;
        double length2=this.getCurveLength(numseg-1, numseg);
        double t2=numseg-cut2/length2;
        return this.getTrimmedCurve2D(t1,t2);
    }

//Curve2D method
    public Object clone(){
        Point2D[] points=this.getPoints();
        return (new Polyline2DE(points));
    }
//Curve2D method
    public String toString(){
        String str="";
        str+="Polyline, segments="+this.segments.length+", close="+this.closed;
        for(int i=0;i<this.segments.length;i++){
            //double t=i;
            //str+=", x,y["+i+"]="+Util.Pt(this.getP(t));
            Segment2D segment=(Segment2D)this.segments[i];
            str+="\n    -- segments["+i+"]="+segment.toString();
        }
        return str;
    }
}
